From c586def0952ecc481b65dab18d091389041b547c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elouan=20App=C3=A9r=C3=A9?= Date: Sun, 30 Aug 2015 22:09:23 +0200 Subject: [PATCH] First commit --- CMakeLists.txt | 23 + LibPkmGC/CMakeLists.txt | 41 + LibPkmGC/include/LibPkmGC/Base/DataStruct.h | 66 + LibPkmGC/include/LibPkmGC/Base/Pokemon.h | 111 + LibPkmGC/include/LibPkmGC/Base/PokemonBox.h | 36 + .../include/LibPkmGC/Base/PokemonString.h | 45 + .../LibPkmGC/Colosseum/Common/BagData.h | 32 + .../Colosseum/Common/BattleModeData.h | 41 + .../LibPkmGC/Colosseum/Common/DaycareData.h | 31 + .../LibPkmGC/Colosseum/Common/Everything.h | 10 + .../Colosseum/Common/GroupBattleRule.h | 36 + .../LibPkmGC/Colosseum/Common/MailboxData.h | 42 + .../LibPkmGC/Colosseum/Common/PCData.h | 38 + .../LibPkmGC/Colosseum/Common/PlayerData.h | 49 + .../LibPkmGC/Colosseum/Common/Pokemon.h | 92 + .../LibPkmGC/Colosseum/Common/PokemonBox.h | 34 + .../Colosseum/Common/StrategyMemoData.h | 35 + .../Colosseum/Common/StrategyMemoEntry.h | 30 + .../LibPkmGC/Colosseum/SaveEditing/Save.h | 38 + .../LibPkmGC/Colosseum/SaveEditing/SaveSlot.h | 81 + LibPkmGC/include/LibPkmGC/Core/Config.h | 24 + LibPkmGC/include/LibPkmGC/Core/Crypto.h | 16 + .../LibPkmGC/Core/Detail/AbilityNames.h | 28 + .../LibPkmGC/Core/Detail/IntegerManipCode.h | 120 + .../include/LibPkmGC/Core/Detail/ItemNames.h | 63 + .../include/LibPkmGC/Core/Detail/MoveNames.h | 28 + .../LibPkmGC/Core/Detail/NatureNames.cpp | 183 + .../LibPkmGC/Core/Detail/NatureNames.h | 28 + .../LibPkmGC/Core/Detail/SpeciesNames.h | 29 + .../LibPkmGC/Core/Detail/StructMacros.h | 147 + LibPkmGC/include/LibPkmGC/Core/IntegerManip.h | 107 + LibPkmGC/include/LibPkmGC/Core/IntegerTypes.h | 26 + LibPkmGC/include/LibPkmGC/Core/ItemInfo.h | 441 ++ LibPkmGC/include/LibPkmGC/Core/Localization.h | 34 + LibPkmGC/include/LibPkmGC/Core/PokemonInfo.h | 1012 +++ LibPkmGC/include/LibPkmGC/GC/Common/BagData.h | 47 + .../LibPkmGC/GC/Common/BattleModeData.h | 38 + .../include/LibPkmGC/GC/Common/DaycareData.h | 58 + .../include/LibPkmGC/GC/Common/Everything.h | 9 + .../LibPkmGC/GC/Common/GroupBattleRule.h | 52 + .../include/LibPkmGC/GC/Common/MailboxData.h | 44 + LibPkmGC/include/LibPkmGC/GC/Common/PCData.h | 40 + .../include/LibPkmGC/GC/Common/PlayerData.h | 52 + LibPkmGC/include/LibPkmGC/GC/Common/Pokemon.h | 32 + .../include/LibPkmGC/GC/Common/PokemonBox.h | 34 + .../LibPkmGC/GC/Common/PokemonString.h | 40 + .../LibPkmGC/GC/Common/StrategyMemoData.h | 59 + .../LibPkmGC/GC/Common/StrategyMemoEntry.h | 55 + .../include/LibPkmGC/GC/SaveEditing/Save.h | 60 + .../LibPkmGC/GC/SaveEditing/SaveSlot.h | 78 + LibPkmGC/include/LibPkmGC/XD/Common/BagData.h | 37 + .../LibPkmGC/XD/Common/BattleModeData.h | 43 + .../include/LibPkmGC/XD/Common/DaycareData.h | 31 + .../include/LibPkmGC/XD/Common/Everything.h | 11 + .../LibPkmGC/XD/Common/GroupBattleRule.h | 46 + .../include/LibPkmGC/XD/Common/MailboxData.h | 39 + LibPkmGC/include/LibPkmGC/XD/Common/PCData.h | 39 + .../include/LibPkmGC/XD/Common/PlayerData.h | 49 + LibPkmGC/include/LibPkmGC/XD/Common/Pokemon.h | 93 + .../include/LibPkmGC/XD/Common/PokemonBox.h | 33 + .../LibPkmGC/XD/Common/PurificationChamber.h | 47 + .../include/LibPkmGC/XD/Common/PurifierData.h | 43 + .../LibPkmGC/XD/Common/StrategyMemoData.h | 37 + .../LibPkmGC/XD/Common/StrategyMemoEntry.h | 30 + .../include/LibPkmGC/XD/SaveEditing/Save.h | 39 + .../LibPkmGC/XD/SaveEditing/SaveSlot.h | 109 + LibPkmGC/src/LibPkmGC/Base/DataStruct.cpp | 80 + LibPkmGC/src/LibPkmGC/Base/Pokemon.cpp | 220 + LibPkmGC/src/LibPkmGC/Base/PokemonBox.cpp | 41 + LibPkmGC/src/LibPkmGC/Base/PokemonString.cpp | 44 + .../src/LibPkmGC/Colosseum/Common/BagData.cpp | 28 + .../Colosseum/Common/BattleModeData.cpp | 42 + .../LibPkmGC/Colosseum/Common/DaycareData.cpp | 34 + .../Colosseum/Common/GroupBattleRule.cpp | 40 + .../LibPkmGC/Colosseum/Common/MailboxData.cpp | 40 + .../src/LibPkmGC/Colosseum/Common/PCData.cpp | 44 + .../LibPkmGC/Colosseum/Common/PlayerData.cpp | 53 + .../src/LibPkmGC/Colosseum/Common/Pokemon.cpp | 152 + .../LibPkmGC/Colosseum/Common/PokemonBox.cpp | 43 + .../Colosseum/Common/StrategyMemoData.cpp | 46 + .../Colosseum/Common/StrategyMemoEntry.cpp | 39 + .../LibPkmGC/Colosseum/SaveEditing/Save.cpp | 50 + .../Colosseum/SaveEditing/SaveSlot.cpp | 280 + LibPkmGC/src/LibPkmGC/Core/Crypto.cpp | 301 + .../src/LibPkmGC/Core/Detail/AbilityNames.cpp | 502 ++ .../src/LibPkmGC/Core/Detail/ItemNames.cpp | 2394 +++++++ .../src/LibPkmGC/Core/Detail/MoveNames.cpp | 2163 +++++++ .../src/LibPkmGC/Core/Detail/SpeciesNames.cpp | 2362 +++++++ LibPkmGC/src/LibPkmGC/Core/ItemInfo.cpp | 46 + LibPkmGC/src/LibPkmGC/Core/Localization.cpp | 533 ++ LibPkmGC/src/LibPkmGC/Core/PokemonInfo.cpp | 5626 +++++++++++++++++ LibPkmGC/src/LibPkmGC/GC/Common/BagData.cpp | 81 + .../src/LibPkmGC/GC/Common/BattleModeData.cpp | 35 + .../src/LibPkmGC/GC/Common/DaycareData.cpp | 57 + .../LibPkmGC/GC/Common/GroupBattleRule.cpp | 101 + .../src/LibPkmGC/GC/Common/MailboxData.cpp | 47 + LibPkmGC/src/LibPkmGC/GC/Common/PCData.cpp | 48 + .../src/LibPkmGC/GC/Common/PlayerData.cpp | 69 + LibPkmGC/src/LibPkmGC/GC/Common/Pokemon.cpp | 41 + .../src/LibPkmGC/GC/Common/PokemonBox.cpp | 24 + .../src/LibPkmGC/GC/Common/PokemonString.cpp | 322 + .../LibPkmGC/GC/Common/StrategyMemoData.cpp | 119 + .../LibPkmGC/GC/Common/StrategyMemoEntry.cpp | 48 + .../GC/Detail/CircularDependencies.cpp | 23 + LibPkmGC/src/LibPkmGC/GC/SaveEditing/Save.cpp | 113 + .../src/LibPkmGC/GC/SaveEditing/SaveSlot.cpp | 101 + LibPkmGC/src/LibPkmGC/XD/Common/BagData.cpp | 48 + .../src/LibPkmGC/XD/Common/BattleModeData.cpp | 47 + .../src/LibPkmGC/XD/Common/DaycareData.cpp | 35 + .../LibPkmGC/XD/Common/GroupBattleRule.cpp | 63 + .../src/LibPkmGC/XD/Common/MailboxData.cpp | 41 + LibPkmGC/src/LibPkmGC/XD/Common/PCData.cpp | 47 + .../src/LibPkmGC/XD/Common/PlayerData.cpp | 55 + LibPkmGC/src/LibPkmGC/XD/Common/Pokemon.cpp | 174 + .../src/LibPkmGC/XD/Common/PokemonBox.cpp | 40 + .../XD/Common/PurificationChamber.cpp | 66 + .../src/LibPkmGC/XD/Common/PurifierData.cpp | 57 + .../LibPkmGC/XD/Common/StrategyMemoData.cpp | 48 + .../LibPkmGC/XD/Common/StrategyMemoEntry.cpp | 38 + LibPkmGC/src/LibPkmGC/XD/SaveEditing/Save.cpp | 60 + .../src/LibPkmGC/XD/SaveEditing/SaveSlot.cpp | 363 ++ PkmGCSaveEditor/CMakeLists.txt | 89 + PkmGCSaveEditor/src/Core/DataUI.cpp | 23 + PkmGCSaveEditor/src/Core/DataUI.h | 28 + PkmGCSaveEditor/src/Core/Globals.cpp | 35 + PkmGCSaveEditor/src/Core/Globals.h | 30 + PkmGCSaveEditor/src/Core/IDataUI.h | 21 + PkmGCSaveEditor/src/Core/ItemComboBox.cpp | 77 + PkmGCSaveEditor/src/Core/ItemComboBox.h | 45 + PkmGCSaveEditor/src/Core/ItemPocketEditor.cpp | 138 + PkmGCSaveEditor/src/Core/ItemPocketEditor.h | 51 + .../src/Core/TrainerInfoLayout.cpp | 70 + PkmGCSaveEditor/src/Core/TrainerInfoLayout.h | 45 + PkmGCSaveEditor/src/Core/UnsignedSpinbox.h | 113 + .../src/Core/VersionInfoLayout.cpp | 60 + PkmGCSaveEditor/src/Core/VersionInfoLayout.h | 33 + PkmGCSaveEditor/src/GCUIs/BagEditor.cpp | 81 + PkmGCSaveEditor/src/GCUIs/BagEditor.h | 33 + PkmGCSaveEditor/src/GCUIs/DaycareUI.cpp | 74 + PkmGCSaveEditor/src/GCUIs/DaycareUI.h | 41 + PkmGCSaveEditor/src/GCUIs/GameConfigUI.cpp | 86 + PkmGCSaveEditor/src/GCUIs/GameConfigUI.h | 47 + PkmGCSaveEditor/src/GCUIs/PCUI.cpp | 80 + PkmGCSaveEditor/src/GCUIs/PCUI.h | 39 + PkmGCSaveEditor/src/GCUIs/PlayerUI.cpp | 113 + PkmGCSaveEditor/src/GCUIs/PlayerUI.h | 52 + .../src/GCUIs/PokemonBoxEditor.cpp | 75 + PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.h | 43 + .../src/GCUIs/PokemonDisplayWidget.cpp | 221 + .../src/GCUIs/PokemonDisplayWidget.h | 51 + PkmGCSaveEditor/src/GCUIs/PokemonUI.cpp | 679 ++ PkmGCSaveEditor/src/GCUIs/PokemonUI.h | 188 + .../src/GCUIs/StrategyMemoEntryWidget.cpp | 107 + .../src/GCUIs/StrategyMemoEntryWidget.h | 57 + PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.cpp | 87 + PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.h | 36 + PkmGCSaveEditor/src/MainWindow.cpp | 458 ++ PkmGCSaveEditor/src/MainWindow.h | 90 + PkmGCSaveEditor/src/XDUIs/PurifierUI.cpp | 89 + PkmGCSaveEditor/src/XDUIs/PurifierUI.h | 54 + PkmGCSaveEditor/src/main.cpp | 14 + .../translations/PkmGCSaveEditor_en.ts | 1445 +++++ .../translations/PkmGCSaveEditor_fr.ts | 1421 +++++ 163 files changed, 28854 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LibPkmGC/CMakeLists.txt create mode 100644 LibPkmGC/include/LibPkmGC/Base/DataStruct.h create mode 100644 LibPkmGC/include/LibPkmGC/Base/Pokemon.h create mode 100644 LibPkmGC/include/LibPkmGC/Base/PokemonBox.h create mode 100644 LibPkmGC/include/LibPkmGC/Base/PokemonString.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/BagData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/BattleModeData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/DaycareData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/Everything.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/GroupBattleRule.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/MailboxData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/PCData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/PlayerData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/Pokemon.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/PokemonBox.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoData.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoEntry.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/Save.h create mode 100644 LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/SaveSlot.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Config.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Crypto.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/AbilityNames.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/IntegerManipCode.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/ItemNames.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/MoveNames.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.cpp create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/SpeciesNames.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Detail/StructMacros.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/IntegerManip.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/IntegerTypes.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/ItemInfo.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/Localization.h create mode 100644 LibPkmGC/include/LibPkmGC/Core/PokemonInfo.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/BagData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/BattleModeData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/DaycareData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/Everything.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/GroupBattleRule.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/MailboxData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/PCData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/PlayerData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/Pokemon.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/PokemonBox.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/PokemonString.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoData.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoEntry.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/SaveEditing/Save.h create mode 100644 LibPkmGC/include/LibPkmGC/GC/SaveEditing/SaveSlot.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/BagData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/BattleModeData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/DaycareData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/Everything.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/GroupBattleRule.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/MailboxData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/PCData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/PlayerData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/Pokemon.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/PokemonBox.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/PurificationChamber.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/PurifierData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoData.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoEntry.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/SaveEditing/Save.h create mode 100644 LibPkmGC/include/LibPkmGC/XD/SaveEditing/SaveSlot.h create mode 100644 LibPkmGC/src/LibPkmGC/Base/DataStruct.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Base/Pokemon.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Base/PokemonBox.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Base/PokemonString.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/BagData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/BattleModeData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/DaycareData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/GroupBattleRule.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/MailboxData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/PCData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/PlayerData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/Pokemon.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/PokemonBox.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoEntry.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/Save.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/SaveSlot.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Crypto.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Detail/AbilityNames.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Detail/ItemNames.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Detail/MoveNames.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Detail/SpeciesNames.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/ItemInfo.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/Localization.cpp create mode 100644 LibPkmGC/src/LibPkmGC/Core/PokemonInfo.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/BagData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/BattleModeData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/DaycareData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/GroupBattleRule.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/MailboxData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/PCData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/PlayerData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/Pokemon.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/PokemonBox.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/PokemonString.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoEntry.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/Detail/CircularDependencies.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/SaveEditing/Save.cpp create mode 100644 LibPkmGC/src/LibPkmGC/GC/SaveEditing/SaveSlot.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/BagData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/BattleModeData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/DaycareData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/GroupBattleRule.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/MailboxData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/PCData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/PlayerData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/Pokemon.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/PokemonBox.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/PurificationChamber.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/PurifierData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoData.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoEntry.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/SaveEditing/Save.cpp create mode 100644 LibPkmGC/src/LibPkmGC/XD/SaveEditing/SaveSlot.cpp create mode 100644 PkmGCSaveEditor/CMakeLists.txt create mode 100644 PkmGCSaveEditor/src/Core/DataUI.cpp create mode 100644 PkmGCSaveEditor/src/Core/DataUI.h create mode 100644 PkmGCSaveEditor/src/Core/Globals.cpp create mode 100644 PkmGCSaveEditor/src/Core/Globals.h create mode 100644 PkmGCSaveEditor/src/Core/IDataUI.h create mode 100644 PkmGCSaveEditor/src/Core/ItemComboBox.cpp create mode 100644 PkmGCSaveEditor/src/Core/ItemComboBox.h create mode 100644 PkmGCSaveEditor/src/Core/ItemPocketEditor.cpp create mode 100644 PkmGCSaveEditor/src/Core/ItemPocketEditor.h create mode 100644 PkmGCSaveEditor/src/Core/TrainerInfoLayout.cpp create mode 100644 PkmGCSaveEditor/src/Core/TrainerInfoLayout.h create mode 100644 PkmGCSaveEditor/src/Core/UnsignedSpinbox.h create mode 100644 PkmGCSaveEditor/src/Core/VersionInfoLayout.cpp create mode 100644 PkmGCSaveEditor/src/Core/VersionInfoLayout.h create mode 100644 PkmGCSaveEditor/src/GCUIs/BagEditor.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/BagEditor.h create mode 100644 PkmGCSaveEditor/src/GCUIs/DaycareUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/DaycareUI.h create mode 100644 PkmGCSaveEditor/src/GCUIs/GameConfigUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/GameConfigUI.h create mode 100644 PkmGCSaveEditor/src/GCUIs/PCUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/PCUI.h create mode 100644 PkmGCSaveEditor/src/GCUIs/PlayerUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/PlayerUI.h create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.h create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.h create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/PokemonUI.h create mode 100644 PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.h create mode 100644 PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.cpp create mode 100644 PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.h create mode 100644 PkmGCSaveEditor/src/MainWindow.cpp create mode 100644 PkmGCSaveEditor/src/MainWindow.h create mode 100644 PkmGCSaveEditor/src/XDUIs/PurifierUI.cpp create mode 100644 PkmGCSaveEditor/src/XDUIs/PurifierUI.h create mode 100644 PkmGCSaveEditor/src/main.cpp create mode 100644 PkmGCSaveEditor/translations/PkmGCSaveEditor_en.ts create mode 100644 PkmGCSaveEditor/translations/PkmGCSaveEditor_fr.ts diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4b51b21 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8.12) +project(PkmGCTools) + +set(CMAKE_INSTALL_PREFIX installdir) +option(BUILD_PKMGCSAVEEDITOR ON) + +add_subdirectory(LibPkmGC) +add_definitions(${LIBPKMGC_DEFINITIONS}) + +message("BUILD_PKMGCSAVEEDITOR:\t${BUILD_PKMGCSAVEEDITOR}") + +if(BUILD_PKMGCSAVEEDITOR) + add_subdirectory(PkmGCSaveEditor) + install(FILES ${LIBPKMGC_RUNTIME} DESTINATION Debug/bin CONFIGURATIONS Debug) + install(FILES ${LIBPKMGC_RUNTIME} DESTINATION Release/bin CONFIGURATIONS Release RelWithDebInfo MinSizeRel) + + install(FILES ${QT5_RUNTIME_DEBUG} DESTINATION Debug/bin CONFIGURATIONS Debug) + install(FILES ${QT5_RUNTIME_RELEASE} DESTINATION Release/bin CONFIGURATIONS Release RelWithDebInfo MinSizeRel) + + install(FILES ${QT5_TRANSLATION_QM} DESTINATION Debug/bin/languages CONFIGURATIONS Debug) + install(FILES ${QT5_TRANSLATION_QM} DESTINATION Release/bin/languages CONFIGURATIONS Release RelWithDebInfo MinSizeRel) +endif() + diff --git a/LibPkmGC/CMakeLists.txt b/LibPkmGC/CMakeLists.txt new file mode 100644 index 0000000..9b25d98 --- /dev/null +++ b/LibPkmGC/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 2.8.12) +project(LibPkmGC) + + +include(FindBoost) +find_package(Boost 1.55.0 REQUIRED) + + +file(GLOB_RECURSE source_files ${PROJECT_SOURCE_DIR}/src/*) +file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/include/*) +set(all_files ${source_files} ${header_files}) + +set(LIBPKMGC_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include + ${Boost_INCLUDE_DIRS} + CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE) + +include_directories(${LIBPKMGC_INCLUDE_DIRS}) + +option(LIBPKMGC_DYN_LIB ON) + +message("LIBPKMGC_DYN_LIB:\t${LIBPKMGC_DYN_LIB}") + +add_definitions(-DLIBPKMGC_SOURCE) +unset(LIBPKMGC_RUNTIME CACHE) +unset(LIBPKMGC_DEFINITONS CACHE) +if(LIBPKMGC_DYN_LIB) + set(LIBPKMGC_DEFINITIONS -DLIBPKMGC_DYN_LIB CACHE INTERNAL "LibPkmGC's definitions" FORCE) + add_definitions(-DLIBPKMGC_DYN_LIB) + add_library(LibPkmGC SHARED ${all_files}) + set(LIBPKMGC_RUNTIME $ CACHE INTERNAL "Runtime dependencies for projects linking against this library" FORCE) + install(FILES $ $ DESTINATION Release/lib/shared CONFIGURATIONS Release RelWithDebInfo MinSizeRel) + install(FILES $ $ DESTINATION Debug/lib/shared CONFIGURATIONS Debug) +else() + set(LIBPKMGC_DEFINITIONS -DLIBPKMGC_STATIC_LIB CACHE INTERNAL "LibPkmGC's definitions" FORCE) + add_definitions(-DLIBPKMGC_STATIC_LIB) + add_library(LibPkmGC STATIC ${all_files}) + install(FILES $ DESTINATION Release/lib/static CONFIGURATIONS Release RelWithDebInfo MinSizeRel) + install(FILES $ DESTINATION Debug/lib/static CONFIGURATIONS Debug) +endif() + +set_target_properties(LibPkmGC PROPERTIES PREFIX "" IMPORT_PREFIX "") \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Base/DataStruct.h b/LibPkmGC/include/LibPkmGC/Base/DataStruct.h new file mode 100644 index 0000000..1d8a81d --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Base/DataStruct.h @@ -0,0 +1,66 @@ +#ifndef _LIBPKMGC_BASE_DATASTRUCT_H +#define _LIBPKMGC_BASE_DATASTRUCT_H + +#include + +#define LIBPKMGC_STRUCT_DECRYPTED 1 +#define LIBPKMGC_FWD_DECL_GC_CLS(cls) namespace Colosseum { class cls; } namespace XD { class cls; } + + +namespace LibPkmGC { +namespace Base { + +class LIBPKMGC_DECL DataStruct { +public: + u8* data; + //u32 statusFlags; + + DataStruct(void); + DataStruct(size_t inSize, const u8* inData = NULL, bool fixed = true); + + virtual void save(void) = 0; + + virtual void reload(const u8* inData = NULL, u32 flags = 0); + + DataStruct(const DataStruct& other); + virtual DataStruct* clone(void) const = 0; + virtual DataStruct* create(void) const = 0; + + void swap(DataStruct& other); + DataStruct& operator=(DataStruct const& other); + + virtual ~DataStruct(void); + + bool sizeIsFixed(void) const; + const size_t fixedSize; // = 0 if not fixed + size_t getSize(void) const; +protected: + size_t size; + void initWithEmptyData(u32 flags = 0); + + void copyData(const u8* data = NULL); + virtual void load(u32 flags = 0); + virtual void loadData(u32 flags = 0); + virtual void loadFields(void) = 0; + virtual void deleteFields(void) = 0; // delete dynamically allocated fields +}; + +class LIBPKMGC_DECL UnimplementedStruct : public DataStruct { +public: + UnimplementedStruct(void) : DataStruct() { } + UnimplementedStruct(size_t inSize, const u8* inData = NULL) : DataStruct(inSize, inData) { if (inData == NULL) initWithEmptyData(); } + + UnimplementedStruct* clone(void) const { return new UnimplementedStruct(*this); } + UnimplementedStruct* create(void) const { return new UnimplementedStruct; } + + void save(void) {} + +private: + void loadFields(void) {} + void deleteFields(void) {} +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Base/Pokemon.h b/LibPkmGC/include/LibPkmGC/Base/Pokemon.h new file mode 100644 index 0000000..e352d5a --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Base/Pokemon.h @@ -0,0 +1,111 @@ +#ifndef _LIBPKMGC_BASE_POKEMON_H +#define _LIBPKMGC_BASE_POKEMON_H + +#include +#include +#include +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(Pokemon) + + +namespace Base { + +class LIBPKMGC_DECL Pokemon : public DataStruct { +public: + Pokemon(size_t inSize, const u8* inData = NULL); + + virtual ~Pokemon(void); + + virtual void swap(Pokemon& other); + + virtual Pokemon& operator=(Pokemon const& other); + virtual Pokemon* clone(void) const = 0; + virtual Pokemon* create(void) const = 0; + + static u16 calculateStat(size_t statIndex, PokemonSpeciesIndex species, PokemonNatureIndex natureIndex, u8 level, u8 IV, u8 EV); + static void calculateStats(PokemonSpeciesIndex species, PokemonNatureIndex natureIndex, u8 level, const u8 IVs[6], const u8 EVs[6], u16 outStats[6]); + static u8 calculateLevelFromExp(PokemonSpeciesIndex species, u32 experience); + static u32 calculateExpFromLevel(PokemonSpeciesIndex species, u8 level); + + void calculateStats(u16 outStats[6]) const; + u8 calculateLevelFromExp(void) const; + u32 calculateExpFromLevel(u8 lvl) const; + + void updateStats(void); + void updateLevelFromExp(void); + void updateExpFromLevel(u8 lvl); + + static bool isShiny(u32 PID, u16 TID, u16 SID); + static PokemonNatureIndex getNature(u32 PID); + static Gender getGender(PokemonSpeciesIndex species, u32 PID); + static PokemonSpeciesIndex getWurmpleEvolution(u32 PID); + static char getUnownForm(u32 PID); + + bool isShiny(void) const; + PokemonNatureIndex getNature(void) const; + Gender getGender(void) const; + + PokemonSpeciesIndex getWurmpleEvolution(void) const; + char getUnownForm(void) const; + + bool isSpecialAbilityDefined(void) const; + virtual PokemonAbilityIndex getAbility(void) const = 0; + virtual bool isEmptyOrInvalid(void) const; + + PokemonSpeciesIndex species; //u16 + ItemIndex heldItem; + + + u8 happiness; + u8 locationCaught; // u16 on Colo/XD + ItemIndex ballCaughtWith; + u8 levelMet; + Gender OTGender; + PokemonString* OTName; + PokemonString* name; + u8 contestLuster; + u8 pkrsStatus; + PokemonMarkings markings; + + u32 experience; + u16 SID; + u16 TID; + u32 PID; + +// u8 encounterType; + VersionInfo version; + + bool specialRibbons[12]; //special ribbons #7 only exists in XD/Col + //u32 statusFlags; + + + PokemonMove moves[4]; + u8 EVs[6]; + u8 IVs[6]; + + u8 contestStats[5]; + ContestAchievementLevel contestAchievements[5]; + + bool usesPartyData; // we will avoid using ptrs here + + struct PokemonComputedPartyData { + u16 currentHP; + u8 level; + PokemonStatus status; + u16 stats[6]; + }; + + PokemonComputedPartyData partyData; + void resetPartyData(void); +protected: + Pokemon(Pokemon const& other); + virtual void deleteFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Base/PokemonBox.h b/LibPkmGC/include/LibPkmGC/Base/PokemonBox.h new file mode 100644 index 0000000..f37d4df --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Base/PokemonBox.h @@ -0,0 +1,36 @@ +#ifndef _LIBPKMGC_BASE_POKEMON_BOX_H +#define _LIBPKMGC_BASE_POKEMON_BOX_H + +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(PokemonBox) + +namespace Base { + +class LIBPKMGC_DECL PokemonBox : public Base::DataStruct { +public: + PokemonBox(size_t inSize, const u8* inData = NULL); + virtual ~PokemonBox(void); + + virtual PokemonBox* clone(void) const = 0; + virtual PokemonBox* create(void) const = 0; + + virtual void deleteFields(void); + + void swap(PokemonBox & other); + PokemonBox& operator=(PokemonBox const& other); + + PokemonString *name; + Pokemon* pkm[30]; + +protected: + PokemonBox(PokemonBox const& other); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Base/PokemonString.h b/LibPkmGC/include/LibPkmGC/Base/PokemonString.h new file mode 100644 index 0000000..c529d17 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Base/PokemonString.h @@ -0,0 +1,45 @@ +#ifndef _LIBPKMGC_BASE_POKEMONSTRING_H +#define _LIBPKMGC_BASE_POKEMONSTRING_H + +#include +#include + +namespace LibPkmGC { +namespace Base { + +// Commands (scroll, color etc...) are NOT supported +class LIBPKMGC_DECL PokemonString { +public: + PokemonString(void); + virtual ~PokemonString(void); + virtual PokemonString& operator=(PokemonString const& other); + + virtual PokemonString* clone(void) const = 0; + virtual PokemonString* create(void) const = 0; + + virtual void fromUTF8(const char* str = NULL) = 0; + + virtual const char* toUTF8(void) const = 0; + virtual size_t size(void) const = 0; // number of characters, not counting NULL + + operator const char*(void) const; + + virtual void load(u8* data, size_t nb) = 0; // nb: number of characters, not counting NULL + virtual void save(u8* data, size_t nb) const = 0; + + +protected: + PokemonString(PokemonString const& other); + + + mutable bool hasChanged; + mutable char* _str; + mutable size_t strSz, strCapacity; + + void resizeStr(void) const; +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/BagData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/BagData.h new file mode 100644 index 0000000..e34545e --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/BagData.h @@ -0,0 +1,32 @@ +#ifndef _LIBPKMGC_COLOSSEUM_BAG_DATA_H +#define _LIBPKMGC_COLOSSEUM_BAG_DATA_H + +#include + +namespace LibPkmGC { +namespace Colosseum { + +class LIBPKMGC_DECL BagData : + public GC::BagData +{ +public: + static const size_t size = 0x300; + BagData(void); + BagData(BagData const& other); + BagData(const u8* inData); + ~BagData(); + + void swap(BagData& other); + + BagData* clone(void) const; + BagData* create(void) const; + + +private: + BagData(XD::BagData const&); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/BattleModeData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/BattleModeData.h new file mode 100644 index 0000000..81ce85d --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/BattleModeData.h @@ -0,0 +1,41 @@ +#ifndef _LIBPKMGC_COLOSSEUM_BATTLE_MODE_DATA_H +#define _LIBPKMGC_COLOSSEUM_BATTLE_MODE_DATA_H + +#include +#include + + +namespace LibPkmGC { +namespace Colosseum { + +/* + ?? + 0xc16c: Colosseum::GroupBattleRules rules[26] + ?? +*/ +class LIBPKMGC_DECL BattleModeData : + public GC::BattleModeData +{ +public: + static const size_t size = 0xcc2c; + BattleModeData(void); + BattleModeData(BattleModeData const& other); + BattleModeData(const u8* inData); + ~BattleModeData(); + + BattleModeData* clone(void) const; + BattleModeData* create(void) const; + + void save(void); +protected: + void loadFields(void); + +private: + BattleModeData(XD::BattleModeData const& other); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/DaycareData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/DaycareData.h new file mode 100644 index 0000000..59347ca --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/DaycareData.h @@ -0,0 +1,31 @@ +#ifndef _LIBPKMGC_COLOSSEUM_DAYCARE_DATA_H +#define _LIBPKMGC_COLOSSEUM_DAYCARE_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { + +class LIBPKMGC_DECL DaycareData : + public GC::DaycareData +{ +public: + static const size_t size = 0x140; + DaycareData(void); + DaycareData(const u8* inData); + DaycareData(DaycareData const& other); + ~DaycareData(void); + + DaycareData* clone(void) const; + DaycareData* create(void) const; + + DaycareData(XD::DaycareData const& other); +private: + void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/Everything.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/Everything.h new file mode 100644 index 0000000..4218611 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/Everything.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/GroupBattleRule.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/GroupBattleRule.h new file mode 100644 index 0000000..6177a07 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/GroupBattleRule.h @@ -0,0 +1,36 @@ +#ifndef _LIBPKMGC_COLOSSEUM_GROUP_BATTLE_RULE_H +#define _LIBPKMGC_COLOSSEUM_GROUP_BATTLE_RULE_H + +#include + +namespace LibPkmGC { +namespace Colosseum { + +class LIBPKMGC_DECL GroupBattleRule : + public GC::GroupBattleRule +{ +public: + static const size_t size = 0x54; + GroupBattleRule(const u8* inData); + GroupBattleRule(GroupBattleRule const& other); + GroupBattleRule(void); + ~GroupBattleRule(); + +// void swap(GroupBattleRule& other); + GroupBattleRule* clone(void) const; + GroupBattleRule* create(void) const; + + void save(void); + +protected: + void loadFields(void); + +private: + GroupBattleRule(XD::GroupBattleRule const& other); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/MailboxData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/MailboxData.h new file mode 100644 index 0000000..c52aa51 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/MailboxData.h @@ -0,0 +1,42 @@ +#ifndef _LIBPKMGC_COLOSSEUM_MAILBOX_DATA +#define _LIBPKMGC_COLOSSEUM_MAILBOX_DATA + +#include + +namespace LibPkmGC { +namespace Colosseum { + +/* + 0x00: u16 mails[32] = mailID or 255 if empty; 0x1f: invisible mail + 0x400: u16 nbMails + 0x402: u8 ? + 0x442: u8 ? +*/ + +class LIBPKMGC_DECL MailboxData : + public GC::MailboxData +{ +public: + static const size_t size = 0x448; + MailboxData(void); + MailboxData(MailboxData const& other); + MailboxData(const u8* inData); + ~MailboxData(void); + + MailboxData* clone(void) const; + MailboxData* create(void) const; + + void save(void); + +protected: + void loadFields(void); + +private: + MailboxData(XD::MailboxData const&); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/PCData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PCData.h new file mode 100644 index 0000000..20b61e7 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PCData.h @@ -0,0 +1,38 @@ +#ifndef _LIBPKMGC_COLOSSEUM_PC_DATA_H +#define _LIBPKMGC_COLOSSEUM_PC_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { + +/* + 0x00: PokemonBox boxes[8] + 0x6dec -- end(0x7198): items[235] +*/ + +class LIBPKMGC_DECL PCData : + public GC::PCData +{ +public: + static const size_t size = 0x7198; + PCData(void); + PCData(PCData const& other); + PCData(const u8* inData); + ~PCData(void); + + PCData* clone(void) const; + PCData* create(void) const; + + void save(void); +protected: + void loadFields(void); +private: + PCData(XD::PCData const&); +}; + +} +} + +#endif diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/PlayerData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PlayerData.h new file mode 100644 index 0000000..2960c3a --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PlayerData.h @@ -0,0 +1,49 @@ +#ifndef _LIBPKMGC_COLOSSEUM_PLAYER_DATA_H +#define _LIBPKMGC_COLOSSEUM_PLAYER_DATA_H + +#include +#include +#include + +namespace LibPkmGC { +namespace Colosseum { + +/* + 0x00 -- 0x2b: trainer name (10+1 chars) + copy + 0x2c: u16 SID + 0x2e: u16 TID + 0x30: Pokémon Party (6*0xc4) + + 0x780: bag + + 0xa80: u8 trainerGender + 0xa84: u32 money + 0xa88: u32 pkCoupons + copy +*/ + +class LIBPKMGC_DECL PlayerData : + public GC::PlayerData +{ +public: + static const size_t size = 0xb18; + PlayerData(void); + PlayerData(PlayerData const& other); + + PlayerData(const u8* inData); + + + ~PlayerData(void); + PlayerData* clone(void) const; + PlayerData* create(void) const; + + void save(void); +protected: + void loadFields(void); +private: + PlayerData(XD::PlayerData const& other); +}; + +} +} + +#endif diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/Pokemon.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/Pokemon.h new file mode 100644 index 0000000..c4b921b --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/Pokemon.h @@ -0,0 +1,92 @@ +#ifndef _LIBPKMGC_COLO_POKEMON_H +#define _LIBPKMGC_COLO_POKEMON_H + +#include + +namespace LibPkmGC { +namespace Colosseum { + +/* +pkm + 0x00: u16 index + 0x02 : u16 ? ? ? ? (0 on shadow pkm) + 0x04 : u32 PID + 0x08 : VersionInfo version(4 bytes) + 0x0c : u16 locationCaught + 0x0e : u8 levelMet + 0x0f : u8 ballCaughtWith + 0x10 : u8 OTGender + 0x11 -- 0x13 : ? ? ? ? ? + 0x14 : u16 SID + 0x16 : u16 TID + 0x18 : OT Name(10 + 1 chars, limited to 8 in game) + 0x2e : Pkm Name(10 + 1, or 5 in game for jap.versions) + 0x44 : Pkm name backup + 0x5a -- 0x5b : u16 = field 0x02 backup + 0x5c : u32 experience + 0x60 : u8 currentLevel + 0x61 -- 0x64 : ? ? + 0x65 : u16 status (u8 on XD) + 0x65 -- 0x67 : ? ? + 0x68 : u32 ? ? + 0x6c--0x78 ? ? + 0x78 : moves info + 0x88 : u16 itemHeld + 0x8a : u16 currentHP + 0x8c : u16 stats[6] + 0x98 : u16 EVs[6] + 0xa4 : u16 IVs[6] + 0xb0 : u16 happinness + 0xb2 : u8 contestsStats[5] + 0xb7 : u8 contestsRibbons[5] + 0xbc : u8 contestLuster + 0xbd : u8 specialRibbons[12] + 0xc9 : u8 unused ? + 0xca : u8 pkrsStatus + 0xcb : u8 ? + 0xcc : u8 abilityUsed + 0xcd : u16 ? ? + 0xcf : u8 marks + // shadow pkm data ? + 0xd0--0xd7 : ? ? + 0xd8 : u16 shadowPkmID + 0xda--0xdb : padding ? + 0xdc : s32 purificationCounter + 0xe0 : u32 expStored + 0xe4 : u16 ? ? + 0xe6 : u16 ? ? + 0xfb : u8 encounterType + 0xfc--0x138 : ? ? ? ? ? ? ? ? ? ? +*/ +class LIBPKMGC_DECL Pokemon : public GC::Pokemon { +public: + static const size_t size = 0x138; + Pokemon(void); + Pokemon(const u8* inData); + Pokemon(Pokemon const& other); + ~Pokemon(void); + Pokemon* clone(void) const; + Pokemon* create(void) const; + + void save(void); + + void swap(Pokemon& other); + Pokemon& operator=(Pokemon const& other); + + bool hasSpecialAbility(void) const; + void setSpecialAbilityStatus(bool status); + bool specialAbilityStatus; + + Pokemon(XD::Pokemon const& other); + Pokemon& operator=(GC::Pokemon const& other); + void swap(GC::Pokemon & other); +protected: + void loadFields(void); + +}; + + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/PokemonBox.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PokemonBox.h new file mode 100644 index 0000000..058c602 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/PokemonBox.h @@ -0,0 +1,34 @@ +#ifndef _LIBPKMGC_COLOSSEUM_POKEMON_BOX_H +#define _LIBPKMGC_COLOSSEUM_POKEMON_BOX_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { + +class LIBPKMGC_DECL PokemonBox : + public GC::PokemonBox +{ +public: + static const size_t size = 0x24a4; + PokemonBox(void); + PokemonBox(PokemonBox const& other); + PokemonBox(const u8* inData); + ~PokemonBox(void); + + PokemonBox* clone(void) const; + PokemonBox* create(void) const; + + void save(void); + + PokemonBox(XD::PokemonBox const& other); +protected: + void loadFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoData.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoData.h new file mode 100644 index 0000000..e4bf809 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoData.h @@ -0,0 +1,35 @@ +#ifndef _LIBPKMGC_COLOSSEUM_STRATEGY_MEMO_DATA_H +#define _LIBPKMGC_COLOSSEUM_STRATEGY_MEMO_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { + +class LIBPKMGC_DECL StrategyMemoData : + public GC::StrategyMemoData +{ +public: + static const size_t size = 0x1774; + ~StrategyMemoData(void); + bool isXD(void) const; + + StrategyMemoData(void); + StrategyMemoData(const u8* inData); + StrategyMemoData(StrategyMemoData const& other); + + StrategyMemoData* clone(void) const; + StrategyMemoData* create(void) const; + + void save(void); + + StrategyMemoData(XD::StrategyMemoData const& other); +protected: + void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoEntry.h b/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoEntry.h new file mode 100644 index 0000000..fa51ba1 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/Common/StrategyMemoEntry.h @@ -0,0 +1,30 @@ +#ifndef _LIBPKMGC_COLOSSEUM_STRATEGY_MEMO_ENTRY_H +#define _LIBPKMGC_COLOSSEUM_STRATEGY_MEMO_ENTRY_H + +#include + +namespace LibPkmGC { +namespace Colosseum { + + +class LIBPKMGC_DECL StrategyMemoEntry : + public GC::StrategyMemoEntry +{ +public: + static const size_t size = 12; + ~StrategyMemoEntry(void); + StrategyMemoEntry(void); + StrategyMemoEntry(const u8* inData); + + bool isXD(void) const; + StrategyMemoEntry* clone(void) const; + StrategyMemoEntry* create(void) const; + + bool isInfoPartial(void) const; + void setInfoCompleteness(bool partial); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/Save.h b/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/Save.h new file mode 100644 index 0000000..efc8e4a --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/Save.h @@ -0,0 +1,38 @@ +#ifndef _LIBPKMGC_COLOSSEUM_SAVE_EDITING_SAVE_H +#define _LIBPKMGC_COLOSSEUM_SAVE_EDITING_SAVE_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { +namespace SaveEditing { + +class LIBPKMGC_DECL Save : + public GC::SaveEditing::Save +{ +public: + static const size_t size = 0x60000; + Save(void); + Save(Save const& other); + + Save(const u8* inData, bool hasGCIData_ = false, bool isDecrypted = false); + //~Save(void); + + Save* clone(void) const; + Save* create(void) const; + + void save(void); + +protected: + void loadFields(void); + +private: + Save(XD::SaveEditing::Save const&); +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/SaveSlot.h b/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/SaveSlot.h new file mode 100644 index 0000000..5d8128e --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Colosseum/SaveEditing/SaveSlot.h @@ -0,0 +1,81 @@ +#ifndef _LIBPKMGC_COLOSSEUM_SAVE_EDITING_SAVE_SLOT_H +#define _LIBPKMGC_COLOSSEUM_SAVE_EDITING_SAVE_SLOT_H + +#include +#include + +namespace LibPkmGC { +namespace Colosseum { +namespace SaveEditing { + +/* + size = 0x1e000 + 0x00: u32 magic + 0x04: u32 saveCount + ** Metadata / game config + 0x08: VersionInfo version + 0x0c: u32 headerChecksum + 0x10: u64/u32[2] memcardUID : memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc + + 0x18: **ENCRYPTED DATA** + + 0x18: u32 storyModeSaveCount // saveCount minus the number of times the rules were saved + 0x20: u32 = 0 + 0x31: u8 noRumble + 0x32: u16 titleScreenLanguage; + 0x78: **END OF METADATA + + 0x78: substructures. In Pokémon Colosseum, they are strictly contiguous with no trash bytes in between. + + (end)-60: **END OF ENCRYPTED DATA** + + (end)-60: u8 checksum[20]; // sha1 digest + (end)-40: u8 randomBytes[40]; +*/ + + +class LIBPKMGC_DECL SaveSlot : + public GC::SaveEditing::SaveSlot +{ +public: + static const size_t size = 0x1e000; + SaveSlot(void); + SaveSlot(const SaveSlot& other); + + SaveSlot(const u8* inData, bool isDecrypted = false); + + ~SaveSlot(void); + + SaveSlot* clone(void) const; + SaveSlot* create(void) const; + + void swap(SaveSlot& other); + SaveSlot& operator=(SaveSlot const& other); + + void save(void); + + bool checkChecksum(bool fix = false); + bool checkHeaderChecksum(bool fix = false); + std::pair checkBothChecksums(bool fixGlobalChecksum = false, bool fixHeaderChecksum = false); + bool isCorrupt(void); + + void saveEncrypted(u8* outBuf); + + s32 storyModeSaveCount; + u8 checksum[20]; // digest + + +protected: + void loadData(u32 flags = 0); + void deleteFields(void); + void loadFields(void); +private: + void _deleteFields_extension(void); + SaveSlot(XD::SaveEditing::SaveSlot const&); +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Config.h b/LibPkmGC/include/LibPkmGC/Core/Config.h new file mode 100644 index 0000000..f910014 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Config.h @@ -0,0 +1,24 @@ +#ifndef _LIBPKMGC_CONFIG_H +#define _LIBPKMGC_CONFIG_H + +// _LICENSE_ + +#include +#include +#include +#define LIBPKMGC_VERSION 1000000 +#define LIBPKMGC_VERSION_MAJOR ((LIBPKMGC_VERSION / 1000000) % 1000) +#define LIBPKMGC_VERSION_MINOR ((LIBPKMGC_VERSION / 1000) % 1000) +#define LIBPKMGC_VERSION_BUILD (LIBPKMGC_VERSION % 1000) + +#if defined(LIBPKMGC_DYN_LIB) && !defined(LIBPKMGC_STATIC_LIB) +# ifdef LIBPKMGC_SOURCE +# define LIBPKMGC_DECL BOOST_SYMBOL_EXPORT +# else +# define LIBPKMGC_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# define LIBPKMGC_DECL +#endif + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Crypto.h b/LibPkmGC/include/LibPkmGC/Core/Crypto.h new file mode 100644 index 0000000..33ceb3c --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Crypto.h @@ -0,0 +1,16 @@ +#ifndef _LIBPKMGC_CRYPTO_H +#define _LIBPKMGC_CRYPTO_H + +#include +#include + +namespace LibPkmGC { +namespace Crypto { + +LIBPKMGC_DECL void sha1(const u8* start, const u8* end, u8 digest[20]); +LIBPKMGC_DECL std::string sha1(const u8* data, const u8* end); + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/AbilityNames.h b/LibPkmGC/include/LibPkmGC/Core/Detail/AbilityNames.h new file mode 100644 index 0000000..f7e5897 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/AbilityNames.h @@ -0,0 +1,28 @@ +#ifndef _LIBPKMGC_ABILITY_NAMES_H +#define _LIBPKMGC_ABILITY_NAMES_H + +#include + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Abilities { + +#define NB_NAMES 78 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; +#undef NB_NAMES + +} +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/IntegerManipCode.h b/LibPkmGC/include/LibPkmGC/Core/Detail/IntegerManipCode.h new file mode 100644 index 0000000..075864a --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/IntegerManipCode.h @@ -0,0 +1,120 @@ +template +void fromEnumInteger(OutputIteratorType const& _dest, E const& _integer, size_t _integerSize = sizeof(I)){ + return fromInteger(_dest, (I) _integer, _integerSize); +} + +template +E toEnumInteger(IteratorType const& _bufferIterator, size_t _integerSize = sizeof(I)){ + return (E) toInteger(_bufferIterator, _integerSize); +} + + +template +void fromBoolInteger(OutputIteratorType const& _dest, bool _integer, size_t _integerSize = sizeof(I)){ + return fromInteger(_dest, (I) (_integer) ? 1 : 0, _integerSize); +} + +template +bool toBoolInteger(IteratorType const& _bufferIterator, size_t _integerSize = sizeof(I)){ + return toInteger(_bufferIterator, _integerSize) != 0; +} + +template +void fromArrayOfIntegers(OutputIteratorType const& _dest, IteratorType const& _integers, + IteratorType const& _integersEnd, + size_t _integerSize = sizeof(typename std::iterator_traits::value_type)){ + + typedef typename std::iterator_traits::value_type I; + + size_t _count = std::distance(_integers, _integersEnd); + + IteratorType it(_integers); + OutputIteratorType dst(_dest); + + for(size_t i = 0; i < _count; i++){ + fromInteger(dst, *it, _integerSize); + ++it; + std::advance(dst, _integerSize); + } +} + +template +void fromArrayOfEnumIntegers(OutputIteratorType const& _dest, IteratorType const& _integers, + IteratorType const& _integersEnd, + size_t _integerSize = sizeof(I)){ + + typedef typename std::iterator_traits::value_type E; + size_t _count = std::distance(_integers, _integersEnd); + + IteratorType it(_integers); + OutputIteratorType dst(_dest); + + for(size_t i = 0; i < _count; i++){ + fromEnumInteger(dst, *it, _integerSize); + ++it; + std::advance(dst, _integerSize); + } +} + +template +void fromArrayOfBoolIntegers(OutputIteratorType const& _dest, IteratorType const& _integers, + IteratorType const& _integersEnd, + size_t _integerSize = sizeof(I)){ + + size_t _count = std::distance(_integers, _integersEnd); + + IteratorType it(_integers); + OutputIteratorType dst(_dest); + + for(size_t i = 0; i < _count; i++){ + fromBoolInteger(dst, *it, _integerSize); + ++it; + std::advance(dst, _integerSize); + } +} + +template +void toArrayOfIntegers(OutputIteratorType const& _dest, IteratorType const& _bufferIterator, + IteratorType const& _bufferIteratorEnd, + size_t _integerSize = sizeof(typename std::iterator_traits::value_type)){ +// size_t _count = std::distance(_bufferIterator, bufferIteratorEnd); + typedef typename std::iterator_traits::value_type I; + + IteratorType it2(_bufferIterator); + OutputIteratorType dst(_dest); + + for(; it2 != _bufferIteratorEnd; std::advance(it2, _integerSize)){ + *dst = toInteger(it2, _integerSize); + ++dst; + } +} + +template +void toArrayOfEnumIntegers(OutputIteratorType const& _dest, IteratorType const& _bufferIterator, + IteratorType const& _bufferIteratorEnd, + size_t _integerSize = sizeof(I)){ +// size_t _count = std::distance(_bufferIterator, bufferIteratorEnd); + typedef typename std::iterator_traits::value_type E; + + IteratorType it2(_bufferIterator); + OutputIteratorType dst(_dest); + + for(; it2 != _bufferIteratorEnd; std::advance(it2, _integerSize)){ + *dst = toEnumInteger(it2, _integerSize); + ++dst; + } +} + +template +void toArrayOfBoolIntegers(OutputIteratorType const& _dest, IteratorType const& _bufferIterator, + IteratorType const& _bufferIteratorEnd, + size_t _integerSize = sizeof(I)){ +// size_t _count = std::distance(_bufferIterator, bufferIteratorEnd); + IteratorType it2(_bufferIterator); + OutputIteratorType dst(_dest); + + for(; it2 != _bufferIteratorEnd; std::advance(it2, _integerSize)){ + *dst = toBoolInteger(it2, _integerSize); + ++dst; + } +} \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/ItemNames.h b/LibPkmGC/include/LibPkmGC/Core/Detail/ItemNames.h new file mode 100644 index 0000000..ad0272f --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/ItemNames.h @@ -0,0 +1,63 @@ +#ifndef _LIBPKMGC_ITEM_NAMES_H +#define _LIBPKMGC_ITEM_NAMES_H + + +#include + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace GivableItems { + +#define NB_NAMES 245 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; +#undef NB_NAMES + +} + +namespace ColosseumExclusiveItems { // Some items are common to Col. and XD + +#define NB_NAMES 48 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; + +#undef NB_NAMES + +} + +namespace XDExclusiveItems { + +extern const size_t namesByIndex[94]; +// BEWARE, these ones are not in the correct order +#define NB_NAMES 91 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; +#undef NB_NAMES + +} + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/MoveNames.h b/LibPkmGC/include/LibPkmGC/Core/Detail/MoveNames.h new file mode 100644 index 0000000..8fd8453 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/MoveNames.h @@ -0,0 +1,28 @@ +#ifndef _LIBPKMGC_MOVE_NAMES_H +#define _LIBPKMGC_MOVE_NAMES_H + +#include + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Moves { + +#define NB_NAMES 355 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; +#undef NB_NAMES + +} +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.cpp b/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.cpp new file mode 100644 index 0000000..341b8cf --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.cpp @@ -0,0 +1,183 @@ +#include + + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Natures { + +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const char* englishNames[25] = { + "HARDY", + "LONELY", + "BRAVE", + "ADAMANT", + "NAUGHTY", + "BOLD", + "DOCILE", + "RELAXED", + "IMPISH", + "LAX", + "TIMID", + "HASTY", + "SERIOUS", + "JOLLY", + "NAIVE", + "MODEST", + "MILD", + "QUIET", + "BASHFUL", + "RASH", + "CALM", + "GENTLE", + "SASSY", + "CAREFUL", + "QUIRKY" +}; + +const char* frenchNames[25] = { + "HARDI", + "SOLO", + "BRAVE", + "RIGIDE", + "MAUVAIS", + "ASSURE", + "DOCILE", + "RELAX", + "MALIN", + "LACHE", + "TIMIDE", + "PRESSE", + "SERIEUX", + "JOVIAL", + "NAIF", + "MODESTE", + "DOUX", + "DISCRET", + "PUDIQUE", + "FOUFOU", + "CALME", + "GENTIL", + "MALPOLI", + "PRUDENT", + "BIZARRE", +}; + +const char* germanNames[25] = { + "ROBUST", + "SOLO", + "MUTIG", + "HART", + "FRECH", + "K\xC3\x9CHN", + "SANFT", + "LOCKER", + "PFIFFIG", + "LASCH", + "SCHEU", + "HASTIG", + "ERNST", + "FROH", + "NAIV", + "M\xC3\x84SSIG", + "MILD", + "RUHIG", + "ZAGHAFT", + "HITZIG", + "STILL", + "ZART", + "FORSCH", + "SACHT", + "KAUZIG", +}; + +const char* italianNames[25] = { + "ARDITA", + "SCHIVA", + "AUDACE", + "DECISA", + "BIRBONA", + "SICURA", + "DOCILE", + "PLACIDA", + "SCALTRA", + "FIACCA", + "TIMIDA", + "LESTA", + "SERIA", + "ALLEGRA", + "INGENUA", + "MODESTA", + "MITE", + "QUIETA", + "RITROSA", + "ARDENTE", + "CALMA", + "GENTILE", + "VIVACE", + "CAUTA", + "FURBA", +}; + +const char* spanishNames[25] = { + "FUERTE", + "HURA\xC3\x91""A", + "AUDAZ", + "FIRME", + "P\xC3\x8D""CARA", + "OSADA", + "D\xC3\x93""CIL", + "PL\xC3\x81""CIDA", + "AGITADA", + "FLOJA", + "MIEDOSA", + "ACTIVA", + "SERIA", + "ALEGRE", + "INGENUA", + "MODESTA", + "AFABLE", + "MANSA", + "T\xC3\x8DMIDA", + "ALOCADA", + "SERENA", + "AMABLE", + "GROSERA", + "CAUTA", + "RARA", +}; + +const char* japaneseNames[25] = { + "\xe3\x81\x8c\xe3\x82\x93\xe3\x81\xb0\xe3\x82\x8a\xe3\x82\x84", + "\xe3\x81\x95\xe3\x81\xbf\xe3\x81\x97\xe3\x81\x8c\xe3\x82\x8a", + "\xe3\x82\x86\xe3\x81\x86\xe3\x81\x8b\xe3\x82\x93", + "\xe3\x81\x84\xe3\x81\x98\xe3\x81\xa3\xe3\x81\xb1\xe3\x82\x8a", + "\xe3\x82\x84\xe3\x82\x93\xe3\x81\xa1\xe3\x82\x83", + "\xe3\x81\x9a\xe3\x81\xb6\xe3\x81\xa8\xe3\x81\x84", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x8a", + "\xe3\x81\xae\xe3\x82\x93\xe3\x81\x8d", + "\xe3\x82\x8f\xe3\x82\x93\xe3\x81\xb1\xe3\x81\x8f", + "\xe3\x81\xae\xe3\x81\x86\xe3\x81\xa6\xe3\x82\x93\xe3\x81\x8d", + "\xe3\x81\x8a\xe3\x81\x8f\xe3\x81\xb3\xe3\x82\x87\xe3\x81\x86", + "\xe3\x81\x9b\xe3\x81\xa3\xe3\x81\x8b\xe3\x81\xa1", + "\xe3\x81\xbe\xe3\x81\x98\xe3\x82\x81", + "\xe3\x82\x88\xe3\x81\x86\xe3\x81\x8d", + "\xe3\x82\x80\xe3\x81\x98\xe3\x82\x83\xe3\x81\x8d", + "\xe3\x81\xb2\xe3\x81\x8b\xe3\x81\x88\xe3\x82\x81", + "\xe3\x81\x8a\xe3\x81\xa3\xe3\x81\xa8\xe3\x82\x8a", + "\xe3\x82\x8c\xe3\x81\x84\xe3\x81\x9b\xe3\x81\x84", + "\xe3\x81\xa6\xe3\x82\x8c\xe3\x82\x84", + "\xe3\x81\x86\xe3\x81\xa3\xe3\x81\x8b\xe3\x82\x8a\xe3\x82\x84", + "\xe3\x81\x8a\xe3\x81\xa0\xe3\x82\x84\xe3\x81\x8b", + "\xe3\x81\x8a\xe3\x81\xa8\xe3\x81\xaa\xe3\x81\x97\xe3\x81\x84", + "\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x84\xe3\x81\x8d", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x86", + "\xe3\x81\x8d\xe3\x81\xbe\xe3\x81\x90\xe3\x82\x8c", +}; + +} +} +} +} \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.h b/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.h new file mode 100644 index 0000000..e0905a1 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/NatureNames.h @@ -0,0 +1,28 @@ +#ifndef _LIBPKMGC_NATURE_NAMES_H +#define _LIBPKMGC_NATURE_NAMES_H + +#include + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Natures { + +#define NB_NAMES 25 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; +#undef NB_NAMES + +} +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/SpeciesNames.h b/LibPkmGC/include/LibPkmGC/Core/Detail/SpeciesNames.h new file mode 100644 index 0000000..9ac3e60 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/SpeciesNames.h @@ -0,0 +1,29 @@ +#ifndef _LIBPKMGC_SPECIES_NAMES_H +#define _LIBPKMGC_SPECIES_NAMES_H + +#include + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Species { + +#define NB_NAMES 388 +extern const char LIBPKMGC_DECL *englishNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *frenchNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *germanNames[NB_NAMES]; +extern const char LIBPKMGC_DECL *italianNames[NB_NAMES]; // english names +extern const char LIBPKMGC_DECL *spanishNames[NB_NAMES]; // english names +extern const char LIBPKMGC_DECL *japaneseNames[NB_NAMES]; + +extern const char **names[7]; + +#undef NB_NAMES + +} +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Detail/StructMacros.h b/LibPkmGC/include/LibPkmGC/Core/Detail/StructMacros.h new file mode 100644 index 0000000..5ed6160 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Detail/StructMacros.h @@ -0,0 +1,147 @@ +#ifndef _LIBPKMGC_STRUCT_MACROS_H +#define _LIBPKMGC_STRUCT_MACROS_H + +#include +#include + +#ifdef LIBPKMGC_SOURCE +# define LIBPKMGC_DEFINE_IMPL_HELPER_MACROS +#endif + +#ifdef LIBPKMGC_DEFINE_IMPL_HELPER_MACROS + +#ifndef BUFFER_NAME +#define BUFFER_NAME data +#endif + +#ifndef TARGET_ENDIANNESS +#define TARGET_ENDINANNESS BE +#endif + +#define SM_H_TMP_NS_EVAL() TARGET_ENDINANNESS +#define SM_H_TMP_NS() LibPkmGC::IntegerManip::SM_H_TMP_NS_EVAL() + +#define LD_FIELD(type,fld,off) fld = SM_H_TMP_NS()::toInteger(BUFFER_NAME+off) +#define LD_FIELD_E(type,fld,off,etype) fld = SM_H_TMP_NS()::toEnumInteger(BUFFER_NAME+off) +#define LD_FIELD_B(type,fld,off) fld = SM_H_TMP_NS()::toBoolInteger(BUFFER_NAME+off) +#define LD_ARRAY(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfIntegers(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz)) +#define LD_ARRAY_E(type,ar,sz,off,etype) SM_H_TMP_NS()::toArrayOfEnumIntegers(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz)) +#define LD_ARRAY_B(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfBoolIntegers(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz)) + +#define SV_FIELD(type,fld,off) SM_H_TMP_NS()::fromInteger(BUFFER_NAME+off, fld) +#define SV_FIELD_E(type,fld,off,etype) SM_H_TMP_NS()::fromEnumInteger(BUFFER_NAME+off, fld) +#define SV_FIELD_B(type,fld,off) SM_H_TMP_NS()::fromBoolInteger(BUFFER_NAME+off, fld) +#define SV_ARRAY(type,ar,sz,off) SM_H_TMP_NS()::fromArrayOfIntegers(BUFFER_NAME+off, ar, ar+sz) +#define SV_ARRAY_E(type,ar,sz,off,etype) SM_H_TMP_NS()::fromArrayOfEnumIntegers(BUFFER_NAME+off, ar, ar+sz) +#define SV_ARRAY_B(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfBoolIntegers(BUFFER_NAME+off, ar, ar+sz) + +#define LD_SUBSTRUCTURE(type, fld, off) fld = new type(data + off) +#define LD_SUBSTRUCTURE_ARRAY(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) LD_SUBSTRUCTURE(type, ar[i__], off+type::size*i__); +#define LD_SUBSTRUCTURE_ARRAY2(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) LD_SUBSTRUCTURE(type, ar[i__], off+ar[i__]->getSize()*i__); + +#define SV_SUBSTRUCTURE(type, fld, off) fld->save(); std::copy(fld->data, fld->data + type::size, data + off); +#define SV_SUBSTRUCTURE2(type, fld, off) fld->save(); std::copy(fld->data, fld->data + fld->getSize(), data + off); +#define SV_SUBSTRUCTURE_ARRAY(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE(type, ar[i__], off+type::size*i__); } +//#define SV_SUBSTRUCTURE_ARRAY2(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE2(type, ar[i__], off+ar[i__]->getSize()*i__); } + + + +#define CP(fld) this->fld = other.fld +#define CP_ARRAY(fld, sz) std::copy(other.fld, other.fld+sz, fld) + +#define SW(fld) std::swap(this->fld, other.fld) +#define SW_ARRAY(fld, sz) for(size_t i__0123 = 0; i__0123 < sz; ++i__0123) SW(fld[i__0123]); + +#define ASSIGN_CP(fld) *(this->fld) = *(other.fld) +#define ASSIGN_ARRAY_CP(fld, sz) for(size_t i__1234 = 0; i__1234 < sz; ++i__1234) ASSIGN_CP(fld[i__1234]); + +#define CL(fld) this->fld = other.fld->clone(); +#define CL_ARRAY(fld, sz) for(size_t i__1234 = 0; i__1234 < sz; ++i__1234) CL(fld[i__1234]); + +#define LIBPKMGC_GEN_CONVERTER_CTOR2(cls, flgs) \ +Colosseum::cls::cls(XD::cls const& other) : GC::cls(Colosseum::cls::size){\ + initWithEmptyData(flgs);\ + GC::cls::operator=(other);\ +}\ +XD::cls::cls(Colosseum::cls const& other) : GC::cls(XD::cls::size){\ + initWithEmptyData(flgs);\ + GC::cls::operator=(other);\ +} + +#define LIBPKMGC_GEN_CONVERTER_CTOR(cls) LIBPKMGC_GEN_CONVERTER_CTOR2(cls, 0) + +#define LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(cls)\ +Colosseum::cls::cls(XD::cls const& other) : GC::cls(Colosseum::cls::size, 0){}\ +XD::cls::cls(Colosseum::cls const& other) : GC::cls(XD::cls::size, 0){} + +#define LIBPKMGC_GEN_UNIMPLEMENTED_SAVE_EDITING_CONVERTER_CTOR(cls)\ +Colosseum::SaveEditing::cls::cls(XD::SaveEditing::cls const& other) : GC::SaveEditing::cls(Colosseum::SaveEditing::cls::size, 0){}\ +XD::SaveEditing::cls::cls(Colosseum::SaveEditing::cls const& other) : GC::SaveEditing::cls(XD::SaveEditing::cls::size, 0){} + +#define LIBPKMGC_GC_GEN_XD_VTF2(cls, flgs) \ +cls& cls::operator=(GC::cls const& other){\ +if(LIBPKMGC_IS_XD(cls,&other)) return (cls&) operator=((cls const&)other);\ +else { deleteFields(); initWithEmptyData(flgs); return (cls&) GC::cls::operator=(other); }\ +}\ +void cls::swap(GC::cls & other){\ +if(LIBPKMGC_IS_XD(cls,&other)) swap((cls&)other);\ +else {cls obj((Colosseum::cls&)other); swap(obj); other.swap(obj);}\ +} + +#define LIBPKMGC_GC_GEN_COL_VTF2(cls, flgs) \ +cls& cls::operator=(GC::cls const& other){\ +if(LIBPKMGC_IS_COLOSSEUM(cls,&other)) return operator=((cls const&)other);\ +else { deleteFields(); initWithEmptyData(flgs); return (cls&) GC::cls::operator=(other); }\ +}\ +void cls::swap(GC::cls & other){\ +if(LIBPKMGC_IS_COLOSSEUM(cls,&other)) swap((cls&)other);\ +else {cls obj((XD::cls&)other); swap(obj); other.swap(obj);}\ +} + +#define LIBPKMGC_GC_GEN_XD_VTF(cls) LIBPKMGC_GC_GEN_XD_VTF2(cls,0) +#define LIBPKMGC_GC_GEN_COL_VTF(cls) LIBPKMGC_GC_GEN_COL_VTF2(cls, 0) +#endif + +#ifndef BOOST_NO_SFINAE + +namespace { +#define CREATE_MEMBER_DETECTOR(X) \ +template class Detect_##X { \ + struct Fallback { int X; }; \ + struct Derived : T, Fallback { }; \ + \ + template struct Check; \ + \ + typedef char ArrayOfOne[1]; \ + typedef char ArrayOfTwo[2]; \ + \ + template static ArrayOfOne & func(Check *); \ + template static ArrayOfTwo & func(...); \ + public: \ + typedef Detect_##X type; \ + static const bool value = sizeof(func(0)) == 2; \ +}; + +CREATE_MEMBER_DETECTOR(isXD) +#undef CREATE_MEMBER_DETECTOR + +} + +namespace LibPkmGC { +namespace Detail { +template bool test_isXD_or_true(T* obj, typename boost::disable_if >::type* dummy = NULL) { return true; } +template bool test_isXD_or_true(T* obj, typename boost::enable_if >::type* dummy = NULL) { + return obj->isXD(); +} +} +} + + + +#define LIBPKMGC_IS_XD(cls, obj) ((obj)->fixedSize == LibPkmGC::XD::cls::size && LibPkmGC::Detail::test_isXD_or_true(obj)) +#define LIBPKMGC_IS_COLOSSEUM(cls, obj) ((obj)->fixedSize == LibPkmGC::Colosseum::cls::size && LibPkmGC::Detail::test_isXD_or_true(obj)) + + +#endif + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/IntegerManip.h b/LibPkmGC/include/LibPkmGC/Core/IntegerManip.h new file mode 100644 index 0000000..49161e2 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/IntegerManip.h @@ -0,0 +1,107 @@ +#ifndef _LIBPKMGC_INTEGER_MANIP_H +#define _LIBPKMGC_INTEGER_MANIP_H + +#include + +#include +#include +#include + + +namespace LibPkmGC { +namespace IntegerManip { + +namespace LE { +template +void fromInteger(OutputIteratorType const& _dest, I const& _integer, size_t _integerSize = sizeof(I)) { + OutputIteratorType dst(_dest); + + for (size_t i = 0; i < _integerSize; i++) { + *dst = (_integer >> (8 * i)) & 0xff; + ++dst; + } +} + +template +I toInteger(IteratorType const& _bufferIterator, size_t _integerSize = sizeof(I)) { + + I ret = I(0); + size_t shift = 0; + IteratorType it(_bufferIterator); + for (; shift <= 8 * _integerSize - 8; ++it) { + ret |= (I(*it) << shift); + shift += 8; + } + return ret; +} + +#include + + +} + +namespace BE { + +template +void fromInteger(OutputIteratorType const& _dest, I const& _integer, size_t _integerSize = sizeof(I)) { + OutputIteratorType dst(_dest); + + std::advance(dst, _integerSize - 1); + size_t shift = 0; + + for (; shift < 8 * _integerSize; shift += 8) { + *dst = (_integer >> shift) & 0xff; + if ((shift + 8) < (8 * _integerSize)) --dst; + } +} + +template +I toInteger(IteratorType const& _bufferIterator, size_t _integerSize = sizeof(I)) { + I ret = I(0); + + IteratorType it(_bufferIterator); + size_t shift = 8 * _integerSize - 8; + for (;; ++it) { + ret |= (I(*it) << shift); + if (shift == 0) break; + else shift -= 8; + } + return ret; +} + +#include + +} + + +template +I rotateLeft(I _value, size_t _rotate, size_t _integerSize = sizeof(I)) { + + _rotate %= 8 * _integerSize; + //e.g n [rotate left/right] 33 is equal to n [rotate left/right] 1 if n is a 8/16/32-bit integer + return ((_value << _rotate) | (_value >> (8 * _integerSize - _rotate))); +} + +template +I rotateRight(I _value, size_t _rotate, size_t _integerSize = sizeof(I)) { + + _rotate %= 8 * _integerSize; + return ((_value >> _rotate) | (_value << (8 * _integerSize - _rotate))); +} + +template +I extractBits(I const& _integer, size_t _endBit, size_t _beginBit, size_t _integerSize = sizeof(I)) { + + if ((_endBit >= _integerSize * 8) || (_beginBit >= _integerSize * 8)) + throw std::out_of_range("The values of _beginBit and/or _endBit you specified are too high (more than _integerSize * 8 - 1) !"); + + if (_endBit < _beginBit) + throw std::invalid_argument("_beginBit cannot be greater than _endBit !"); + + return (_integer >> _beginBit) & ((1 << (_endBit - _beginBit + 1)) - 1); +} + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/IntegerTypes.h b/LibPkmGC/include/LibPkmGC/Core/IntegerTypes.h new file mode 100644 index 0000000..61957eb --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/IntegerTypes.h @@ -0,0 +1,26 @@ +#ifndef _LIBPKMGC_INTEGER_TYPES_H +#define _LIBPKMGC_INTEGER_TYPES_H + +#include +#include + +namespace LibPkmGC { + +#ifndef BOOST_NO_INT64_T +typedef boost::uint64_t u64; +typedef boost::int64_t s64; +#else +# define LIBPKM_NO_INT64_T +#endif + +typedef boost::uint32_t u32; +typedef boost::uint16_t u16; +typedef boost::uint8_t u8; + +typedef boost::int32_t s32; +typedef boost::int16_t s16; +typedef boost::int8_t s8; + +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/ItemInfo.h b/LibPkmGC/include/LibPkmGC/Core/ItemInfo.h new file mode 100644 index 0000000..718a344 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/ItemInfo.h @@ -0,0 +1,441 @@ +#ifndef _LIBPKMGC_ITEM_INFO_H +#define _LIBPKMGC_ITEM_INFO_H + +#include + +namespace LibPkmGC { + +enum ItemIndex { + NoItem = 0x0000, + MasterBall = 0x0001, + UltraBall = 0x0002, + GreatBall = 0x0003, + PokeBall = 0x0004, + SafariBall = 0x0005, + NetBall = 0x0006, + DiveBall = 0x0007, + NestBall = 0x0008, + RepeatBall = 0x0009, + TimerBall = 0x000A, + LuxuryBall = 0x000B, + PremierBall = 0x000C, + Potion = 0x000D, + Antidote = 0x000E, + BurnHeal = 0x000F, + IceHeal = 0x0010, + Awakening = 0x0011, + ParlyzHeal = 0x0012, + FullRestore = 0x0013, + MaxPotion = 0x0014, + HyperPotion = 0x0015, + SuperPotion = 0x0016, + FullHeal = 0x0017, + Revive = 0x0018, + MaxRevive = 0x0019, + FreshWater = 0x001A, + SodaPop = 0x001B, + Lemonade = 0x001C, + MoomooMilk = 0x001D, + EnergyPowder = 0x001E, + EnergyRoot = 0x001F, + HealPowder = 0x0020, + RevivalHerb = 0x0021, + Ether = 0x0022, + MaxEther = 0x0023, + Elixir = 0x0024, + MaxElixir = 0x0025, + LavaCookie = 0x0026, + BlueFlute = 0x0027, + YellowFlute = 0x0028, + RedFlute = 0x0029, + BlackFlute = 0x002A, + WhiteFlute = 0x002B, + BerryJuice = 0x002C, + SacredAsh = 0x002D, + ShoalSalt = 0x002E, + ShoalShell = 0x002F, + RedShard = 0x0030, + BlueShard = 0x0031, + YellowShard = 0x0032, + GreenShard = 0x0033, + + + HPUp = 0x003F, + Protein = 0x0040, + Iron = 0x0041, + Carbos = 0x0042, + Calcium = 0x0043, + RareCandy = 0x0044, + PPUp = 0x0045, + Zinc = 0x0046, + PPMax = 0x0047, + + + GuardSpec = 0x0049, + DireHit = 0x004A, + XAttack = 0x004B, + XDefend = 0x004C, + XSpeed = 0x004D, + XAccuracy = 0x004E, + XSpecial = 0x004F, + Pokedoll = 0x0050, + FluffyTail = 0x0051, + + SuperRepel = 0x0053, + MaxRepel = 0x0054, + EscapeRope = 0x0055, + Repel = 0x0056, + + SunStone = 0x005D, + MoonStone = 0x005E, + FireStone = 0x005F, + ThunderStone = 0x0060, + WaterStone = 0x0061, + LeafStone = 0x0062, + + TinyMushroom = 0x0067, + BigMushroom = 0x0068, + + Pearl = 0x006A, + BigPearl = 0x006B, + Stardust = 0x006C, + StarPiece = 0x006D, + Nugget = 0x006E, + HeartScale = 0x006F, + + OrangeMail = 0x0079, + HarborMail = 0x007A, + GlitterMail = 0x007B, + MechMail = 0x007C, + WoodMail = 0x007D, + WaveMail = 0x007E, + BeadMail = 0x007F, + ShadowMail = 0x0080, + TropicMail = 0x0081, + DreamMail = 0x0082, + FabMail = 0x0083, + RetroMail = 0x0084, + + CheriBerry = 0x0085, + ChestoBerry = 0x0086, + PechaBerry = 0x0087, + RawstBerry = 0x0088, + AspearBerry = 0x0089, + LeppaBerry = 0x008A, + OranBerry = 0x008B, + PersimBerry = 0x008C, + LumBerry = 0x008D, + SitrusBerry = 0x008E, + FigyBerry = 0x008F, + WikiBerry = 0x0090, + MagoBerry = 0x0091, + AguavBerry = 0x0092, + IapapaBerry = 0x0093, + RazzBerry = 0x0094, + BlukBerry = 0x0095, + NanabBerry = 0x0096, + WepearBerry = 0x0097, + PinapBerry = 0x0098, + PomegBerry = 0x0099, + KelpsyBerry = 0x009A, + QualotBerry = 0x009B, + HondewBerry = 0x009C, + GrepaBerry = 0x009D, + TamatoBerry = 0x009E, + CornnBerry = 0x009F, + MagostBerry = 0x00A0, + RabutaBerry = 0x00A1, + NomelBerry = 0x00A2, + SpelonBerry = 0x00A3, + PamtreBerry = 0x00A4, + WatmelBerry = 0x00A5, + DurinBerry = 0x00A6, + BelueBerry = 0x00A7, + LiechiBerry = 0x00A8, + GanlonBerry = 0x00A9, + SalacBerry = 0x00AA, + PetayaBerry = 0x00AB, + ApicotBerry = 0x00AC, + LansatBerry = 0x00AD, + StarfBerry = 0x00AE, + EnigmaBerry = 0x00AF, + + BrightPowder = 0x00B3, + WhiteHerb = 0x00B4, + MachoBrace = 0x00B5, + ExpShare = 0x00B6, + QuickClaw = 0x00B7, + SootheBell = 0x00B8, + MentalHerb = 0x00B9, + ChoiceBand = 0x00BA, + KingsRock = 0x00BB, + SilverPowder = 0x00BC, + AmuletCoin = 0x00BD, + CleanseTag = 0x00BE, + SoulDew = 0x00BF, + DeepSeaTooth = 0x00C0, + DeepSeaScale = 0x00C1, + SmokeBall = 0x00C2, + Everstone = 0x00C3, + FocusBand = 0x00C4, + LuckyEgg = 0x00C5, + ScopeLens = 0x00C6, + MetalCoat = 0x00C7, + Leftovers = 0x00C8, + DragonScale = 0x00C9, + LightBall = 0x00CA, + SoftSand = 0x00CB, + HardStone = 0x00CC, + MiracleSeed = 0x00CD, + BlackGlasses = 0x00CE, + BlackBelt = 0x00CF, + Magnet = 0x00D0, + MysticWater = 0x00D1, + SharpBeak = 0x00D2, + PoisonBarb = 0x00D3, + NeverMeltIce = 0x00D4, + SpellTag = 0x00D5, + TwistedSpoon = 0x00D6, + Charcoal = 0x00D7, + DragonFang = 0x00D8, + SilkScarf = 0x00D9, + UpGrade = 0x00DA, + ShellBell = 0x00DB, + SeaIncense = 0x00DC, + LaxIncense = 0x00DD, + LuckyPunch = 0x00DE, + MetalPowder = 0x00DF, + ThickClub = 0x00E0, + Stick = 0x00E1, + + + RedScarf = 0x00FE, + BlueScarf = 0x00FF, + PinkScarf = 0x0100, + GreenScarf = 0x0101, + YellowScarf = 0x0102, + + TM01 = 0x0121, + TM02 = 0x0122, + TM03 = 0x0123, + TM04 = 0x0124, + TM05 = 0x0125, + TM06 = 0x0126, + TM07 = 0x0127, + TM08 = 0x0128, + TM09 = 0x0129, + TM10 = 0x012A, + TM11 = 0x012B, + TM12 = 0x012C, + TM13 = 0x012D, + TM14 = 0x012E, + TM15 = 0x012F, + TM16 = 0x0130, + TM17 = 0x0131, + TM18 = 0x0132, + TM19 = 0x0133, + TM20 = 0x0134, + TM21 = 0x0135, + TM22 = 0x0136, + TM23 = 0x0137, + TM24 = 0x0138, + TM25 = 0x0139, + TM26 = 0x013A, + TM27 = 0x013B, + TM28 = 0x013C, + TM29 = 0x013D, + TM30 = 0x013E, + TM31 = 0x013F, + TM32 = 0x0140, + TM33 = 0x0141, + TM34 = 0x0142, + TM35 = 0x0143, + TM36 = 0x0144, + TM37 = 0x0145, + TM38 = 0x0146, + TM39 = 0x0147, + TM40 = 0x0148, + TM41 = 0x0149, + TM42 = 0x014A, + TM43 = 0x014B, + TM44 = 0x014C, + TM45 = 0x014D, + TM46 = 0x014E, + TM47 = 0x014F, + TM48 = 0x0150, + TM49 = 0x0151, + TM50 = 0x0152, + + /* Colosseum-only items (mostly key items) */ + + JailKey = 0x01F4, + ElevatorKey = 0x01F5, // common to colo and XD + + SmallTablet = 0x01F6, + FDisk = 0x01F7, + RDisk = 0x01F8, + LDisk = 0x01F9, + DDisk = 0x01FA, + UDisk = 0x01FB, + SubwayKey = 0x01FC, + MaingateKey = 0x01FD, + CardKey = 0x01FE, + DownStKey = 0x01FF, + DNASample = 0x0200, + DNASample1 = 0x0201, + DNASample2 = 0x0202, + DNASample3 = 0x0203, + DNASample4 = 0x0204, + DNASample5 = 0x0205, + DNASample6 = 0x0206, + DNASample7 = 0x0207, + DNASample8 = 0x0208, + DNASample9 = 0x0209, + DNASample10 = 0x020A, + DNASample11 = 0x020B, + DNASample12 = 0x020C, + DNASample13 = 0x020D, + DNASample14 = 0x020E, + DNASample15 = 0x020F, + DNASample16 = 0x0210, + DNASample17 = 0x0211, + DataROM_C = 0x0212, + SteelTeeth = 0x0213, + Gear = 0x0214, + RedIDBadge = 0x0215, + GrnIDBadge = 0x0216, + BluIDBadge = 0x0217, + YlwIDBadge = 0x0218, + TimeFlute = 0x0219, + EinFileS = 0x021A, + EinFileH = 0x021B, + EinFileC = 0x021C, + EinFileP = 0x021D, + CologneCase_C = 0x021E, + JoyScent_C = 0x021F, + ExciteScent_C = 0x0220, + VividScent_C = 0x0221, + PowerupPart = 0x0222, + EinFileF = 0x0223, + + + /* XD-only items. On the debugger, they will probably be hidden by the Colosseum-only items */ + SafeKey = 0x01F4, + + BonslyCard = 0x01F6, + MachinePart = 0x01F7, + GonzapsKey = 0x01F8, + DataROM_XD = 0x01F9, + IDCard = 0x01FA, + MusicDisc = 0x01FB, + SystemLever = 0x01FC, + MayorsNote = 0x01FD, + MirorRadar = 0x01FE, + PokeSnack = 0x01FF, + CologneCase_XD = 0x200, + JoyScent_XD = 0x0201, + ExciteScent_XD = 0x0202, + VividScent_XD = 0x0203, + SunShard = 0x0204, + MoonShard = 0x0205, + BonslyPhoto = 0x0206, + CryAnalyzer = 0x0207, + + + KraneMemo1 = 0x020B, + KraneMemo2 = 0x020C, + KraneMemo3 = 0x020D, + KraneMemo4 = 0x020E, + KraneMemo5 = 0x020F, + VoiceCase1 = 0x0210, + VoiceCase2 = 0x0211, + VoiceCase3 = 0x0212, + VoiceCase4 = 0x0213, + VoiceCase5 = 0x0214, + DiscCase = 0x0215, + BattleCD01 = 0x0216, + BattleCD02 = 0x0217, + BattleCD03 = 0x0218, + BattleCD04 = 0x0219, + BattleCD05 = 0x021A, + BattleCD06 = 0x021B, + BattleCD07 = 0x021C, + BattleCD08 = 0x021D, + BattleCD09 = 0x021E, + BattleCD10 = 0x021F, + BattleCD11 = 0x0220, + BattleCD12 = 0x0221, + BattleCD13 = 0x0222, + BattleCD14 = 0x0223, + BattleCD15 = 0x0224, + BattleCD16 = 0x0225, + BattleCD17 = 0x0226, + BattleCD18 = 0x0227, + BattleCD19 = 0x0228, + BattleCD20 = 0x0229, + BattleCD21 = 0x022A, + BattleCD22 = 0x022B, + BattleCD23 = 0x022C, + BattleCD24 = 0x022D, + BattleCD25 = 0x022E, + BattleCD26 = 0x022F, + BattleCD27 = 0x0230, + BattleCD28 = 0x0231, + BattleCD29 = 0x0232, + BattleCD30 = 0x0233, + BattleCD31 = 0x0234, + BattleCD32 = 0x0235, + BattleCD33 = 0x0236, + BattleCD34 = 0x0237, + BattleCD35 = 0x0238, + BattleCD36 = 0x0239, + BattleCD37 = 0x023A, + BattleCD38 = 0x023B, + BattleCD39 = 0x023C, + BattleCD40 = 0x023D, + BattleCD41 = 0x023E, + BattleCD42 = 0x023F, + BattleCD43 = 0x0240, + BattleCD44 = 0x0241, + BattleCD45 = 0x0242, + BattleCD46 = 0x0243, + BattleCD47 = 0x0244, + BattleCD48 = 0x0245, + BattleCD49 = 0x0246, + BattleCD50 = 0x0247, + BattleCD51 = 0x0248, + BattleCD52 = 0x0249, + BattleCD53 = 0x024A, + BattleCD54 = 0x024B, + BattleCD55 = 0x024C, + BattleCD56 = 0x024D, + BattleCD57 = 0x024E, + BattleCD58 = 0x024F, + BattleCD59 = 0x0250, + BattleCD60 = 0x0251, +}; + +struct LIBPKMGC_DECL Item { + ItemIndex index; + u16 quantity; + + void load(u8* data); + void save(u8* data); +}; + +enum ItemCategoryIndex { + NoItemCategory = 0, + PokeballsCategory = 1, + RegularItemsCategory = 2, + BerriesCategory = 3, + TMsCategory = 4, + KeyItemsCategory = 5, + ColognesCategory = 6, + BattleCDsCategory = 7 +}; + +LIBPKMGC_DECL ItemCategoryIndex getItemCategory(ItemIndex index, bool isXD = false); + +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/Localization.h b/LibPkmGC/include/LibPkmGC/Core/Localization.h new file mode 100644 index 0000000..42ffdcb --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/Localization.h @@ -0,0 +1,34 @@ +#ifndef _LIBPKMGC_LOCALIZATION_H +#define _LIBPKMGC_LOCALIZATION_H + +#include +#include +#include +#include +#include +#include +#include + +namespace LibPkmGC { +namespace Localization { + +LIBPKMGC_DECL size_t itemIndexToNameIndex(ItemIndex index, bool isXD = false); +LIBPKMGC_DECL ItemIndex nameIndexToItemIndex(size_t index, bool isXD = false); + +LIBPKMGC_DECL size_t pkmSpeciesIndexToNameIndex(PokemonSpeciesIndex index); +LIBPKMGC_DECL PokemonSpeciesIndex nameIndexToPkmSpeciesIndex(size_t index); + +LIBPKMGC_DECL const char* getPokemonSpeciesName(LanguageIndex language, PokemonSpeciesIndex index); +LIBPKMGC_DECL const char* getPokemonSpeciesNameByPkdxIndex(LanguageIndex language, u16 pkdexIndex); + +LIBPKMGC_DECL const char* getPokemonNatureName(LanguageIndex language, PokemonNatureIndex index); +LIBPKMGC_DECL const char* getPokemonMoveName(LanguageIndex language, PokemonMoveIndex index); +LIBPKMGC_DECL const char* getPokemonAbilityName(LanguageIndex language, PokemonAbilityIndex index); + +LIBPKMGC_DECL const char* getItemName(LanguageIndex language, ItemIndex index, bool isXD = false); + + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/Core/PokemonInfo.h b/LibPkmGC/include/LibPkmGC/Core/PokemonInfo.h new file mode 100644 index 0000000..a48b757 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/Core/PokemonInfo.h @@ -0,0 +1,1012 @@ +#ifndef _LIBPKMGC_POKEMON_INFO_H +#define _LIBPKMGC_POKEMON_INFO_H + +#include +namespace LibPkmGC{ +enum GameIndex { + NoGame = 0, + FireRed = 1, + LeafGreen = 2, + + Sapphire = 8, + Ruby = 9, + Emerald = 10, + + Colosseum_XD = 11 +}; +enum RegionIndex { + NoRegion = 0, NTSC_J = 1, NTSC_U = 2, PAL = 3 +}; +enum LanguageIndex { + NoLanguage = 0, Japanese = 1, English = 2, German = 3, French = 4, Italian = 5, Spanish = 6 +}; + +struct LIBPKMGC_DECL VersionInfo { + /* The following enum values come from Col/XD */ + + GameIndex game; + RegionIndex currentRegion; + RegionIndex originalRegion; + + LanguageIndex language; + + void load(u8* data); + + void save(u8* data); + + bool isIncomplete(void) const; + +}; + +const VersionInfo emptyVersionInfo = { NoGame, NoRegion, NoRegion, NoLanguage }; + +enum ContestAchievementLevel { + NoContestWon = 0, + NormalContestWon = 1, + SuperContestWon = 2, + HyperContestWon = 3, + MasterContestWon = 4 +}; + + +enum Gender{ Male = 0, Female = 1, Genderless = 2 }; +enum EncounterType{ + Unencountered = 0, + FatefulEncounter = 1, + Gift = 0x50, + NormalEncounter = 0xb8, +}; + +enum PokemonStorageUnit { + NotStored = 0, + StoredInParty = 1, + StoredInPC = 2, + StoredInPurifier = 3, + StoredInDaycare = 4 +}; + +struct LIBPKMGC_DECL PokemonStorageInfo { + PokemonStorageUnit storageUnit; + size_t index, subIndex; +}; + +const PokemonStorageInfo emptyStorageInfo = { NotStored, 0, 0 }; + +enum PokemonSpeciesIndex{ + NoSpecies = 0, + Bulbasaur = 0x01, + Ivysaur = 0x02, + Venusaur = 0x03, + Charmander = 0x04, + Charmeleon = 0x05, + Charizard = 0x06, + Squirtle = 0x07, + Wartortle = 0x08, + Blastoise = 0x09, + Caterpie = 0x0A, + Metapod = 0x0B, + Butterfree = 0x0C, + Weedle = 0x0D, + Kakuna = 0x0E, + Beedrill = 0x0F, + Pidgey = 0x10, + Pidgeotto = 0x11, + Pidgeot = 0x12, + Rattata = 0x13, + Raticate = 0x14, + Spearow = 0x15, + Fearow = 0x16, + Ekans = 0x17, + Arbok = 0x18, + Pikachu = 0x19, + Raichu = 0x1A, + Sandshrew = 0x1B, + Sandslash = 0x1C, + NidoranF = 0x1D, + Nidorina = 0x1E, + Nidoqueen = 0x1F, + NidoranM = 0x20, + Nidorino = 0x21, + Nidoking = 0x22, + Clefairy = 0x23, + Clefable = 0x24, + Vulpix = 0x25, + Ninetales = 0x26, + Jigglypuff = 0x27, + Wigglytuff = 0x28, + Zubat = 0x29, + Golbat = 0x2A, + Oddish = 0x2B, + Gloom = 0x2C, + Vileplume = 0x2D, + Paras = 0x2E, + Parasect = 0x2F, + Venonat = 0x30, + Venomoth = 0x31, + Diglett = 0x32, + Dugtrio = 0x33, + Meowth = 0x34, + Persian = 0x35, + Psyduck = 0x36, + Golduck = 0x37, + Mankey = 0x38, + Primeape = 0x39, + Growlithe = 0x3A, + Arcanine = 0x3B, + Poliwag = 0x3C, + Poliwhirl = 0x3D, + Poliwrath = 0x3E, + Abra = 0x3F, + Kadabra = 0x40, + Alakazam = 0x41, + Machop = 0x42, + Machoke = 0x43, + Machamp = 0x44, + Bellsprout = 0x45, + Weepinbell = 0x46, + Victreebel = 0x47, + Tentacool = 0x48, + Tentacruel = 0x49, + Geodude = 0x4A, + Graveler = 0x4B, + Golem = 0x4C, + Ponyta = 0x4D, + Rapidash = 0x4E, + Slowpoke = 0x4F, + Slowbro = 0x50, + Magnemite = 0x51, + Magneton = 0x52, + Farfetch_d = 0x53, + Doduo = 0x54, + Dodrio = 0x55, + Seel = 0x56, + Dewgong = 0x57, + Grimer = 0x58, + Muk = 0x59, + Shellder = 0x5A, + Cloyster = 0x5B, + Gastly = 0x5C, + Haunter = 0x5D, + Gengar = 0x5E, + Onix = 0x5F, + Drowzee = 0x60, + Hypno = 0x61, + Krabby = 0x62, + Kingler = 0x63, + Voltorb = 0x64, + Electrode = 0x65, + Exeggcute = 0x66, + Exeggutor = 0x67, + Cubone = 0x68, + Marowak = 0x69, + Hitmonlee = 0x6A, + Hitmonchan = 0x6B, + Lickitung = 0x6C, + Koffing = 0x6D, + Weezing = 0x6E, + Rhyhorn = 0x6F, + Rhydon = 0x70, + Chansey = 0x71, + Tangela = 0x72, + Kangaskhan = 0x73, + Horsea = 0x74, + Seadra = 0x75, + Goldeen = 0x76, + Seaking = 0x77, + Staryu = 0x78, + Starmie = 0x79, + MrMime = 0x7A, + Scyther = 0x7B, + Jynx = 0x7C, + Electabuzz = 0x7D, + Magmar = 0x7E, + Pinsir = 0x7F, + Tauros = 0x80, + Magikarp = 0x81, + Gyarados = 0x82, + Lapras = 0x83, + Ditto = 0x84, + Eevee = 0x85, + Vaporeon = 0x86, + Jolteon = 0x87, + Flareon = 0x88, + Porygon = 0x89, + Omanyte = 0x8A, + Omastar = 0x8B, + Kabuto = 0x8C, + Kabutops = 0x8D, + Aerodactyl = 0x8E, + Snorlax = 0x8F, + Articuno = 0x90, + Zapdos = 0x91, + Moltres = 0x92, + Dratini = 0x93, + Dragonair = 0x94, + Dragonite = 0x95, + Mewtwo = 0x96, + Mew = 0x97, + + Chikorita = 0x98, + Bayleef = 0x99, + Meganium = 0x9A, + Cyndaquil = 0x9B, + Quilava = 0x9C, + Typhlosion = 0x9D, + Totodile = 0x9E, + Croconaw = 0x9F, + Feraligatr = 0xA0, + Sentret = 0xA1, + Furret = 0xA2, + Hoothoot = 0xA3, + Noctowl = 0xA4, + Ledyba = 0xA5, + Ledian = 0xA6, + Spinarak = 0xA7, + Ariados = 0xA8, + Crobat = 0xA9, + Chinchou = 0xAA, + Lanturn = 0xAB, + Pichu = 0xAC, + Cleffa = 0xAD, + Igglybuff = 0xAE, + Togepi = 0xAF, + Togetic = 0xB0, + Natu = 0xB1, + Xatu = 0xB2, + Mareep = 0xB3, + Flaaffy = 0xB4, + Ampharos = 0xB5, + Bellossom = 0xB6, + Marill = 0xB7, + Azumarill = 0xB8, + Sudowoodo = 0xB9, + Politoed = 0xBA, + Hoppip = 0xBB, + Skiploom = 0xBC, + Jumpluff = 0xBD, + Aipom = 0xBE, + Sunkern = 0xBF, + Sunflora = 0xC0, + Yanma = 0xC1, + Wooper = 0xC2, + Quagsire = 0xC3, + Espeon = 0xC4, + Umbreon = 0xC5, + Murkrow = 0xC6, + Slowking = 0xC7, + Misdreavus = 0xC8, + Unown = 0xC9, + Wobbuffet = 0xCA, + Girafarig = 0xCB, + Pineco = 0xCC, + Forretress = 0xCD, + Dunsparce = 0xCE, + Gligar = 0xCF, + Steelix = 0xD0, + Snubbull = 0xD1, + Granbull = 0xD2, + Qwilfish = 0xD3, + Scizor = 0xD4, + Shuckle = 0xD5, + Heracross = 0xD6, + Sneasel = 0xD7, + Teddiursa = 0xD8, + Ursaring = 0xD9, + Slugma = 0xDA, + Magcargo = 0xDB, + Swinub = 0xDC, + Piloswine = 0xDD, + Corsola = 0xDE, + Remoraid = 0xDF, + Octillery = 0xE0, + Delibird = 0xE1, + Mantine = 0xE2, + Skarmory = 0xE3, + Houndour = 0xE4, + Houndoom = 0xE5, + Kingdra = 0xE6, + Phanpy = 0xE7, + Donphan = 0xE8, + Porygon2 = 0xE9, + Stantler = 0xEA, + Smeargle = 0xEB, + Tyrogue = 0xEC, + Hitmontop = 0xED, + Smoochum = 0xEE, + Elekid = 0xEF, + Magby = 0xF0, + Miltank = 0xF1, + Blissey = 0xF2, + Raikou = 0xF3, + Entei = 0xF4, + Suicune = 0xF5, + Larvitar = 0xF6, + Pupitar = 0xF7, + Tyranitar = 0xF8, + Lugia = 0xF9, + HoOh = 0xFA, + Celebi = 0xFB, + + Treecko = 0x115, + Grovyle = 0x116, + Sceptile = 0x117, + Torchic = 0x118, + Combusken = 0x119, + Blaziken = 0x11A, + Mudkip = 0x11B, + Marshtomp = 0x11C, + Swampert = 0x11D, + Poochyena = 0x11E, + Mightyena = 0x11F, + Zigzagoon = 0x120, + Linoone = 0x121, + Wurmple = 0x122, + Silcoon = 0x123, + Beautifly = 0x124, + Cascoon = 0x125, + Dustox = 0x126, + Lotad = 0x127, + Lombre = 0x128, + Ludicolo = 0x129, + Seedot = 0x12A, + Nuzleaf = 0x12B, + Shiftry = 0x12C, + Nincada = 0x12D, + Ninjask = 0x12E, + Shedinja = 0x12F, + Taillow = 0x130, + Swellow = 0x131, + Shroomish = 0x132, + Breloom = 0x133, + Spinda = 0x134, + Wingull = 0x135, + Pelipper = 0x136, + Surskit = 0x137, + Masquerain = 0x138, + Wailmer = 0x139, + Wailord = 0x13A, + Skitty = 0x13B, + Delcatty = 0x13C, + Kecleon = 0x13D, + Baltoy = 0x13E, + Claydol = 0x13F, + Nosepass = 0x140, + Torkoal = 0x141, + Sableye = 0x142, + Barboach = 0x143, + Whiscash = 0x144, + Luvdisc = 0x145, + Corphish = 0x146, + Crawdaunt = 0x147, + Feebas = 0x148, + Milotic = 0x149, + Carvanha = 0x14A, + Sharpedo = 0x14B, + Trapinch = 0x14C, + Vibrava = 0x14D, + Flygon = 0x14E, + Makuhita = 0x14F, + Hariyama = 0x150, + Electrike = 0x151, + Manectric = 0x152, + Numel = 0x153, + Camerupt = 0x154, + Spheal = 0x155, + Sealeo = 0x156, + Walrein = 0x157, + Cacnea = 0x158, + Cacturne = 0x159, + Snorunt = 0x15A, + Glalie = 0x15B, + Lunatone = 0x15C, + Solrock = 0x15D, + Azurill = 0x15E, + Spoink = 0x15F, + Grumpig = 0x160, + Plusle = 0x161, + Minun = 0x162, + Mawile = 0x163, + Meditite = 0x164, + Medicham = 0x165, + Swablu = 0x166, + Altaria = 0x167, + Wynaut = 0x168, + Duskull = 0x169, + Dusclops = 0x16A, + Roselia = 0x16B, + Slakoth = 0x16C, + Vigoroth = 0x16D, + Slaking = 0x16E, + Gulpin = 0x16F, + Swalot = 0x170, + Tropius = 0x171, + Whismur = 0x172, + Loudred = 0x173, + Exploud = 0x174, + Clamperl = 0x175, + Huntail = 0x176, + Gorebyss = 0x177, + Absol = 0x178, + Shuppet = 0x179, + Banette = 0x17A, + Seviper = 0x17B, + Zangoose = 0x17C, + Relicanth = 0x17D, + Aron = 0x17E, + Lairon = 0x17F, + Aggron = 0x180, + Castform = 0x181, + Volbeat = 0x182, + Illumise = 0x183, + Lileep = 0x184, + Cradily = 0x185, + Anorith = 0x186, + Armaldo = 0x187, + Ralts = 0x188, + Kirlia = 0x189, + Gardevoir = 0x18A, + Bagon = 0x18B, + Shelgon = 0x18C, + Salamence = 0x18D, + Beldum = 0x18E, + Metang = 0x18F, + Metagross = 0x190, + Regirock = 0x191, + Regice = 0x192, + Registeel = 0x193, + Kyogre = 0x194, + Groudon = 0x195, + Rayquaza = 0x196, + Latias = 0x197, + Latios = 0x198, + Jirachi = 0x199, + Deoxys = 0x19A, + Chimecho = 0x19B, + + Bonsly = 0x19D, + Munchlax = 0x19E // Munchlax is not a valid Pokémon in this game (0 base stats total), unlike Bonsly +}; + +enum PokemonNatureIndex{ + Hardy = 0, + Lonely = 1, + Brave = 2, + Adamant = 3, + Naughty = 4, + Bold = 5, + Docile = 6, + Relaxed = 7, + Impish = 8, + Lax = 9, + Timid = 10, + Hasty = 11, + Serious = 12, + Jolly = 13, + Naive = 14, + Modest = 15, + Mild = 16, + Quiet = 17, + Bashful = 18, + Rash = 19, + Calm = 20, + Gentle = 21, + Sassy = 22, + Careful = 23, + Quirky = 24 +}; + + + +enum PokemonMoveIndex{ + NoMove = 0, + Pound = 1, + KarateChop = 2, + DoubleSlap = 3, + CometPunch = 4, + MegaPunch = 5, + PayDay = 6, + FirePunch = 7, + IcePunch = 8, + ThunderPunch = 9, + Scratch = 10, + ViceGrip = 11, + Guillotine = 12, + RazorWind = 13, + SwordsDance = 14, + Cut = 15, + Gust = 16, + WingAttack = 17, + Whirlwind = 18, + Fly = 19, + Bind = 20, + Slam = 21, + VineWhip = 22, + Stomp = 23, + DoubleKick = 24, + MegaKick = 25, + JumpKick = 26, + RollingKick = 27, + SandAttack = 28, + Headbutt = 29, + HornAttack = 30, + FuryAttack = 31, + HornDrill = 32, + Tackle = 33, + BodySlam = 34, + Wrap = 35, + TakeDown = 36, + Thrash = 37, + DoubleEdge = 38, + TailWhip = 39, + PoisonSting = 40, + Twineedle = 41, + PinMissile = 42, + Leer = 43, + Bite = 44, + Growl = 45, + Roar = 46, + Sing = 47, + Supersonic = 48, + SonicBoom = 49, + Disable = 50, + Acid = 51, + Ember = 52, + Flamethrower = 53, + Mist = 54, + WaterGun = 55, + HydroPump = 56, + Surf = 57, + IceBeam = 58, + Blizzard = 59, + Psybeam = 60, + BubbleBeam = 61, + AuroraBeam = 62, + HyperBeam = 63, + Peck = 64, + DrillPeck = 65, + Submission = 66, + LowKick = 67, + Counter = 68, + SeismicToss = 69, + Strength = 70, + Absorb = 71, + MegaDrain = 72, + LeechSeed = 73, + Growth = 74, + RazorLeaf = 75, + SolarBeam = 76, + PoisonPowder = 77, + StunSpore = 78, + SleepPowder = 79, + PetalDance = 80, + StringShot = 81, + DragonRage = 82, + FireSpin = 83, + ThunderShock = 84, + Thunderbolt = 85, + ThunderWave = 86, + Thunder = 87, + RockThrow = 88, + Earthquake = 89, + Fissure = 90, + Dig = 91, + Toxic = 92, + Confusion = 93, + Psychic = 94, + Hypnosis = 95, + Meditate = 96, + Agility = 97, + QuickAttack = 98, + Rage = 99, + Teleport = 100, + NightShade = 101, + Mimic = 102, + Screech = 103, + DoubleTeam = 104, + Recover = 105, + Harden = 106, + Minimize = 107, + Smokescreen = 108, + ConfuseRay = 109, + Withdraw = 110, + DefenseCurl = 111, + Barrier = 112, + LightScreen = 113, + Haze = 114, + Reflect = 115, + FocusEnergy = 116, + Bide = 117, + Metronome = 118, + MirrorMove = 119, + SelfDestruct = 120, + EggBomb = 121, + Lick = 122, + Smog = 123, + Sludge = 124, + BoneClub = 125, + FireBlast = 126, + Waterfall = 127, + Clamp = 128, + Swift = 129, + SkullBash = 130, + SpikeCannon = 131, + Constrict = 132, + Amnesia = 133, + Kinesis = 134, + SoftBoiled = 135, + HighJumpKick = 136, + Glare = 137, + DreamEater = 138, + PoisonGas = 139, + Barrage = 140, + LeechLife = 141, + LovelyKiss = 142, + SkyAttack = 143, + Transform = 144, + Bubble = 145, + DizzyPunch = 146, + Spore = 147, + Flash = 148, + Psywave = 149, + Splash = 150, + AcidArmor = 151, + Crabhammer = 152, + Explosion = 153, + FurySwipes = 154, + Bonemerang = 155, + Rest = 156, + RockSlide = 157, + HyperFang = 158, + Sharpen = 159, + Conversion = 160, + TriAttack = 161, + SuperFang = 162, + Slash = 163, + Substitute = 164, + Struggle = 165, + Sketch = 166, + TripleKick = 167, + Thief = 168, + SpiderWeb = 169, + MindReader = 170, + Nightmare = 171, + FlameWheel = 172, + Snore = 173, + Curse = 174, + Flail = 175, + Conversion2 = 176, + Aeroblast = 177, + CottonSpore = 178, + Reversal = 179, + Spite = 180, + PowderSnow = 181, + Protect = 182, + MachPunch = 183, + ScaryFace = 184, + FeintAttack = 185, + SweetKiss = 186, + BellyDrum = 187, + SludgeBomb = 188, + MudSlap = 189, + Octazooka = 190, + Spikes = 191, + ZapCannon = 192, + Foresight = 193, + DestinyBond = 194, + PerishSong = 195, + IcyWind = 196, + Detect = 197, + BoneRush = 198, + LockOn = 199, + Outrage = 200, + Sandstorm = 201, + GigaDrain = 202, + Endure = 203, + Charm = 204, + Rollout = 205, + FalseSwipe = 206, + Swagger = 207, + MilkDrink = 208, + Spark = 209, + FuryCutter = 210, + SteelWing = 211, + MeanLook = 212, + Attract = 213, + SleepTalk = 214, + HealBell = 215, + Return = 216, + Present = 217, + Frustration = 218, + Safeguard = 219, + PainSplit = 220, + SacredFire = 221, + Magnitude = 222, + DynamicPunch = 223, + Megahorn = 224, + DragonBreath = 225, + BatonPass = 226, + Encore = 227, + Pursuit = 228, + RapidSpin = 229, + SweetScent = 230, + IronTail = 231, + MetalClaw = 232, + VitalThrow = 233, + MorningSun = 234, + Synthesis = 235, + Moonlight = 236, + HiddenPower = 237, + CrossChop = 238, + Twister = 239, + RainDance = 240, + SunnyDay = 241, + Crunch = 242, + MirrorCoat = 243, + PsychUp = 244, + ExtremeSpeed = 245, + AncientPower = 246, + ShadowBall = 247, + FutureSight = 248, + RockSmash = 249, + Whirlpool = 250, + BeatUp = 251, + FakeOut = 252, + Uproar = 253, + Stockpile = 254, + SpitUp = 255, + Swallow = 256, + HeatWave = 257, + Hail = 258, + Torment = 259, + Flatter = 260, + WillOWisp = 261, + Memento = 262, + Facade = 263, + FocusPunch = 264, + SmellingSalts = 265, + FollowMe = 266, + NaturePower = 267, + Charge = 268, + Taunt = 269, + HelpingHand = 270, + Trick = 271, + RolePlay = 272, + Wish = 273, + Assist = 274, + Ingrain = 275, + Superpower = 276, + MagicCoat = 277, + Recycle = 278, + Revenge = 279, + BrickBreak = 280, + Yawn = 281, + KnockOff = 282, + Endeavor = 283, + Eruption = 284, + SkillSwap = 285, + Imprison = 286, + Refresh = 287, + Grudge = 288, + Snatch = 289, + SecretPower = 290, + Dive = 291, + ArmThrust = 292, + Camouflage = 293, + TailGlow = 294, + LusterPurge = 295, + MistBall = 296, + FeatherDance = 297, + TeeterDance = 298, + BlazeKick = 299, + MudSport = 300, + IceBall = 301, + NeedleArm = 302, + SlackOff = 303, + HyperVoice = 304, + PoisonFang = 305, + CrushClaw = 306, + BlastBurn = 307, + HydroCannon = 308, + MeteorMash = 309, + Astonish = 310, + WeatherBall = 311, + Aromatherapy = 312, + FakeTears = 313, + AirCutter = 314, + Overheat = 315, + OdorSleuth = 316, + RockTomb = 317, + SilverWind = 318, + MetalSound = 319, + GrassWhistle = 320, + Tickle = 321, + CosmicPower = 322, + WaterSpout = 323, + SignalBeam = 324, + ShadowPunch = 325, + Extrasensory = 326, + SkyUppercut = 327, + SandTomb = 328, + SheerCold = 329, + MuddyWater = 330, + BulletSeed = 331, + AerialAce = 332, + IcicleSpear = 333, + IronDefense = 334, + Block = 335, + Howl = 336, + DragonClaw = 337, + FrenzyPlant = 338, + BulkUp = 339, + Bounce = 340, + MudShot = 341, + PoisonTail = 342, + Covet = 343, + VoltTackle = 344, + MagicalLeaf = 345, + WaterSport = 346, + CalmMind = 347, + LeafBlade = 348, + DragonDance = 349, + RockBlast = 350, + ShockWave = 351, + WaterPulse = 352, + DoomDesire = 353, + PsychoBoost = 354 +}; + +enum PokemonSpeciesExpGrowthType { + MediumFast = 0, + Erratic = 1, + Fluctuating = 2, + MediumSlow = 3, + Fast = 4, + Slow = 5, +}; + +enum PokemonNatureAffinity { + Beneficial = 0, Neutral = 1, Detrimental = 2 +}; + +enum PokemonAbilityIndex { + NoAbility = 0, + Stench = 1, + Drizzle = 2, + SpeedBoost = 3, + BattleArmor = 4, + Sturdy = 5, + Damp = 6, + Limber = 7, + SandVeil = 8, + Static = 9, + VoltAbsorb = 10, + WaterAbsorb = 11, + Oblivious = 12, + CloudNine = 13, + Compoundeyes = 14, + Insomnia = 15, + ColorChange = 16, + Immunity = 17, + FlashFire = 18, + ShieldDust = 19, + OwnTempo = 20, + SuctionCups = 21, + Intimidate = 22, + ShadowTag = 23, + RoughSkin = 24, + WonderGuard = 25, + Levitate = 26, + EffectSpore = 27, + Synchronize = 28, + ClearBody = 29, + NaturalCure = 30, + Lightningrod = 31, + SereneGrace = 32, + SwiftSwim = 33, + Chlorophyll = 34, + Illuminate = 35, + Trace = 36, + HugePower = 37, + PoisonPoint = 38, + InnerFocus = 39, + MagmaArmor = 40, + WaterVeil = 41, + MagnetPull = 42, + Soundproof = 43, + RainDish = 44, + SandStream = 45, + Pressure = 46, + ThickFat = 47, + EarlyBird = 48, + FlameBody = 49, + RunAway = 50, + KeenEye = 51, + HyperCutter = 52, + Pickup = 53, + Truant = 54, + Hustle = 55, + CuteCharm = 56, + Plus = 57, + Minus = 58, + Forecast = 59, + StickyHold = 60, + ShedSkin = 61, + Guts = 62, + MarvelScale = 63, + LiquidOoze = 64, + Overgrow = 65, + Blaze = 66, + Torrent = 67, + Swarm = 68, + RockHead = 69, + Drought = 70, + ArenaTrap = 71, + VitalSpirit = 72, + WhiteSmoke = 73, + PurePower = 74, + ShellArmor = 75, + Cacophony = 76, + AirLock = 77, +}; + +enum PokemonSpeciesGenderRatio { + MaleOnly = 0, + M7F1 = 31, + M1F3 = 63, + M1F1 = 127, + M3F1 = 191, + M1F7 = 223, + FemaleOnly = 254, + GenderlessOnly = 255, // 'Only' to avoid a name clash with enum Gender +}; + +enum PokemonStatus { + NoStatus = 0, Poisoned = 3, BadlyPoisoned = 4, Paralyzed = 5, Burnt = 6, Frozen = 7, Asleep = 8 +}; + +struct LIBPKMGC_DECL PokemonSpeciesData { + bool isValid; + PokemonSpeciesExpGrowthType expGrowthType; + PokemonSpeciesGenderRatio genderRatio; + u16 baseHappinness; + PokemonAbilityIndex possibleAbilities[2]; + u16 baseStats[6]; + u16 EVYield[6]; +}; + +LIBPKMGC_DECL const u32* getSpeciesExpTable(PokemonSpeciesIndex index); +LIBPKMGC_DECL PokemonSpeciesData getSpeciesData(PokemonSpeciesIndex index); +LIBPKMGC_DECL PokemonNatureAffinity getNatureStatAffinity(PokemonNatureIndex nature, size_t stat); +LIBPKMGC_DECL u8 getBaseMoveMaxPPs(PokemonMoveIndex move); + +/* +LIBPKMGC_DECL extern const u32 expTables[6][101]; +LIBPKMGC_DECL extern const PokemonSpeciesData speciesData[0x19f]; +LIBPKMGC_DECL extern const PokemonNatureAffinity natureStatAffinities[25][5]; +LIBPKMGC_DECL extern const u8 baseMoveMaxPPs[355];*/ + +LIBPKMGC_DECL u16 getPokedexIndexOf(PokemonSpeciesIndex speciesIndex); +LIBPKMGC_DECL PokemonSpeciesIndex getSpeciesIndexOf(u16 pokedexIndex); + +struct LIBPKMGC_DECL PokemonMove { + PokemonMoveIndex moveIndex; + u8 currentPPs; + u8 nbPPUpsUsed; + + void load(u8* data); + + void save(u8* data); + + u8 calculateMaxPP(void) const; + +}; + +struct LIBPKMGC_DECL PokemonMarkings { + bool circle, square, triangle, heart; + void load(u8 m); + u8 save(void) const; +}; + +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/BagData.h b/LibPkmGC/include/LibPkmGC/GC/Common/BagData.h new file mode 100644 index 0000000..2af72ed --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/BagData.h @@ -0,0 +1,47 @@ +#ifndef _LIBPKMGC_GC_BAG_DATA_H +#define _LIBPKMGC_GC_BAG_DATA_H + +#include +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(BagData) +namespace GC { + +class LIBPKMGC_DECL BagData : + public Base::DataStruct +{ +public: + BagData(size_t inSize, size_t nb_regular_items, const u8* inData = NULL); + + virtual ~BagData(); + + virtual BagData* clone(void) const = 0; + virtual BagData* create(void) const = 0; + + void swap(BagData& other); + + BagData& operator=(BagData const& other); + + virtual void save(void); + + const size_t nbRegularItems; + Item* regularItems; + Item keyItems[43]; + Item pokeballs[16]; + Item TMs[64]; + Item berries[46]; + Item colognes[3]; + +protected: + BagData(BagData const& other); + + virtual void deleteFields(void); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/BattleModeData.h b/LibPkmGC/include/LibPkmGC/GC/Common/BattleModeData.h new file mode 100644 index 0000000..c550c1b --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/BattleModeData.h @@ -0,0 +1,38 @@ +#ifndef _LIBPKMGC_GC_BATTLE_MODE_DATA_H +#define _LIBPKMGC_GC_BATTLE_MODE_DATA_H + +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(BattleModeData) + +namespace GC { + +class LIBPKMGC_DECL BattleModeData : + public Base::DataStruct +{ +public: + BattleModeData(size_t inSize, const u8* inData = NULL); + + virtual ~BattleModeData(); + + virtual BattleModeData* clone(void) const = 0; + virtual BattleModeData* create(void) const = 0; + + void swap(BattleModeData& other); + BattleModeData& operator=(BattleModeData const& other); + + GroupBattleRule* rules[6]; + +protected: + BattleModeData(BattleModeData const& other); + + virtual void deleteFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/DaycareData.h b/LibPkmGC/include/LibPkmGC/GC/Common/DaycareData.h new file mode 100644 index 0000000..659344f --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/DaycareData.h @@ -0,0 +1,58 @@ +#ifndef _LIBPKMGC_GC_DAYCARE_DATA_H +#define _LIBPKMGC_GC_DAYCARE_DATA_H + +#include + + +namespace LibPkmGC { + +enum DaycareStatus { + NotVisited = -1, NoPkmDeposited = 0, PkmDeposited = 1 +}; + +LIBPKMGC_FWD_DECL_GC_CLS(DaycareData) + +namespace GC { + +/* +For both Colosseum and XD: + 0x00: s8 daycareStatus (0: no pkm, >1: pkm in daycare, <0: first visit (XD only) + 0x01: u8 initialPkmLevel; + 0x02: padding/trash data + 0x04: u32 initialPurificationCounter + 0x08--end: stored pkm +*/ + +// Cost of daycare : 100*(1 + (currentLevel - initialLevel) + 1 + int((purifCtr - initialPurifCtr)/100)) +// or 100*(1 + currentLevel - initialLvl) if (purifCtr - initialPurifCtr) < 100. 0 if status != PkmDeposited +class LIBPKMGC_DECL DaycareData : + public Base::DataStruct +{ +public: + DaycareData(size_t inSize, const u8* inData = NULL); + virtual ~DaycareData(void); + + virtual DaycareData* clone(void) const = 0; + virtual DaycareData* create(void) const = 0; + + virtual void swap(DaycareData& other); + virtual DaycareData& operator=(DaycareData const& other); + + virtual void save(void); + + DaycareStatus status; + u8 initialPkmLevel; + u32 initialPkmPurifCounter; + Pokemon* pkm; + +protected: + DaycareData(DaycareData const& other); + + virtual void deleteFields(void); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/Everything.h b/LibPkmGC/include/LibPkmGC/GC/Common/Everything.h new file mode 100644 index 0000000..2ac348f --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/Everything.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/GroupBattleRule.h b/LibPkmGC/include/LibPkmGC/GC/Common/GroupBattleRule.h new file mode 100644 index 0000000..678b26b --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/GroupBattleRule.h @@ -0,0 +1,52 @@ +#ifndef _LIBPKMGC_GC_GROUP_BATTLE_RULE_H +#define _LIBPKMGC_GC_GROUP_BATTLE_RULE_H + +#include + +namespace LibPkmGC { + +enum ItemRestrictionLevel { + AllItemsAllowed = 0, + NoItemAllowed = 1, + SomeItemsAllowed = 2 +}; + +LIBPKMGC_FWD_DECL_GC_CLS(GroupBattleRule) +namespace GC { + +class LIBPKMGC_DECL GroupBattleRule : + public Base::DataStruct +{ +public: + GroupBattleRule(size_t inSize, size_t nb_banned_items, const u8* inData = NULL); + + virtual ~GroupBattleRule(void); + + GroupBattleRule& operator=(GroupBattleRule const& other); + virtual GroupBattleRule* clone(void) const = 0; + virtual GroupBattleRule* create(void) const = 0; + + void swap(GroupBattleRule& other); + virtual void save(void); + + u16 minLevel, maxLevel; + u16 maxLevelSum; + ItemRestrictionLevel itemRestrictions; + bool noSpeciesClause, noItemClause, noSleepClause, noFreezeClause; + bool noSkillSwap, explosionClause, noRequiemClause, allowFixedDmgAbilities; + + s16 maxBattleDuration, orderTimeout; // resp. in min., sec. if negative, it's the opposite of the suggested value + + const size_t nbBannableItems; + bool* bannedItems; // 60 or 62 + +protected: + GroupBattleRule(GroupBattleRule const& other); + virtual void deleteFields(void); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/MailboxData.h b/LibPkmGC/include/LibPkmGC/GC/Common/MailboxData.h new file mode 100644 index 0000000..a679883 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/MailboxData.h @@ -0,0 +1,44 @@ +#ifndef _LIBPKMGC_GC_MAILBOX_DATA +#define _LIBPKMGC_GC_MAILBOX_DATA + +#include + +#define LIBPKMGC_MAILBOX_EMPTY_MAIL 255 + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(MailboxData) + +namespace GC { + +class LIBPKMGC_DECL MailboxData : + public Base::DataStruct +{ +public: + MailboxData(size_t inSize, u16 max_nb_mails, const u8* inData = NULL); + virtual ~MailboxData(); + + void swap(MailboxData& other); + + MailboxData& operator=(MailboxData const& other); + + virtual MailboxData* clone(void) const = 0; + virtual MailboxData* create(void) const = 0; + + bool isMailEmpty(size_t i); + + u16 nbMails; + u16* mails; + const u16 maxNbMails; + +protected: + MailboxData(MailboxData const& other); + + virtual void deleteFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/PCData.h b/LibPkmGC/include/LibPkmGC/GC/Common/PCData.h new file mode 100644 index 0000000..cb8efef --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/PCData.h @@ -0,0 +1,40 @@ +#ifndef _LIBPKMGC_GC_PC_DATA_H +#define _LIBPKMGC_GC_PC_DATA_H + +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(PCData) +namespace GC { + +class LIBPKMGC_DECL PCData : + public Base::DataStruct +{ +public: + PCData(size_t inSize, size_t nb_boxes, const u8* inData = NULL); + virtual ~PCData(void); + + virtual PCData* clone(void) const = 0; + virtual PCData* create(void) const = 0; + + void swap(PCData& other); + + PCData& operator=(PCData const& other); + + PokemonBox** boxes; + const size_t nbBoxes; + + Item items[235]; + +protected: + PCData(PCData const& other); + + virtual void deleteFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/PlayerData.h b/LibPkmGC/include/LibPkmGC/GC/Common/PlayerData.h new file mode 100644 index 0000000..aa7aac5 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/PlayerData.h @@ -0,0 +1,52 @@ +#ifndef _LIBPKMGC_GC_PLAYER_DATA_H +#define _LIBPKMGC_GC_PLAYER_DATA_H + +#include +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(PlayerData) + +namespace GC { + +class LIBPKMGC_DECL PlayerData : + public Base::DataStruct +{ +public: + PlayerData(size_t inSize, const u8* inData = NULL); + PlayerData& operator=(PlayerData const& other); + + virtual PlayerData* clone(void) const = 0; + virtual PlayerData* create(void) const = 0; + + virtual ~PlayerData(void); + + void swap(PlayerData& other); + + void swapPokemon(size_t n, size_t m); + virtual void save(void); + + + PokemonString* trainerName; + u16 SID, TID; + + Pokemon* party[6]; + + BagData* bag; + + Gender trainerGender; + u32 money; + u32 pkCoupons; + +protected: + PlayerData(PlayerData const& other); + + virtual void deleteFields(void); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/Pokemon.h b/LibPkmGC/include/LibPkmGC/GC/Common/Pokemon.h new file mode 100644 index 0000000..0582f8c --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/Pokemon.h @@ -0,0 +1,32 @@ +#ifndef _LIBPKMGC_GC_POKEMON_H +#define _LIBPKMGC_GC_POKEMON_H +#include +#include + +namespace LibPkmGC { +namespace GC { +class LIBPKMGC_DECL Pokemon : + public Base::Pokemon { +public: + Pokemon(size_t inSize, const u8* inData = NULL); + virtual ~Pokemon(void); + virtual Pokemon* clone(void) const = 0; + virtual Pokemon* create(void) const = 0; + + virtual void swap(Pokemon& other); + virtual Pokemon& operator=(Pokemon const& other); + virtual bool hasSpecialAbility(void) const = 0; + virtual void setSpecialAbilityStatus(bool status) = 0; + virtual PokemonAbilityIndex getAbility(void) const; + u16 shadowPkmID; + + virtual void swap(Base::Pokemon& other); + virtual Pokemon& operator=(Base::Pokemon const& other); +protected: + Pokemon(Pokemon const& other); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/PokemonBox.h b/LibPkmGC/include/LibPkmGC/GC/Common/PokemonBox.h new file mode 100644 index 0000000..77588d3 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/PokemonBox.h @@ -0,0 +1,34 @@ +#ifndef _LIBPKMGC_GC_POKEMON_BOX_H +#define _LIBPKMGC_GC_POKEMON_BOX_H + +#include +#include + +namespace LibPkmGC { +namespace GC { + +/* + 0x00: PokemonString name (2*(8+1) bytes) + 0x12: u16 ?? + 0x14 -- end: Pokemon pkm[30] +*/ + +class LIBPKMGC_DECL PokemonBox : public Base::PokemonBox { +public: + PokemonBox(size_t inSize, const u8* inData = NULL); + virtual ~PokemonBox(void); + + virtual PokemonBox* clone(void) const = 0; + virtual PokemonBox* create(void) const = 0; + + virtual void save(void); + +protected: + PokemonBox(PokemonBox const& other); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/PokemonString.h b/LibPkmGC/include/LibPkmGC/GC/Common/PokemonString.h new file mode 100644 index 0000000..e46858b --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/PokemonString.h @@ -0,0 +1,40 @@ +#ifndef _LIBPKMGC_GC_POKEMON_STRING_H +#define _LIBPKMGC_GC_POKEMON_STRING_H + +#include + +namespace LibPkmGC { +namespace GC { + +class LIBPKMGC_DECL PokemonString : public Base::PokemonString { +public: + PokemonString(const char* str = NULL); + PokemonString(u8* data, size_t nb); + PokemonString(PokemonString const& other); + ~PokemonString(void); + + PokemonString* clone(void) const; + PokemonString* create(void) const; + + PokemonString& operator=(PokemonString const& other); + PokemonString& operator=(Base::PokemonString const& other); + + void fromUTF8(const char* str = NULL); + const char* toUTF8(void) const; + + size_t size(void) const; + void load(u8* data, size_t nb); + void save(u8* data, size_t nb) const; + +private: + u8* _data; + size_t dataSz; + size_t dataCapacity; + + void resizeData(void); +}; + +} +} + +#endif diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoData.h b/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoData.h new file mode 100644 index 0000000..3d80c45 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoData.h @@ -0,0 +1,59 @@ +#ifndef _LIBPKMGC_GC_STRATEGY_MEMO_DATA_H +#define _LIBPKMGC_GC_STRATEGY_MEMO_DATA_H + +#include +#include + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(StrategyMemoData) + +namespace GC { + +/* + For both XD and Colosseum: + 0x00: u32 nbEntries, max. 500 + 0x04: StrategyMemoEntry entries[500]; +*/ + +class LIBPKMGC_DECL StrategyMemoData : + public Base::DataStruct +{ +public: + StrategyMemoData(size_t inSize, const u8* inData = NULL); + + virtual bool isXD(void) const = 0; + virtual ~StrategyMemoData(void); + + virtual StrategyMemoData* clone(void) const = 0; + virtual StrategyMemoData* create(void) const = 0; + + void swap(StrategyMemoData& other); + StrategyMemoData& operator=(StrategyMemoData const& other); + + virtual void save(void); + + virtual bool registerSpecies(PokemonSpeciesIndex index, u32 PID, u16 SID = 0, u16 TID = 0); + virtual bool registerSpecies(Pokemon* pkm); + void deleteEntry(size_t index); + + size_t recount(void) const; + + void sortedBySpeciesIndex(StrategyMemoEntry* dst[0x19b]); // only entries containing a valid Gen III species index are sorted + virtual void fixInvalidEntries(void); + + u16 nbEntries; + StrategyMemoEntry* entries[500]; + +protected: + StrategyMemoData(StrategyMemoData const& other); + + virtual void deleteFields(void); + virtual void loadFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoEntry.h b/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoEntry.h new file mode 100644 index 0000000..2649fd5 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/Common/StrategyMemoEntry.h @@ -0,0 +1,55 @@ +#ifndef _LIBPKMGC_GC_STRATEGY_MEMO_ENTRY_H +#define _LIBPKMGC_GC_STRATEGY_MEMO_ENTRY_H + +#include +#include + + +namespace LibPkmGC { + +LIBPKMGC_FWD_DECL_GC_CLS(StrategyMemoEntry) + +namespace GC { + +/* + For both Colosseum and XD: + 0x00: u16 pokemonIndex | flag (Colosseum: 0 : pokémon fully registered; 0x8000 : registered as seen; XD : 0x8000 if registered) + 0x04: u16 firstSID + 0x06: u16 firstTID + 0x08: u32 firstPID +*/ + +class LIBPKMGC_DECL StrategyMemoEntry : + public Base::DataStruct +{ +public: + StrategyMemoEntry(const u8* inData = NULL); + virtual ~StrategyMemoEntry(void); + virtual bool isXD(void) const = 0; + virtual void save(void); + + virtual StrategyMemoEntry* clone(void) const = 0; + virtual StrategyMemoEntry* create(void) const = 0; + + void swap(StrategyMemoEntry& other); + + bool isEmpty(void) const; + + virtual bool isInfoPartial(void) const = 0; + virtual void setInfoCompleteness(bool partial) = 0; + + //PokemonSpeciesStatus status; // discarded in Pokémon XD, where full information is automatically obtained + u16 flags; + PokemonSpeciesIndex species; + u16 firstSID, firstTID; + u32 firstPID; + +protected: + virtual void deleteFields(void); + virtual void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/SaveEditing/Save.h b/LibPkmGC/include/LibPkmGC/GC/SaveEditing/Save.h new file mode 100644 index 0000000..e202e6c --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/SaveEditing/Save.h @@ -0,0 +1,60 @@ +#ifndef _LIBPKMGC_GC_SAVE_EDITING_SAVE_H +#define _LIBPKMGC_GC_SAVE_EDITING_SAVE_H + +#include + +namespace LibPkmGC { + +namespace XD { namespace SaveEditing { class Save; } } +namespace Colosseum { namespace SaveEditing { class Save; } } + +namespace GC { +namespace SaveEditing { + +/* +For both Colosseum and XD: + 0x0000 -- 0x6000: banner data + 0x6000 -- end: SaveSlot saveSlots[3 (Colo.) or 2 (XD)] +*/ + +class LIBPKMGC_DECL Save : + public Base::DataStruct +{ +public: + Save(size_t inSize, size_t nb_slots, const u8* inData = NULL, bool hasGCIData_ = false); + + virtual Save* clone(void) const = 0; + virtual Save* create(void) const = 0; + + void swap(Save& other); + Save& operator=(Save const& other); + + virtual ~Save(void); + + virtual void reload(const u8* inData = NULL, u32 flags = 0); + + void saveEncrypted(u8* outBuf, bool exportGCIData = true); + SaveSlot* getMostRecentSlot(size_t index = 0) const; + SaveSlot* getMostRecentValidSlot(size_t index = 0, size_t *outIndex = NULL); + + SaveSlot** saveSlots; + + const size_t nbSlots; + + bool hasGCIData; + u8 GCIData[0x40]; + +protected: + Save(Save const& other); + + bool _is_decrypted; + virtual void loadData(u32 flags = 0); + virtual void deleteFields(void); + +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/GC/SaveEditing/SaveSlot.h b/LibPkmGC/include/LibPkmGC/GC/SaveEditing/SaveSlot.h new file mode 100644 index 0000000..ea8b726 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/GC/SaveEditing/SaveSlot.h @@ -0,0 +1,78 @@ +#ifndef _LIBPKMGC_GC_SAVE_EDITING_SAVE_SLOT_H +#define _LIBPKMGC_GC_SAVE_EDITING_SAVE_SLOT_H + +#include +#include + +namespace LibPkmGC { + +enum SaveMagic { + ColosseumMagic = 0x01010000, + XDMagic = 0x01010100 +}; + +namespace XD { namespace SaveEditing { class SaveSlot; } } +namespace Colosseum { namespace SaveEditing { class SaveSlot; } } + +namespace GC { +namespace SaveEditing { + + +class LIBPKMGC_DECL SaveSlot : public Base::DataStruct +{ +public: + + SaveSlot(size_t inSize, size_t nb_random_bytes, const u8* inData = NULL); + SaveSlot(const SaveSlot& other); + virtual ~SaveSlot(void); + + + void swap(SaveSlot& other); + + SaveSlot& operator=(SaveSlot const& other); + + virtual SaveSlot* clone(void) const = 0; + virtual SaveSlot* create(void) const = 0; + + virtual void reload(const u8* inData = NULL, u32 flags = 0); + + virtual bool checkChecksum(bool fix = false) = 0; + virtual bool checkHeaderChecksum(bool fix = false) = 0; + + virtual std::pair checkBothChecksums(bool fixGlobalChecksum = false, bool fixHeaderChecksum = false) = 0; + + virtual bool isCorrupt(void) = 0; + virtual void saveEncrypted(u8* outBuf) = 0; + + + SaveMagic magic; // 0x00 -- 0x04 (0x03 actually) + s32 headerChecksum; // definition and location vary across Colosseum and XD + + s32 saveCount;//, totalSaveCount; + + /* A bit inconsistent across versions */ + u32 memcardUID[2]; // u64. memcard[0:8] xor memcard[8:16] xor memcard[16:24] iirc + VersionInfo version; + LanguageIndex titleScreenLanguage; + bool noRumble; + + const size_t nbRandomBytes; + u8* randomBytes; + + PlayerData* player; + PCData* PC; + MailboxData* mailbox; + DaycareData* daycare; + StrategyMemoData* strategyMemo; + BattleModeData* battleMode; + +protected: + virtual void deleteFields(void); + +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/BagData.h b/LibPkmGC/include/LibPkmGC/XD/Common/BagData.h new file mode 100644 index 0000000..d06ac0d --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/BagData.h @@ -0,0 +1,37 @@ +#ifndef _LIBPKMGC_XD_BAG_DATA_H +#define _LIBPKMGC_XD_BAG_DATA_H + +#include + +namespace LibPkmGC { +namespace XD { + +class LIBPKMGC_DECL BagData : + public GC::BagData +{ +public: + static const size_t size = 0x418; + BagData(void); + BagData(const u8* inData); + BagData(BagData const& other); + ~BagData(); + + void swap(BagData& other); + + BagData* clone(void) const; + BagData* create(void) const; + + void save(void); + + Item battleCDs[60]; +protected: + void loadFields(void); +private: + BagData(Colosseum::BagData const&); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/BattleModeData.h b/LibPkmGC/include/LibPkmGC/XD/Common/BattleModeData.h new file mode 100644 index 0000000..e62641c --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/BattleModeData.h @@ -0,0 +1,43 @@ +#ifndef _LIBPKMGC_XD_BATTLE_MODE_DATA_H +#define _LIBPKMGC_XD_BATTLE_MODE_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00: XDBattleRule rules[6] + 0x360: u8 groupBattleModeUsed + 0x361--0x363: unused/trash data +*/ +class LIBPKMGC_DECL BattleModeData : + public GC::BattleModeData +{ +public: + static const size_t size = 0x364; + BattleModeData(void); + BattleModeData(BattleModeData const&); + BattleModeData(const u8* inData); + ~BattleModeData(); + + void swap(BattleModeData& other); + BattleModeData* clone(void) const; + BattleModeData* create(void) const; + + void save(void); + + + bool battleModeUsed; + +private: + void loadFields(void); + BattleModeData(Colosseum::BattleModeData const& other); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/DaycareData.h b/LibPkmGC/include/LibPkmGC/XD/Common/DaycareData.h new file mode 100644 index 0000000..b1b400d --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/DaycareData.h @@ -0,0 +1,31 @@ +#ifndef _LIBPKMGC_XD_DAYCARE_DATA_H +#define _LIBPKMGC_XD_DAYCARE_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +class LIBPKMGC_DECL DaycareData : + public GC::DaycareData +{ +public: + static const size_t size = 0xcc; + DaycareData(void); + DaycareData(DaycareData const& other); + DaycareData(const u8* inData); + ~DaycareData(void); + + DaycareData* clone(void) const; + DaycareData* create(void) const; + + DaycareData(Colosseum::DaycareData const& other); +private: + void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/Everything.h b/LibPkmGC/include/LibPkmGC/XD/Common/Everything.h new file mode 100644 index 0000000..2132657 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/Everything.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/GroupBattleRule.h b/LibPkmGC/include/LibPkmGC/XD/Common/GroupBattleRule.h new file mode 100644 index 0000000..547b126 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/GroupBattleRule.h @@ -0,0 +1,46 @@ +#ifndef _LIBPKMGC_XD_GROUP_BATTLE_RULE_H +#define _LIBPKMGC_XD_GROUP_BATTLE_RULE_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +class LIBPKMGC_DECL GroupBattleRule : + public GC::GroupBattleRule +{ +public: + static const size_t size = 0x90; + GroupBattleRule(const u8* inData); + GroupBattleRule(void); + GroupBattleRule(GroupBattleRule const& other); + + ~GroupBattleRule(); + + void swap(GroupBattleRule& other); + GroupBattleRule* clone(void) const; + GroupBattleRule* create(void) const; + + void save(void); + + + bool revealDeoxysForm; + GC::PokemonString* customName; // 25 + 1 + + u16 nbPkm; + bool isBattleOpen; // unresticted number of Pkm., max. 6. +protected: + void loadFields(void); + void deleteFields(void); + +private: + GroupBattleRule(Colosseum::GroupBattleRule const& other); + + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/MailboxData.h b/LibPkmGC/include/LibPkmGC/XD/Common/MailboxData.h new file mode 100644 index 0000000..4aa8169 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/MailboxData.h @@ -0,0 +1,39 @@ +#ifndef _LIBPKMGC_XD_MAILBOX_DATA +#define _LIBPKMGC_XD_MAILBOX_DATA + +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00: u16 nbMails + 0x02: u16 mails[32] = mailID or 255 if empty + 0x42 -- end (0x49): unused (?) +*/ + +class LIBPKMGC_DECL MailboxData : + public GC::MailboxData +{ +public: + static const size_t size = 0x4a; + MailboxData(void); + MailboxData(MailboxData const& other); + MailboxData(const u8* inData); + ~MailboxData(void); + + MailboxData* clone(void) const; + MailboxData* create(void) const; + + void save(void); +protected: + void loadFields(void); +private: + MailboxData(Colosseum::MailboxData const&); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/PCData.h b/LibPkmGC/include/LibPkmGC/XD/Common/PCData.h new file mode 100644 index 0000000..5aa5014 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/PCData.h @@ -0,0 +1,39 @@ +#ifndef _LIBPKMGC_XD_PC_DATA_H +#define _LIBPKMGC_XD_PC_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00: PokemonBox boxes[8] + 0xb860: items[235] + 0xbc0c -- end(0xbc50): unknown/unused ? +*/ + +class LIBPKMGC_DECL PCData : + public GC::PCData +{ +public: + static const size_t size = 0xbc50; + PCData(void); + PCData(PCData const& other); + PCData(const u8* inData); + ~PCData(void); + + PCData* clone(void) const; + PCData* create(void) const; + + void save(void); +protected: + void loadFields(void); +private: + PCData(Colosseum::PCData const&); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/PlayerData.h b/LibPkmGC/include/LibPkmGC/XD/Common/PlayerData.h new file mode 100644 index 0000000..46d835f --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/PlayerData.h @@ -0,0 +1,49 @@ +#ifndef _LIBPKMGC_XD_PLAYER_DATA_H +#define _LIBPKMGC_XD_PLAYER_DATA_H + +#include +#include +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00 -- 0x2b: trainer name (10+1 wide characters) + copy + 0x2c: u16 SID + 0x2e: u16 TID + 0x30: Pokémon Party (6*0xc4) + + 0x4c8: bag + + 0x8e0: u8 trainerGender + 0x8e4: u32 money + 0x8e8: u32 pkCoupons + copy +*/ + +class LIBPKMGC_DECL PlayerData : + public GC::PlayerData +{ +public: + static const size_t size = 0x978; + PlayerData(void); + PlayerData(PlayerData const& other); + PlayerData(const u8* inData); + + + ~PlayerData(void); + PlayerData* clone(void) const; + PlayerData* create(void) const; + + //void swap(PlayerData& other); + void save(void); +protected: + void loadFields(void); +private: + PlayerData(Colosseum::PlayerData const&); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/Pokemon.h b/LibPkmGC/include/LibPkmGC/XD/Common/Pokemon.h new file mode 100644 index 0000000..e9da663 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/Pokemon.h @@ -0,0 +1,93 @@ +#ifndef _LIBPKMGC_XD_POKEMON_H +#define _LIBPKMGC_XD_POKEMON_H + +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00: u16 species + 0x02: u16 itemHeld + 0x04: u16 currentHP + 0x06: u16 happiness + 0x08: u16 locationCaught + // 0x09 -- 0xd :: ?? + 0x0e: u8 levelMet + 0x0f: u8 ballCaughtWith + 0x10: u8 OTGender (00 male 01 female 02 genderless=none) + 0x11: u8 currentLevel + 0x12: u8 Contest Luster + 0x13: u8 pkrsStatus + 0x14: u8 marks (bitfield) + 0x15: 0xff ? + 0x16: u16 status (3 psn, 4 psn (toxic ?), 5 par, 6 brn, 7 frzn, 8 slp) + 0x17: ? + 0x18 -- 0x1b : ? (0x50) + 0x1d: u8 pkmFlags + bit 7: egg flag + bit 6: special (second) ability flag. Pokémon XD's catchable Pkms have a 50% chance to have their special ability + bit 5: invalidity flag. MUST **NOT** BE SET for the Pokémon to be considered as valid ("not empty") + bit 4: "not traded" flag ?? + bit 2: "caught" flag ?? + 0x1e 0x1f : ?? + 0x20: u32 experience + 0x24: u16 SID + 0x26: u16 TID + 0x28: u32 PID + 0x2c -- 0x32 : ?? (0 on shadow pkm) + 0x33: u8 encounterType + 0x34 -- 0x37 : Version info (actual region, original region, original language) + 0x38: GC::PokemonString OTName (10+1 chars = 22 bytes) + 0x4e: GC::PokemonString name (10+1 chars) + 0x64: pkm name backup + 0x7a -- 0x7b: ?? + 0x7c: u16 specialRibbons + 0x7e -- 0x7f: ?? + 0x80: moves[4]{u16 moveID, u8 basePP (?), u8 nbPPUps} + 0x90: u16 stats[6] + 0x9c: u16 EVs[6] + 0xa8: u8 IVs[6] + 0xae: u8 contestStats[6] (0 to 255) + 0xb3: u8 contestAchievements[5] + 0xb7: unused + 0xb8 : u16 ?? + 0xba: shadow pkm id + 0xbc -- 0xbf : ??? ???? + 0xc0 -- 0xc1 : unused ? + 0xc2: party identify (lead = 00, 01 otherwise) +*/ + +class LIBPKMGC_DECL Pokemon : public GC::Pokemon { +public: + static const size_t size = 0xc4; + Pokemon(void); + Pokemon(const u8* inData); + Pokemon(Pokemon const& other); + ~Pokemon(void); + Pokemon* clone(void) const; + Pokemon* create(void) const; + + void save(void); + + void swap(Pokemon& other); + Pokemon& operator=(Pokemon const& other); + + bool hasSpecialAbility(void) const; + void setSpecialAbilityStatus(bool status); + + u8 pkmFlags; + + bool isEmptyOrInvalid(void) const; + Pokemon(Colosseum::Pokemon const& other); + Pokemon& operator=(GC::Pokemon const& other); + void swap(GC::Pokemon & other); +private: + void loadFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/PokemonBox.h b/LibPkmGC/include/LibPkmGC/XD/Common/PokemonBox.h new file mode 100644 index 0000000..7e6f48c --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/PokemonBox.h @@ -0,0 +1,33 @@ +#ifndef _LIBPKMGC_XD_POKEMON_BOX_H +#define _LIBPKMGC_XD_POKEMON_BOX_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +class LIBPKMGC_DECL PokemonBox : + public GC::PokemonBox +{ +public: + static const size_t size = 0x170c; + PokemonBox(void); + PokemonBox(PokemonBox const& other); + PokemonBox(const u8* inData); + ~PokemonBox(void); + + PokemonBox* clone(void) const; + PokemonBox* create(void) const; + + void save(void); + + PokemonBox(Colosseum::PokemonBox const& other); +protected: + void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/PurificationChamber.h b/LibPkmGC/include/LibPkmGC/XD/Common/PurificationChamber.h new file mode 100644 index 0000000..1e683b9 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/PurificationChamber.h @@ -0,0 +1,47 @@ +#ifndef _LIBPKMGC_XD_PURIFICATION_CHAMBER_H +#define _LIBPKMGC_XD_PURIFICATION_CHAMBER_H + +#include +namespace LibPkmGC { +namespace XD { + +/* + 0x00: XDPokemon normalPkm[4] + 0x310: XDPokemon shadowPkm + 0x3d4: u8 ?? + 0x3d5 -- end: padding/trash bytes +*/ + +class LIBPKMGC_DECL PurificationChamber : + public Base::DataStruct +{ +public: + static const size_t size = 0x3d8; + PurificationChamber(void); + PurificationChamber(const u8* inData); + + ~PurificationChamber(void); + + PurificationChamber(PurificationChamber const& other); + PurificationChamber& operator=(PurificationChamber const& other); + void swap(PurificationChamber& other); + + PurificationChamber* clone(void) const; + PurificationChamber* create(void) const; + + void save(void); + + Pokemon* normalPkm[4]; + Pokemon* shadowPkm; + +private: + void deleteFields(void); + void loadFields(void); + + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/PurifierData.h b/LibPkmGC/include/LibPkmGC/XD/Common/PurifierData.h new file mode 100644 index 0000000..9043e14 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/PurifierData.h @@ -0,0 +1,43 @@ +#ifndef _LIBPKMGC_PURIFIER_DATA_H +#define _LIBPKMGC_PURIFIER_DATA_H + +#include + +namespace LibPkmGC { +namespace XD { + +/* + 0x00--end(0x2298): PurificationChamber chambers[9] +*/ + +class LIBPKMGC_DECL PurifierData : + public Base::DataStruct +{ +public: + static const size_t size = 0x2298; + PurifierData(void); + PurifierData(const u8* inData); + + ~PurifierData(void); + + PurifierData(PurifierData const& other); + PurifierData& operator=(PurifierData const& other); + void swap(PurifierData& other); + + PurifierData* clone(void) const; + PurifierData* create(void) const; + + void save(void); + + PurificationChamber* chambers[9]; + +private: + void deleteFields(void); + void loadFields(void); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoData.h b/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoData.h new file mode 100644 index 0000000..0839c4f --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoData.h @@ -0,0 +1,37 @@ +#ifndef _LIBPKMGC_XD_STRATEGY_MEMO_DATA_H +#define _LIBPKMGC_XD_STRATEGY_MEMO_DATA_H + +#include +#include + +namespace LibPkmGC { +namespace XD { + +class LIBPKMGC_DECL StrategyMemoData : + public GC::StrategyMemoData +{ +public: + static const size_t size = 0x1774; + ~StrategyMemoData(void); + + bool isXD(void) const; + StrategyMemoData(void); + StrategyMemoData(const u8* inData); + StrategyMemoData(StrategyMemoData const& other); + + + StrategyMemoData* clone(void) const; + StrategyMemoData* create(void) const; + + void save(void); + + StrategyMemoData(Colosseum::StrategyMemoData const& other); + +protected: + void loadFields(void); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoEntry.h b/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoEntry.h new file mode 100644 index 0000000..1022fc1 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/Common/StrategyMemoEntry.h @@ -0,0 +1,30 @@ +#ifndef _LIBPKMGC_XD_STRATEGY_MEMO_ENTRY_H +#define _LIBPKMGC_XD_STRATEGY_MEMO_ENTRY_H + +#include + +namespace LibPkmGC { +namespace XD { + + +class LIBPKMGC_DECL StrategyMemoEntry : + public GC::StrategyMemoEntry +{ +public: + static const size_t size = 12; + ~StrategyMemoEntry(void); + StrategyMemoEntry(void); + StrategyMemoEntry(const u8* inData); + + bool isXD(void) const; + StrategyMemoEntry* clone(void) const; + StrategyMemoEntry* create(void) const; + + bool isInfoPartial(void) const; + void setInfoCompleteness(bool partial); +}; + +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/SaveEditing/Save.h b/LibPkmGC/include/LibPkmGC/XD/SaveEditing/Save.h new file mode 100644 index 0000000..8af1a60 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/SaveEditing/Save.h @@ -0,0 +1,39 @@ +#ifndef _LIBPKMGC_XD_SAVE_EDITING_SAVE_H +#define _LIBPKMGC_XD_SAVE_EDITING_SAVE_H + +#include +#include + +namespace LibPkmGC { +namespace XD { +namespace SaveEditing { + +class LIBPKMGC_DECL Save : + public GC::SaveEditing::Save +{ +public: + static const size_t size = 0x56000; + Save(void); + Save(Save const& other); + Save(const u8* inData, bool hasGCIData_ = false, bool isDecrypted = false); + //~Save(void); + + Save* clone(void) const; + Save* create(void) const; + + void save(void); + + void saveUnshuffled(void); + +protected: + void loadFields(void); + +private: + Save(Colosseum::SaveEditing::Save const&); +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/include/LibPkmGC/XD/SaveEditing/SaveSlot.h b/LibPkmGC/include/LibPkmGC/XD/SaveEditing/SaveSlot.h new file mode 100644 index 0000000..38e1a02 --- /dev/null +++ b/LibPkmGC/include/LibPkmGC/XD/SaveEditing/SaveSlot.h @@ -0,0 +1,109 @@ +#ifndef _LIBPKMGC_XD_SAVE_EDITING_SAVE_SLOT_H +#define _LIBPKMGC_XD_SAVE_EDITING_SAVE_SLOT_H + +#include +#include + +namespace LibPkmGC { +namespace XD { +namespace SaveEditing { + +/* + 0x00: u32 magic + 0x04: s32 saveCount + 0x08: u16 encryptionKeys[4] (random generated) + + 0x10: **ENCRYPTED DATA** + 0x10: u32 checksum[4] (stored in a particular way, see below) + 0x20: u16 substructureSizes[16] + 0x40: u32 substructureOffsets[16] (stored in a particular way, see below) + 0x80: u16 substructure8SubsubstructureSizes[5] (??) + + 0xa8: substructures + (end)-40: **END OF ENCRYPTED DATA** + (end)-40: u8 randomBytes[40]; +*/ + +/* + Substructures, in order : + - [0] metadata/game config, size=0x88 (for compat. w/ colosseum it is directly handled within GC::SaveSlot) + - [1] party & player data + - [2] PC Storage + - [3] Mailbox + - [4] Daycare + - [5] Strategy memo + - [6] Battle mode + - [7] Shadow Pokémon data (in Colosseum, this is apparently a PID list; the full shadow data SEEMS to be included in the Pokémon's data) + - ? + - ? + - map data / script state + - Purifier +*/ + + +/* + Metadata substructure (off 0 (total 0xa8)) : + 0x00: VersionInfo version (game, region, language) + 0x04--0x07: u32 ? + 0x08: u64 memcardUID (see GCSaveSlot.h) + + 0x29: u8 noRumble + 0x2a: u16 titleScreenLanguage + 0x38: s32 headerChecksum +*/ + +class LIBPKMGC_DECL SaveSlot : + public GC::SaveEditing::SaveSlot +{ +public: + static const size_t size = 0x28000; + SaveSlot(void); + SaveSlot(const u8* inData, bool isDecrypted = false); + SaveSlot(SaveSlot const& other); + + ~SaveSlot(void); + + SaveSlot* clone(void) const; + SaveSlot* create(void) const; + + void swap(SaveSlot& other); + SaveSlot& operator=(SaveSlot const& other); + + void save(void); + + bool checkChecksum(bool fix = false); + bool checkHeaderChecksum(bool fix = false); + std::pair checkBothChecksums(bool fixGlobalChecksum = false, bool fixHeaderChecksum = false); + bool isCorrupt(void); + + void reorderSubstructures(void); + void saveUnshuffled(void); + + void saveEncrypted(u8* outBuf); + + PurifierData* purifier; + + u32 checksum[4]; + + u16 encryptionKeys[4]; + u32 substructureSizes[16]; // there are actually 12 substructures + u32 substructureOffsets[16]; // there are actually 12 substructures + + +protected: + void loadData(u32 flags = 0); + void deleteFields(void); + void loadFields(void); + +private: + Base::UnimplementedStruct* unhandledSubstructures[16]; // by definition don't pay attention to that + void _deleteFields_extension(void); + bool _other_corruption_flags; + SaveSlot(Colosseum::SaveEditing::SaveSlot const&); +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Base/DataStruct.cpp b/LibPkmGC/src/LibPkmGC/Base/DataStruct.cpp new file mode 100644 index 0000000..56fd5bd --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Base/DataStruct.cpp @@ -0,0 +1,80 @@ +#include +namespace LibPkmGC { +namespace Base { +//size_t allocatedBytesInUsage = 0; +DataStruct::DataStruct(void) : data(NULL), size(0), fixedSize(0) {} +void DataStruct::copyData(const u8* inData) { + if (inData == NULL) { + data = NULL; + return; + } + delete[] data; + data = new u8[size]; + std::copy(inData, inData + size, data); +} + +void DataStruct::loadData(u32 flags) {}; + +void DataStruct::load(u32 flags) { + loadData(flags); + loadFields(); +} + +DataStruct::DataStruct(size_t inSize, const u8* inData, bool fixed) : size(inSize), data(NULL), fixedSize((fixed) ? inSize : 0) { +// allocatedBytesInUsage += inSize; + copyData(inData); +} + + +DataStruct::~DataStruct(void) { +// allocatedBytesInUsage -= size; + delete[] data; +} + +bool DataStruct::sizeIsFixed(void) const{ + return fixedSize != 0; +} + +void DataStruct::reload(const u8* inData, u32 flags) { + deleteFields(); + if (inData != NULL) std::copy(inData, inData + size, data); + load(flags); +} + +DataStruct::DataStruct(DataStruct const& other) : size(other.size), fixedSize(other.fixedSize) { + data = new u8[size]; + std::copy(other.data, other.data + size, data); +} + +void DataStruct::swap(DataStruct& other) { + if ((!sizeIsFixed() || (sizeIsFixed() && (size == other.size))) && (this != &other)) + SW(data); +} + +DataStruct& DataStruct::operator=(const DataStruct& other) { + if (this != &other) { + if (sizeIsFixed()) { + if (size == other.size) CP_ARRAY(data, size); + else std::fill(data, data + size, 0); + } + else { + CP(size); + delete[] data; + data = new u8[size]; + std::copy(other.data, other.data + size, data); + } + } + return *this; +} + +void DataStruct::initWithEmptyData(u32 flags) { + if (data != NULL) delete[] data; + data = new u8[size]; + std::fill(data, data + size, 0); + loadFields(); +} + +size_t DataStruct::getSize(void) const { return size; } + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Base/Pokemon.cpp b/LibPkmGC/src/LibPkmGC/Base/Pokemon.cpp new file mode 100644 index 0000000..ffd9e00 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Base/Pokemon.cpp @@ -0,0 +1,220 @@ +#include + +namespace LibPkmGC { + + +namespace Base { + +u16 Pokemon::calculateStat(size_t statIndex, PokemonSpeciesIndex species, PokemonNatureIndex natureIndex, u8 level, u8 IV, u8 EV){ + static const u16 n[3] = { 110, 100, 90 }; + + if ((statIndex == 0) && (species == Shedinja)) return 1; + if (statIndex >= 6) return 0; + + size_t i = statIndex; + u16 outStat; + + outStat = IV + (2 * getSpeciesData(species).baseStats[i]) + EV / 4; + + // We're applying bonuses now + if(i == 0) return ((outStat + 100) * level / 100) + 10; // HP + else return (outStat * level / 100 + 5) * n[(size_t)getNatureStatAffinity(natureIndex, i) ] / 100; + +} + +void Pokemon::calculateStats(PokemonSpeciesIndex species, PokemonNatureIndex natureIndex, u8 level, const u8 IVs[6], const u8 EVs[6], u16 outStats[6]) { + for (size_t i = 0; i < 6; ++i) + outStats[i] = calculateStat(i, species, natureIndex, level, IVs[i], EVs[i]); +} + +u8 Pokemon::calculateLevelFromExp(PokemonSpeciesIndex species, u32 experience) { + const u32* expTable = getSpeciesExpTable(species); + if (experience >= expTable[100]) return 100; + + u8 i = 0; + while (i < 100 && experience >= expTable[++i]); + return i-1; +} + +u32 Pokemon::calculateExpFromLevel(PokemonSpeciesIndex species, u8 level) { + const u32* expTable = getSpeciesExpTable(species); + if (level >= 100) return expTable[100]; + return expTable[level]; +} + +Pokemon::Pokemon(size_t inSize, const u8* inData) : DataStruct(inSize, inData) { +} + +Pokemon::~Pokemon(void) { + +} + + +u8 Pokemon::calculateLevelFromExp(void) const { + return calculateLevelFromExp(species, experience); +} + +void Pokemon::updateLevelFromExp(void) { partyData.level = calculateLevelFromExp(); } + +u32 Pokemon::calculateExpFromLevel(u8 lvl) const { + return calculateExpFromLevel(species, lvl); +} + +void Pokemon::updateExpFromLevel(u8 lvl) { experience = calculateExpFromLevel(lvl); } + +void Pokemon::calculateStats(u16 outStats[6]) const { + calculateStats(species, (PokemonNatureIndex)(PID % 25), calculateLevelFromExp(), IVs, EVs, outStats); +} + +void Pokemon::updateStats(void) { calculateStats(partyData.stats); } + +bool Pokemon::isShiny(u32 PID, u16 TID, u16 SID) { + return ((PID >> 16) ^ (PID & 0xffff) ^ SID ^ TID) < 8; +} + +PokemonNatureIndex Pokemon::getNature(u32 PID) { + return (PokemonNatureIndex)(PID % 25); +} + +Gender Pokemon::getGender(PokemonSpeciesIndex species, u32 PID) { + PokemonSpeciesGenderRatio r = getSpeciesData(species).genderRatio; + if (r == GenderlessOnly) return Genderless; + else if (r == MaleOnly) return Male; + else if (r == FemaleOnly) return Female; + else + return ((PID & 0xff) >= (u32)r) ? Male : Female; +} + +PokemonSpeciesIndex Pokemon::getWurmpleEvolution(u32 PID) { + return (((PID & 0xffff) % 10) < 5) ? Silcoon : Cascoon; +} + +char Pokemon::getUnownForm(u32 PID) { + char tbl[] = "ABCDEFGHIKLMNOPQRSTUVWXYZ?!"; + u32 n = (((PID >> 24) & 3) << 6) | (((PID >> 16) & 3) << 4) | (((PID >> 8) & 3) << 2) | (PID & 3); + return tbl[n % 28]; +} + +bool Pokemon::isShiny(void) const { + return isShiny(PID, TID, SID); +} + +PokemonNatureIndex Pokemon::getNature(void) const { + return getNature(PID); +} + +Gender Pokemon::getGender(void) const { + return getGender(species, PID); +} + +PokemonSpeciesIndex Pokemon::getWurmpleEvolution(void) const { + return getWurmpleEvolution(PID); +} + +char Pokemon::getUnownForm(void) const { + return getUnownForm(PID); +} + +void Pokemon::resetPartyData(void) { + updateStats(); + updateLevelFromExp(); + partyData.status = NoStatus; + partyData.currentHP = partyData.stats[0]; +} +Pokemon::Pokemon(Pokemon const & other) : Base::DataStruct(other.fixedSize, NULL, true){ + data = new u8[other.fixedSize]; + Pokemon::operator=(other); +} +void Pokemon::deleteFields(void){ +} +/* +void Pokemon::calculateSpindaSpotsPosition(std::pair[4]) const{ + u32 PID_2 = PID; +}*/ + +bool Pokemon::isEmptyOrInvalid(void) const { + return (species > 0x19e) || (species == 0) || !getSpeciesData(species).isValid || version.isIncomplete(); +} + +bool Pokemon::isSpecialAbilityDefined(void) const{ + return (getSpeciesData(species).possibleAbilities[1] != NoAbility); +} +void Pokemon::swap(Pokemon& other) { + DataStruct::swap(other); + SW(species); + SW(heldItem); + + SW(happiness); + SW(locationCaught); + SW(ballCaughtWith); + SW(levelMet); + SW(OTGender); + SW(OTName); + SW(name); + SW(contestLuster); + SW(pkrsStatus); + SW(markings); + + SW(experience); + SW(SID); + SW(TID); + SW(PID); + +// SW(encounterType); + SW(version); + + SW(usesPartyData); + SW(partyData); + + SW_ARRAY(specialRibbons, 12) + SW_ARRAY(moves, 4); + SW_ARRAY(EVs, 6); + SW_ARRAY(IVs, 6); + + SW_ARRAY(contestStats, 5); + SW_ARRAY(contestAchievements, 5); + +} + +Pokemon & Pokemon::operator=(Pokemon const & other){ + if (this != &other) { + Base::DataStruct::operator=(other); + CP(species); + CP(heldItem); + + CP(happiness); + CP(locationCaught); + CP(ballCaughtWith); + CP(levelMet); + CP(OTGender); + CL(OTName) + CL(name); + CP(contestLuster); + CP(pkrsStatus); + CP(markings); + + CP(experience); + CP(SID); + CP(TID); + CP(PID); + + // CP(encounterType); + CP(version); + + CP_ARRAY(specialRibbons, 12); + CP(usesPartyData); + CP(partyData); + + CP_ARRAY(moves, 4); + CP_ARRAY(EVs, 6); + CP_ARRAY(IVs, 6); + + CP_ARRAY(contestStats, 5); + CP_ARRAY(contestAchievements, 5); + } + return *this; +} + + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Base/PokemonBox.cpp b/LibPkmGC/src/LibPkmGC/Base/PokemonBox.cpp new file mode 100644 index 0000000..e1a1d41 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Base/PokemonBox.cpp @@ -0,0 +1,41 @@ +#include + +namespace LibPkmGC { +namespace Base { + +PokemonBox::PokemonBox(size_t inSize, const u8* inData) : DataStruct(inSize, inData) { + +} + +void PokemonBox::deleteFields(void) { + for (size_t i = 0; i < 30; ++i) + delete pkm[i]; +} + +PokemonBox::PokemonBox(PokemonBox const& other) : DataStruct(other) { + CL(name); + CL_ARRAY(pkm, 30); +} + +PokemonBox::~PokemonBox(void) { + PokemonBox::deleteFields(); +} + +void PokemonBox::swap(PokemonBox& other) { + DataStruct::swap(other); + SW(name); + for (size_t i = 0; i < 30; ++i) pkm[i]->swap(*other.pkm[i]); +} + +PokemonBox& PokemonBox::operator=(PokemonBox const& other) { + DataStruct::operator=(other); + if (this != &other) { + PokemonBox::deleteFields(); + for (size_t i = 0; i < 30; ++i) *pkm[i] = *(other.pkm[i]); + CL(name); + } + return *this; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Base/PokemonString.cpp b/LibPkmGC/src/LibPkmGC/Base/PokemonString.cpp new file mode 100644 index 0000000..96645f4 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Base/PokemonString.cpp @@ -0,0 +1,44 @@ +#include + +namespace LibPkmGC { +namespace Base { + + + +PokemonString::PokemonString(void) : hasChanged(true), _str(NULL), strSz(0), strCapacity(0) { +} + +PokemonString::~PokemonString(void) { +} + +PokemonString & PokemonString::operator=(PokemonString const & other) { + if (this != &other) { + hasChanged = other.hasChanged; + strSz = other.strSz; + resizeStr(); + std::copy(other._str, other._str + strSz, _str); + + } + return *this; +} + + +PokemonString::operator const char*(void) const { + return toUTF8(); +} + +PokemonString::PokemonString(PokemonString const & other) : hasChanged(other.hasChanged), strSz(other.strSz), strCapacity(0), _str(NULL) { + resizeStr(); + std::copy(other._str, other._str + strSz, _str); +} + +void PokemonString::resizeStr(void) const { + if (strCapacity < strSz) { + strCapacity = strSz; + delete[] _str; + _str = new char[strSz]; + } +} + +} +} diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/BagData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/BagData.cpp new file mode 100644 index 0000000..7973387 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/BagData.cpp @@ -0,0 +1,28 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +BagData::BagData(void) : GC::BagData(0x300, 20) { + initWithEmptyData(); +} + +BagData::BagData(const u8* inData) : GC::BagData(0x300, 20, inData) { + load(); +} + +BagData::BagData(BagData const& other) : GC::BagData(other){} + +BagData::~BagData(){ +} + +BagData* BagData::clone(void) const { + return new BagData(*this); +} + +BagData* BagData::create(void) const { + return new BagData; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/BattleModeData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/BattleModeData.cpp new file mode 100644 index 0000000..1d4b89f --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/BattleModeData.cpp @@ -0,0 +1,42 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +BattleModeData::BattleModeData(void) : GC::BattleModeData(0xcc2c) { + initWithEmptyData(); +} + +BattleModeData::BattleModeData(const u8* inData) : GC::BattleModeData(0xcc2c, inData) { + load(); +} + +BattleModeData::BattleModeData(BattleModeData const& other) : GC::BattleModeData(other) {} + + +BattleModeData::~BattleModeData() +{ +} + +BattleModeData* BattleModeData::clone(void) const +{ + return new BattleModeData(*this); +} + +BattleModeData* BattleModeData::create(void) const +{ + return new BattleModeData; +} + +void BattleModeData::loadFields(void) { + LD_SUBSTRUCTURE_ARRAY(GroupBattleRule, rules, 6, 0xc16c); + //LD_FIELD_B(u8, groupBattleModeUsed, 0x360); +} + +void BattleModeData::save(void) { + SV_SUBSTRUCTURE_ARRAY(GroupBattleRule, rules, 6, 0xc16c); + //SV_FIELD_B(u8, groupBattleModeUsed, 0x360); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/DaycareData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/DaycareData.cpp new file mode 100644 index 0000000..c7a1f4b --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/DaycareData.cpp @@ -0,0 +1,34 @@ +#include + + +namespace LibPkmGC { +namespace Colosseum { + +DaycareData::DaycareData(void) : GC::DaycareData(0x140) { + initWithEmptyData(); +} + +DaycareData::DaycareData(const u8* inData) : GC::DaycareData(0x140, inData) { + load(); +} + +DaycareData::DaycareData(DaycareData const& other) : GC::DaycareData(other) {} +DaycareData::~DaycareData(void) { +} + +void DaycareData::loadFields(void) { + GC::DaycareData::loadFields(); + status = (status == NotVisited) ? NoPkmDeposited : status; + pkm = new Pokemon(data + 8); +} + +DaycareData* DaycareData::clone(void) const { + return new DaycareData(*this); +} + +DaycareData* DaycareData::create(void) const { + return new DaycareData; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/GroupBattleRule.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/GroupBattleRule.cpp new file mode 100644 index 0000000..bde5ed8 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/GroupBattleRule.cpp @@ -0,0 +1,40 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +GroupBattleRule::GroupBattleRule(const u8* inData) : GC::GroupBattleRule(0x54, 60, inData) { + load(); +} + +GroupBattleRule::GroupBattleRule(void) : GC::GroupBattleRule(0x54, 60) { + initWithEmptyData(); +} + +GroupBattleRule::GroupBattleRule(GroupBattleRule const& other) : GC::GroupBattleRule(other) {} + +GroupBattleRule::~GroupBattleRule() +{ +} + + +GroupBattleRule* GroupBattleRule::clone(void) const { + return new GroupBattleRule(*this); +} + +GroupBattleRule* GroupBattleRule::create(void) const { + return new GroupBattleRule; +} + +void GroupBattleRule::loadFields(void) { + GC::GroupBattleRule::loadFields(); + LD_ARRAY_B(u8, bannedItems, 60, 24); +} + +void GroupBattleRule::save(void) { + GC::GroupBattleRule::save(); + SV_ARRAY_B(u8, bannedItems, 60, 24); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/MailboxData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/MailboxData.cpp new file mode 100644 index 0000000..b0386c3 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/MailboxData.cpp @@ -0,0 +1,40 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + + +MailboxData::MailboxData(void) : GC::MailboxData(0x448, 512) { + initWithEmptyData(); +} + +MailboxData::MailboxData(const u8* inData) : GC::MailboxData(0x448, 512, inData) { + load(); +} + +MailboxData::MailboxData(MailboxData const& other) : GC::MailboxData(other) {} + +MailboxData::~MailboxData() { +} + +MailboxData* MailboxData::clone(void) const { + return new MailboxData(*this); +} + +MailboxData* MailboxData::create(void) const { + return new MailboxData; +} + +void MailboxData::loadFields(void) { + mails = new u16[512]; + LD_ARRAY(u16, mails, 512, 0); + LD_FIELD(u16, nbMails, 0x400); +} + +void MailboxData::save(void) { + SV_ARRAY(u16, mails, 512, 0); + SV_FIELD(u16, nbMails, 0x400); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/PCData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PCData.cpp new file mode 100644 index 0000000..0abb306 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PCData.cpp @@ -0,0 +1,44 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +PCData::PCData(void) : GC::PCData(0x7198, 3) { + initWithEmptyData(); +} + +PCData::PCData(const u8* inData) : GC::PCData(0x7198, 3, inData) { + load(); +} + +PCData::PCData(PCData const& other) : GC::PCData(other) {} +PCData::~PCData(void) { +} + +PCData* PCData::clone(void) const { + return new PCData(*this); +} + +PCData* PCData::create(void) const { + return new PCData; +} + + +void PCData::loadFields(void) { + boxes = new GC::PokemonBox*[nbBoxes]; + + LD_SUBSTRUCTURE_ARRAY(PokemonBox, boxes, 3, 0); + + for (size_t i = 0; i < 235; ++i) + items[i].load(data + 0x6dec + 4*i); +} + +void PCData::save(void) { + SV_SUBSTRUCTURE_ARRAY(PokemonBox, boxes, 3, 0); + + for (size_t i = 0; i < 235; ++i) + items[i].save(data + 0x6dec + 4*i); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/PlayerData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PlayerData.cpp new file mode 100644 index 0000000..7236ff6 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PlayerData.cpp @@ -0,0 +1,53 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +PlayerData::PlayerData(void) : GC::PlayerData(0xb18) { + initWithEmptyData(); +} + +PlayerData::PlayerData(const u8* inData) : GC::PlayerData(0xb18, inData) { + load(); +} + +PlayerData::PlayerData(PlayerData const& other) : GC::PlayerData(other) {} + +PlayerData::~PlayerData(void){ +} + +PlayerData* PlayerData::clone(void) const { + return new PlayerData(*this); +} + +PlayerData* PlayerData::create(void) const { + return new PlayerData; +} + +void PlayerData::loadFields(void) { + GC::PlayerData::loadFields(); + + LD_FIELD_E(u8, trainerGender, 0xa80, Gender); + if (trainerGender > Female) trainerGender = Male; + + LD_FIELD(u32, money, 0xa84); + LD_FIELD(u32, pkCoupons, 0xa88); + + LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30); + LD_SUBSTRUCTURE(BagData, bag, 0x780); +} + +void PlayerData::save(void) { + GC::PlayerData::save(); + if (trainerGender > Female) trainerGender = Male; + SV_FIELD_E(u8, trainerGender, 0xa80, Gender); + SV_FIELD(u32, money, 0xa84); + SV_FIELD(u32, pkCoupons, 0xa88); + SV_FIELD(u32, pkCoupons, 0xa8c); + + SV_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30); + SV_SUBSTRUCTURE(BagData, bag, 0x780); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/Pokemon.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/Pokemon.cpp new file mode 100644 index 0000000..f9df3dd --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/Pokemon.cpp @@ -0,0 +1,152 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +Pokemon::Pokemon(const u8* inData) : GC::Pokemon(0x138, inData) { + load(); +} + +Pokemon::Pokemon(void) : GC::Pokemon(0x138) { initWithEmptyData(); } + +Pokemon::~Pokemon(void) { +} + +Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other), specialAbilityStatus(other.specialAbilityStatus){} + +Pokemon* Pokemon::clone(void) const { return new Pokemon(*this); } +Pokemon* Pokemon::create(void) const { return new Pokemon; } + +void Pokemon::swap(Pokemon& other) { + GC::Pokemon::swap(other); + SW(specialAbilityStatus); +} + +void Pokemon::loadFields(void) { + u8 marksTmp = 0; + + LD_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex); + LD_FIELD(u32, PID, 0x04); + version.load(data + 0x08); + + u16 locationCaught_tmp; + LD_FIELD(u16, locationCaught_tmp, 0x0c); + locationCaught = (u8)((locationCaught_tmp > 255) ? 255 : locationCaught_tmp); + + LD_FIELD(u8, levelMet, 0x0e); + LD_FIELD_E(u8, ballCaughtWith, 0x0f, ItemIndex); + LD_FIELD_E(u8, OTGender, 0x10, Gender); + LD_FIELD(u16, SID, 0x14); + LD_FIELD(u16, TID, 0x16); + OTName = new GC::PokemonString(data + 0x18, 10); + name = new GC::PokemonString(data + 0x2e, 10); + LD_FIELD(u32, experience, 0x5c); + + LD_FIELD(u8, partyData.level, 0x60); + if (partyData.level > 100) partyData.level = 100; + LD_FIELD_E(u16, partyData.status, 0x65, PokemonStatus); + partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status; + LD_FIELD_E(u16, heldItem, 0x88, ItemIndex); + + LD_FIELD(u16, partyData.currentHP, 0x8a); + LD_ARRAY(u16, partyData.stats, 6, 0x8c); + + u16 EVs_tmp[6]; // EVs are internally stored as u16 + LD_ARRAY(u16, EVs_tmp, 6, 0x98); + for (size_t i = 0; i < 6; ++i) EVs[i] = (u8)((EVs_tmp[i] > 255) ? 255 : EVs_tmp[i]); + + LD_ARRAY(u8, IVs, 6, 0xa4); + for (size_t i = 0; i < 6; ++i) IVs[i] = (IVs[i] > 31) ? 31 : IVs[i]; + + u16 happiness_tmp; + LD_FIELD(u16, happiness_tmp, 0xb0); + happiness = (happiness_tmp > 255) ? 255 : happiness_tmp; + + + LD_ARRAY(u8, contestStats, 5, 0xb2); + LD_ARRAY_E(u8, contestAchievements, 5, 0xb7, ContestAchievementLevel); + LD_FIELD(u8, contestLuster, 0xbc); + + LD_ARRAY_B(u8, specialRibbons, 12, 0xbd); + + LD_FIELD(u8, pkrsStatus, 0xca); + LD_FIELD_B(u8, specialAbilityStatus, 0xcc); + + LD_FIELD(u8, marksTmp, 0xcf); + + LD_FIELD(u16, shadowPkmID, 0xd8); + + + markings.load(marksTmp); + for (size_t i = 0; i < 4; ++i) + moves[i].load(data + 0x78 + 4 * i); +} + +void Pokemon::save(void) { + SV_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex); + SV_FIELD(u32, PID, 0x04); + version.save(data + 0x08); + SV_FIELD(u16, (u16) locationCaught, 0x0c); + SV_FIELD(u8, levelMet, 0x0e); + SV_FIELD_E(u8, ballCaughtWith, 0x0f, ItemIndex); + SV_FIELD_E(u8, OTGender, 0x10, Gender); + SV_FIELD(u16, SID, 0x14); + SV_FIELD(u16, TID, 0x16); + OTName->save(data + 0x18, 10); + name->save(data + 0x2e, 10); + name->save(data + 0x44, 10); + SV_FIELD(u32, experience, 0x5c); + + if (partyData.level > 100) partyData.level = 100; + SV_FIELD(u8, partyData.level, 0x60); + partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status; + SV_FIELD_E(u16, partyData.status, 0x65, PokemonStatus); + SV_FIELD_E(u16, heldItem, 0x88, ItemIndex); + + SV_FIELD(u16, partyData.currentHP, 0x8a); + SV_ARRAY(u16, partyData.stats, 6, 0x8c); + + u16 EVs_tmp[6]; for (size_t i = 0; i < 6; ++i) EVs_tmp[i] = (u16)EVs[i]; + SV_ARRAY(u16, EVs_tmp, 6, 0x98); + for (size_t i = 0; i < 6; ++i) IVs[i] = (IVs[i] > 31) ? 31 : IVs[i]; + SV_ARRAY(u8, IVs, 6, 0xa4); + + SV_FIELD(u16, (u16)happiness, 0xb0); + SV_ARRAY(u8, contestStats, 5, 0xb2); + SV_ARRAY_E(u8, contestAchievements, 5, 0xb7, ContestAchievementLevel); + SV_FIELD(u8, contestLuster, 0xbc); + + SV_ARRAY_B(u8, specialRibbons, 12, 0xbd); + + SV_FIELD(u8, pkrsStatus, 0xca); + SV_FIELD_B(u8, specialAbilityStatus, 0xcc); + + SV_FIELD(u8, markings.save(), 0xcf); + + SV_FIELD(u16, shadowPkmID, 0xd8); + + for (size_t i = 0; i < 4; ++i) + moves[i].save(data + 0x78 + 4 * i); + + +} + +Pokemon& Pokemon::operator=(Pokemon const& other) { + if (this != &other) { + GC::Pokemon::operator=(other); + CP(specialAbilityStatus); + } + return *this; +} + +LIBPKMGC_GC_GEN_COL_VTF(Pokemon) +bool Pokemon::hasSpecialAbility(void) const { + return isSpecialAbilityDefined() && specialAbilityStatus; +} + +void Pokemon::setSpecialAbilityStatus(bool status) { + specialAbilityStatus = isSpecialAbilityDefined() && status; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/PokemonBox.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PokemonBox.cpp new file mode 100644 index 0000000..ddf6dee --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/PokemonBox.cpp @@ -0,0 +1,43 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +PokemonBox::PokemonBox(void) : GC::PokemonBox(0x24a4) { + initWithEmptyData(); +} + +PokemonBox::PokemonBox(const u8* inData) : GC::PokemonBox(0x24a4, inData) { + load(); +} +PokemonBox::PokemonBox(PokemonBox const& other) : GC::PokemonBox(other) {} + + +PokemonBox::~PokemonBox(void) +{ +} + + + +PokemonBox* PokemonBox::clone(void) const { + return new PokemonBox(*this); +} + +PokemonBox* PokemonBox::create(void) const { + return new PokemonBox; +} + + + +void PokemonBox::loadFields(void) { + GC::PokemonBox::loadFields(); + LD_SUBSTRUCTURE_ARRAY(Pokemon, pkm, 30, 0x14); +} + +void PokemonBox::save(void) { + GC::PokemonBox::save(); + SV_SUBSTRUCTURE_ARRAY(Pokemon, pkm, 30, 0x14); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoData.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoData.cpp new file mode 100644 index 0000000..1d485b8 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoData.cpp @@ -0,0 +1,46 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +StrategyMemoData::StrategyMemoData(void) : GC::StrategyMemoData(0x1774) { + initWithEmptyData(); +} + +StrategyMemoData::StrategyMemoData(const u8* inData) : GC::StrategyMemoData(0x1774, inData) { + load(); +} + +StrategyMemoData::StrategyMemoData(StrategyMemoData const& other) : GC::StrategyMemoData(other) {} + +bool StrategyMemoData::isXD(void) const { + return false; +} +StrategyMemoData* StrategyMemoData::clone(void) const +{ + return new StrategyMemoData(*this); +} + +StrategyMemoData* StrategyMemoData::create(void) const +{ + return new StrategyMemoData; +} + +void StrategyMemoData::loadFields(void) { + GC::StrategyMemoData::loadFields(); + LD_SUBSTRUCTURE_ARRAY(StrategyMemoEntry, entries, 500, 4); +} + +void StrategyMemoData::save(void) { + GC::StrategyMemoData::save(); + SV_SUBSTRUCTURE_ARRAY(StrategyMemoEntry, entries, 500, 4); + +} + + +StrategyMemoData::~StrategyMemoData(void) +{ +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoEntry.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoEntry.cpp new file mode 100644 index 0000000..fde636f --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/Common/StrategyMemoEntry.cpp @@ -0,0 +1,39 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { + +StrategyMemoEntry::~StrategyMemoEntry(void) { +} + +StrategyMemoEntry::StrategyMemoEntry(void) : GC::StrategyMemoEntry() { + initWithEmptyData(); +} + +StrategyMemoEntry::StrategyMemoEntry(const u8* inData) : GC::StrategyMemoEntry(inData) { + load(); +} + +bool StrategyMemoEntry::isXD(void) const { + return false; +} + +StrategyMemoEntry* StrategyMemoEntry::clone(void) const { + return new StrategyMemoEntry(*this); +} + +StrategyMemoEntry* StrategyMemoEntry::create(void) const { + return new StrategyMemoEntry; +} + +bool StrategyMemoEntry::isInfoPartial(void) const { + return (flags == 2); +} + +void StrategyMemoEntry::setInfoCompleteness(bool partial) { + flags = (partial) ? 2 : 0; +} + + +} +} diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/Save.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/Save.cpp new file mode 100644 index 0000000..1fa1031 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/Save.cpp @@ -0,0 +1,50 @@ +#include + +namespace LibPkmGC { +namespace Colosseum { +namespace SaveEditing { + + +Save::Save(void) : GC::SaveEditing::Save(0x60000, 3) { + initWithEmptyData(); +} + +Save::Save(const u8* inData, bool hasGCIData_, bool isDecrypted) : GC::SaveEditing::Save(0x60000, 3, inData, hasGCIData_) { + load((isDecrypted) ? 1 : 0); +} +Save::Save(Save const& other) : GC::SaveEditing::Save(other) {} + + +Save* Save::clone(void) const { + return new Save(*this); +} + +Save* Save::create(void) const { + return new Save; +} + +/* + 0x0000 -- 0x6000: save file title + icon (ignored here) + 0x6000: SaveSlot saveSlots[3] +*/ +void Save::loadFields(void) { + // deleteFields(); + + saveSlots = new GC::SaveEditing::SaveSlot*[3]; + u8* start = data + 0x6000; + /*delete saveSlots[0]; + delete saveSlots[1];*/ + saveSlots[0] = new SaveSlot(start, _is_decrypted); + saveSlots[1] = new SaveSlot(start + 0x1e000, _is_decrypted); + saveSlots[2] = new SaveSlot(start + 0x1e000*2, _is_decrypted); + +} + +void Save::save(void) { + SV_SUBSTRUCTURE_ARRAY(SaveSlot, saveSlots, 3, 0x6000); +} + + +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/SaveSlot.cpp b/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/SaveSlot.cpp new file mode 100644 index 0000000..9a495da --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Colosseum/SaveEditing/SaveSlot.cpp @@ -0,0 +1,280 @@ +#include +#include + +namespace LibPkmGC { +namespace Colosseum { +namespace SaveEditing { + +inline void decrypt_in_place_impl(u8* data, u8 digest[20]) { + u8 key[20]; + std::copy(digest, digest + 20, key); + + u32 K[5], D[5]; + + std::copy(key, key + 20, (u8*)K); // these copy calls will be optimized by the compiler + + for (size_t i = 0; i < 5; ++i) // unrolling the loops manually has no influence over the performance + K[i] = ~K[i]; // 'NOT' the 20 digest bytes + + std::copy((u8*)K, (u8*)(K + 5), key); + + for (size_t i = 0x18; i < 0x1dfd8; i += 20) { + Crypto::sha1(data + i, data + i + 20, key); // hash the 20 bytes of encrypted data -- there are the next key + + std::copy(data + i, data + i + 20, (u8*)D); + + for (size_t j = 0; j < 5; ++j) + D[j] ^= K[j]; // 'XOR' the data with the current digest + + std::copy((u8*)D, (u8*)(D + 5), data + i); + std::copy(key, key + 20, (u8*)K); + } + +} + + +inline void encrypt_impl(u8* data, u8* outData, u8 digest[20]) { + u8 key[20]; + std::copy(digest, digest + 20, key); + + u32 K[5], D[5], OD[5]; + + std::copy(key, key + 20, (u8*)K); // these copy calls will be optimized by the compiler + + for (size_t i = 0; i < 5; ++i) // unrolling the loops manually has no influence over the performance + K[i] = ~K[i]; // 'NOT' the 20 digest bytes + + std::copy((u8*)K, (u8*)(K + 5), key); + + for (size_t i = 0x18; i < 0x1dfd8; i += 20) { + std::copy(data + i, data + i + 20, (u8*)D); + + for (size_t j = 0; j < 5; ++j) + OD[j] = D[j] ^ K[j]; // 'XOR' the data with the current digest + + std::copy((u8*)OD, (u8*)(OD + 5), outData + i); + Crypto::sha1(outData + i, outData + i + 20, key); + std::copy(key, key + 20, (u8*)K); + } +} + + + + + + +SaveSlot::SaveSlot(void) : GC::SaveEditing::SaveSlot(0x1e000, 20) { + initWithEmptyData(1); +} + + +SaveSlot::SaveSlot(const u8* inData, bool isDecrypted) : GC::SaveEditing::SaveSlot(0x1e000, 20, inData) { + u32 flags = (isDecrypted) ? 1 : 0; + load(flags); +} + + +SaveSlot::SaveSlot(SaveSlot const& other) : GC::SaveEditing::SaveSlot(other), storyModeSaveCount(other.storyModeSaveCount) { + CP_ARRAY(checksum, 20); +} + +void SaveSlot::deleteFields(void) { + GC::SaveEditing::SaveSlot::deleteFields(); + _deleteFields_extension(); +} + +SaveSlot::~SaveSlot(void) { + _deleteFields_extension(); +} + +SaveSlot* SaveSlot::clone(void) const { + return new SaveSlot(*this); +} + +SaveSlot* SaveSlot::create(void) const { + return new SaveSlot; +} + +void SaveSlot::swap(SaveSlot& other) { + GC::SaveEditing::SaveSlot::swap(other); + SW(storyModeSaveCount); + SW_ARRAY(checksum, 20); + +} + + +bool SaveSlot::checkChecksum(bool fix){ + u8 newDigest[20]; + std::fill(data + 12, data + 16, 0); // headerChecksum field + Crypto::sha1(data, data + 0x1dfd8, newDigest); + SV_FIELD(s32, headerChecksum, 12); + + bool ret = std::equal(checksum, checksum + 20, newDigest); + if (!ret && fix) std::copy(newDigest, newDigest + 20, checksum); + return ret; +} + +bool SaveSlot::checkHeaderChecksum(bool fix){ + using namespace IntegerManip::BE; + u8 newDigest[20]; // when computing the header's checksum, words @0x18 @0x1c are already encrypted + std::fill(data + 12, data + 16, 0); // headerChecksum field + Crypto::sha1(data, data + 0x1dfd8, newDigest); + + u32 D[2], H[2]; + u8 tmpBuf[8]; + + std::copy(newDigest, newDigest + 8, (u8*)H); + std::copy(data + 0x18, data + 0x20, (u8*)D); + + + D[0] ^= ~H[0]; + D[1] ^= ~H[1]; + + std::copy((u8*)D, (u8*)(D + 2), tmpBuf); + + s32 newHC = 0; + for (size_t i = 0; i < 0x18; i += 4) + newHC -= (s32) toInteger(data + i); + + newHC -= (s32)toInteger(tmpBuf); + newHC -= (s32)toInteger(tmpBuf + 4); + + SV_FIELD(s32, headerChecksum, 12); + + bool ret = (newHC == headerChecksum); + if (!ret && fix) headerChecksum = newHC; + return ret; +} + +std::pair SaveSlot::checkBothChecksums(bool fixGlobalChecksum, bool fixHeaderChecksum) { + if (!fixGlobalChecksum || !fixHeaderChecksum) return std::pair(checkChecksum(fixGlobalChecksum), checkHeaderChecksum(fixHeaderChecksum)); + else { + using namespace IntegerManip::BE; + u8 newDigest[20]; // when computing the header's checksum, words @0x18 @0x1c are already encrypted + std::fill(data + 12, data + 16, 0); // headerChecksum field + Crypto::sha1(data, data + 0x1dfd8, newDigest); + + bool ret1 = std::equal(checksum, checksum + 20, newDigest); + if (!ret1) std::copy(newDigest, newDigest + 20, checksum); + + u32 D[2], H[2]; + u8 tmpBuf[8]; + + std::copy(newDigest, newDigest + 8, (u8*)H); + std::copy(data + 0x18, data + 0x20, (u8*)D); + + + D[0] ^= ~H[0]; + D[1] ^= ~H[1]; + + std::copy((u8*)D, (u8*)(D + 2), tmpBuf); + + s32 newHC = 0; + for (size_t i = 0; i < 0x18; i += 4) + newHC -= (s32)toInteger(data + i); + + newHC -= (s32)toInteger(tmpBuf); + newHC -= (s32)toInteger(tmpBuf + 4); + + SV_FIELD(s32, headerChecksum, 12); + + bool ret2 = (newHC == headerChecksum); + headerChecksum = newHC; + + return std::pair(ret1, ret2); + } +} + +bool SaveSlot::isCorrupt(void) { + if ((static_cast(magic) & 0xffff0000) != (u32)ColosseumMagic) return true; + std::pair chk = checkBothChecksums(); + return !chk.first || !chk.second; +} + + +void SaveSlot::loadData(u32 flags) { + bool decrypted = (flags & 1) == 1; + + std::copy(data + 0x1dfec, data + 0x1e000, checksum); + + if (!decrypted) decrypt_in_place_impl(data, checksum); +} + + +void SaveSlot::loadFields(void) { + randomBytes = new u8[20]; + LD_FIELD_E(u32, magic, 0, SaveMagic); + LD_FIELD(s32, saveCount, 4); + + version.load(data + 8); + LD_FIELD(u32, headerChecksum, 12); + LD_ARRAY(u32, memcardUID, 2, 16); + LD_FIELD(u32, storyModeSaveCount, 24); + + LD_FIELD_B(u8, noRumble, 0x31); + LD_FIELD_E(u16, titleScreenLanguage, 0x32, LanguageIndex); + size_t offset = 0x70 + 8; + + +#define LD_IMPLEMENTED_SUBSTRUCTURE(type, field) LD_SUBSTRUCTURE(type, field, offset); offset += type::size; + + LD_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player); + LD_IMPLEMENTED_SUBSTRUCTURE(PCData, PC); + LD_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox); + LD_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare); + LD_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo); + offset += 0x523c; + LD_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode); + // unknown substructures following + + std::copy(data + 0x1dfd8, data + 0x1dfec, randomBytes); +} + +void SaveSlot::save(void) { + magic = ColosseumMagic; + SV_FIELD_E(u32, ColosseumMagic, 0, SaveMagic); + SV_FIELD(u32, saveCount, 4); + //deleteFields(); + + version.save(data + 8); + SV_ARRAY(u32, memcardUID, 2, 16); + SV_FIELD(s32, storyModeSaveCount, 24); + SV_FIELD_B(u8, noRumble, 0x31); + SV_FIELD_E(u16, titleScreenLanguage, 0x32, LanguageIndex); + + size_t offset = 0x70 + 8; + + +#define SV_IMPLEMENTED_SUBSTRUCTURE(type, field) SV_SUBSTRUCTURE(type, field, offset); offset += type::size; + + SV_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player); + SV_IMPLEMENTED_SUBSTRUCTURE(PCData, PC); + SV_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox); + SV_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare); + SV_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo); + offset += 0x523c; + SV_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode); + // unknown substructures following + + + checkBothChecksums(true, true); // update checksums + SV_FIELD(u32, headerChecksum, 12); + + std::copy(randomBytes, randomBytes + 20, data + 0x1dfd8); + std::copy(checksum, checksum + 20, data + 0x1dfec); + +} + +void SaveSlot::saveEncrypted(u8* outBuf) { + save(); + std::copy(data, data + 0x18, outBuf); + std::copy(data + 0x1dfd8, data + 0x1e000, outBuf + 0x1dfd8); + encrypt_impl(data, outBuf, checksum); +} + +void SaveSlot::_deleteFields_extension(void) { +} + +} +} +} diff --git a/LibPkmGC/src/LibPkmGC/Core/Crypto.cpp b/LibPkmGC/src/LibPkmGC/Core/Crypto.cpp new file mode 100644 index 0000000..578bfb0 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Crypto.cpp @@ -0,0 +1,301 @@ +#include +#include +using namespace LibPkmGC; + +#define os_memcpy memcpy +#define os_memset memset + +// MODIFIED : + +/* ===== start - public domain SHA1 implementation ===== */ + +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +----------------- +Modified 7/98 +By James H. Brown +Still 100% Public Domain + +Corrected a problem which generated improper hash values on 16 bit machines +Routine SHA1Update changed from +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int +len) +to +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned +long len) + +The 'len' parameter was declared an int which works fine on 32 bit machines. +However, on 16 bit machines an int is too small for the shifts being done +against +it. This caused the hash function to generate incorrect values if len was +greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). + +Since the file IO in main() reads 16K at a time, any file 8K or larger would +be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million +"a"s). + +I also changed the declaration of variables i & j in SHA1Update to +unsigned long from unsigned int for the same reason. + +These changes should make no difference to any 32 bit implementations since +an +int and a long are the same size in those environments. + +-- +I also corrected a few compiler warnings generated by Borland C. +1. Added #include for exit() prototype +2. Removed unused variable 'j' in SHA1Final +3. Changed exit(0) to return(0) at end of main. + +ALL changes I made can be located by searching for comments containing 'JHB' +----------------- +Modified 8/98 +By Steve Reid +Still 100% public domain + +1- Removed #include and used return() instead of exit() +2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) +3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net + +----------------- +Modified 4/01 +By Saul Kravitz +Still 100% PD +Modified to run on Compaq Alpha hardware. + +----------------- +Modified 4/01 +By Jouni Malinen +Minor changes to match the coding style used in Dynamics. + +Modified September 24, 2004 +By Jouni Malinen +Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined. + +*/ + +/* +Test Vectors (from FIPS PUB 180-1) +"abc" +A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" +34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +struct SHA1_CTX { + u32 state[5]; + u32 count[2]; + u8 buffer[64]; +}; + +#define SHA1HANDSOFF + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BOOST_ENDIAN_BIG_BYTE == BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define blk0(i) (l[i] = (rol(l[i], 24) & 0xFF00FF00) | \ + (rol(l[i], 8) & 0x00FF00FF)) +#else +#define blk0(i) l[i] +#endif +#define blk(i) (l[i & 15] = rol(l[(i + 13) & 15] ^ \ + l[(i + 8) & 15] ^ l[(i + 2) & 15] ^ l[i & 15], 1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R1(v,w,x,y,z,i) \ + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ + w = rol(w, 30); +#define R2(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); +#define R3(v,w,x,y,z,i) \ + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ + w = rol(w, 30); +#define R4(v,w,x,y,z,i) \ + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ + w=rol(w, 30); + + +#ifdef VERBOSE /* SAK */ +void SHAPrintContext(SHA1_CTX *context, char *msg) +{ + printf("%s (%d,%d) %x %x %x %x %x\n", + msg, + context->count[0], context->count[1], + context->state[0], + context->state[1], + context->state[2], + context->state[3], + context->state[4]); +} +#endif + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +inline void SHA1Transform(u32 state[5], const u8 buffer[64]) +{ + u32 a, b, c, d, e; + u32 l[16]; +#ifdef SHA1HANDSOFF + os_memcpy((u8*)l, buffer, 64); +#else +// +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1); R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3); + R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5); R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7); + R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9); R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11); + R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13); R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17); R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19); + R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21); R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23); + R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25); R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27); + R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29); R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31); + R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33); R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35); + R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37); R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39); + R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41); R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43); + R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45); R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47); + R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49); R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51); + R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53); R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55); + R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57); R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59); + R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61); R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63); + R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65); R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67); + R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69); R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71); + R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73); R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75); + R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77); R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + //a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + //os_memset(block, 0, 64); +#endif +} + + +/* SHA1Init - Initialize new context */ + +inline void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +inline void SHA1Update(SHA1_CTX* context, const u8 *_data, u32 len) +{ + u32 i, j; + const u8 *data = _data; + +#ifdef VERBOSE + SHAPrintContext(context, "before"); +#endif + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) + context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + os_memcpy(&context->buffer[j], data, (i = 64 - j)); + SHA1Transform(context->state, context->buffer); + for (; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + os_memcpy(&context->buffer[j], &data[i], len - i); +#ifdef VERBOSE + SHAPrintContext(context, "after "); +#endif +} + + +/* Add padding and return the message digest. */ + +inline void SHA1Final(u8 digest[20], SHA1_CTX* context) +{ + u32 i; + u8 finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (u8) + ((context->count[(i >= 4 ? 0 : 1)] >> + ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ + } + SHA1Update(context, (u8 *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (u8 *) "\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() + */ + for (i = 0; i < 20; i++) { + digest[i] = (u8) + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & + 255); + } + + /* Wipe variables */ + /* + i = 0; + os_memset(context->buffer, 0, 64); + os_memset(context->state, 0, 20); + os_memset(context->count, 0, 8); + os_memset(finalcount, 0, 8); + */ +} + +/* ===== end - public domain SHA1 implementation ===== */ + +static const char* nibbles = "0123456789abcdef"; + +namespace LibPkmGC { +namespace Crypto { + +void sha1(const u8* start, const u8* end, u8 digest[20]) { + SHA1_CTX ctx; + SHA1Init(&ctx); + SHA1Update(&ctx, start, (size_t)(end-start)); + SHA1Final(digest, &ctx); +} + +std::string sha1(const u8* start, const u8* end) { + u8 digest[20]; + sha1(start, end, digest); + + std::string ret; + ret.resize(40); + for (size_t i = 0; i < 20; ++i) { + ret[39 - 2 * i] = nibbles[digest[19 - i] & 0x0f]; + ret[39 - 2 * i - 1] = nibbles[(digest[19 - i] >> 4) & 0x0f]; + } + return ret; +} + + +} +} diff --git a/LibPkmGC/src/LibPkmGC/Core/Detail/AbilityNames.cpp b/LibPkmGC/src/LibPkmGC/Core/Detail/AbilityNames.cpp new file mode 100644 index 0000000..68dbe80 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Detail/AbilityNames.cpp @@ -0,0 +1,502 @@ +#include + + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Abilities { + +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + + +const char *englishNames[78] = { + "(None)", + "STENCH", + "DRIZZLE", + "SPEED BOOST", + "BATTLE ARMOR", + "STURDY", + "DAMP", + "LIMBER", + "SAND VEIL", + "STATIC", + "VOLT ABSORB", + "WATER ABSORB", + "OBLIVIOUS", + "CLOUD NINE", + "COMPOUNDEYES", + "INSOMNIA", + "COLOR CHANGE", + "IMMUNITY", + "FLASH FIRE", + "SHIELD DUST", + "OWN TEMPO", + "SUCTION CUPS", + "INTIMIDATE", + "SHADOW TAG", + "ROUGH SKIN", + "WONDER GUARD", + "LEVITATE", + "EFFECT SPORE", + "SYNCHRONIZE", + "CLEAR BODY", + "NATURAL CURE", + "LIGHTNINGROD", + "SERENE GRACE", + "SWIFT SWIM", + "CHLOROPHYLL", + "ILLUMINATE", + "TRACE", + "HUGE POWER", + "POISON POINT", + "INNER FOCUS", + "MAGMA ARMOR", + "WATER VEIL", + "MAGNET PULL", + "SOUNDPROOF", + "RAIN DISH", + "SAND STREAM", + "PRESSURE", + "THICK FAT", + "EARLY BIRD", + "FLAME BODY", + "RUN AWAY", + "KEEN EYE", + "HYPER CUTTER", + "PICKUP", + "TRUANT", + "HUSTLE", + "CUTE CHARM", + "PLUS", + "MINUS", + "FORECAST", + "STICKY HOLD", + "SHED SKIN", + "GUTS", + "MARVEL SCALE", + "LIQUID OOZE", + "OVERGROW", + "BLAZE", + "TORRENT", + "SWARM", + "ROCK HEAD", + "DROUGHT", + "ARENA TRAP", + "VITAL SPIRIT", + "WHITE SMOKE", + "PURE POWER", + "SHELL ARMOR", + "CACOPHONY", + "AIR LOCK" +}; + +const char *frenchNames[78] = { + "(Rien)", + "PUANTEUR", + "CRACHIN", + "TURBO", + "ARMURBASTON", + "FERMETE", + "MOITEUR", + "ECHAUFFEMENT", + "VOILE SABLE", + "STATIK", + "ABSORB VOLT", + "ABSORB EAU", + "BENET", + "CIEL GRIS", + "OEIL COMPOSE", + "INSOMNIA", + "DEGUISEMENT", + "VACCIN", + "TORCHE", + "ECRAN POUDRE", + "TEMPO PERSO", + "VENTOUSE", + "INTIMIDATION", + "MARQUE OMBRE", + "PEAU DURE", + "GARDE MYSTIK", + "LEVITATION", + "POSE SPORE", + "SYNCHRO", + "CORPS SAIN", + "MEDIC NATURE", + "PARATONNERRE", + "SERENITE", + "GLISSADE", + "CHLOROPHYLE", + "LUMIATIRANCE", + "CALQUE", + "COLOFORCE", + "POINT POISON", + "ATTENTION", + "ARMUMAGMA", + "IGNIFU-VOILE", + "MAGNEPIEGE", + "ANTI-BRUIT", + "CUVETTE", + "SABLE VOLANT", + "PRESSION", + "ISOGRAISSE", + "MATINAL", + "CORPS ARDENT", + "FUITE", + "REGARD VIF", + "HYPER CUTTER", + "RAMASSAGE", + "ABSENTEISME", + "AGITATION", + "JOLI SOURIRE", + "PLUS", + "MINUS", + "METEO", + "GLUE", + "MUE", + "CRAN", + "ECAILLE SPE.", + "SUINTEMENT", + "ENGRAIS", + "BRASIER", + "TORRENT", + "ESSAIM", + "TETE DE ROC", + "SECHERESSE", + "PIEGE", + "ESPRIT VITAL", + "ECRAN FUMEE", + "FORCE PURE", + "COQUE ARMURE", + "CACOPHONIE", + "AIR LOCK", +}; + +const char *germanNames[78] = { + "(Nichts)", + "DUFTNOTE", + "NIESEL", + "TEMPOSCHUB", + "KAMPFPANZER", + "ROBUSTHEIT", + "FEUCHTIGKEIT", + "FLEXIBILIT\xC3\x84T", + "SANDSCHLEIER", + "STATIK", + "VOLTABSORBER", + "H2O-ABSORBER", + "D\xC3\x96SIGKEIT", + "WOLKE SIEBEN", + "FACETTENAUGE", + "INSOMNIA", + "FARBWECHSEL", + "IMMUNIT\xC3\x84T", + "FEUERF\xC3\x84NGER", + "PUDERABWEHR", + "TEMPOMACHER", + "SAUGNAPF", + "BEDROHER", + "WEGSPERRE", + "RAUHAUT", + "WUNDERWACHE", + "SCHWEBE", + "SPORENWIRT", + "SYNCHRO", + "NEUTRALTORSO", + "INNERE KRAFT", + "BLITZF\xC3\x84NGER", + "EDELMUT", + "WASSERTEMPO", + "CHLOROPHYLL", + "ERLEUCHTUNG", + "F\xC3\x84HRTE", + "KRAFTKOLOSS", + "GIFTDORN", + "KONZENTRATOR", + "MAGMAPANZER", + "AQUAH\xC3\x9CLLE", + "MAGNETFALLE", + "L\xC3\x84RMSCHUTZ", + "REGENGENUSS", + "SANDSTURM", + "ERZWINGER", + "SPECKSCHICHT", + "FR\xC3\x9CHWECKER", + "FLAMMK\xC3\x96RPER", + "ANGSTHASE", + "ADLERAUGE", + "SCHERENMACHT", + "MITNAHME", + "SCHNARCHNASE", + "\xC3\x9C""BEREIFER", + "CHARMEBOLZEN", + "PLUS", + "MINUS", + "PROGNOSE", + "WERTEHALTER", + "EXPIDERMIS", + "ADRENALIN", + "NOTSCHUTZ", + "KLOAKENSOSSE", + "NOTD\xC3\x9CNGER", + "GROSSBRAND", + "STURZBACH", + "HEXAPLAGA", + "STEINHAUPT", + "D\xC3\x9CRRE", + "AUSWEGSLOS", + "MUNTERKEIT", + "PULVERRAUCH", + "MENTALKRAFT", + "PANZERHAUT", + "KAKOPHONY", + "KLIMASCHUTZ", +}; + +const char *italianNames[78] = { + "(Nessuno)", + "TANFO", + "PIOVISCHIO", + "ACCELERATORE", + "LOTTASCUDO", + "VIGORE", + "UMIDIT\xC3\x80", + "SCIOLTEZZA", + "SABBIAVELO", + "STATICO", + "ASSORBIVOLT", + "ASSORBACQUA", + "INDIFFERENZA", + "ANTIMETEO", + "INSETTOCCHI", + "INSONNIA", + "CAMBIACOLORE", + "IMMUNIT\xC3\x80", + "FUOCARDORE", + "POLVOSCUDO", + "MENTE LOCALE", + "VENTOSE", + "PREPOTENZA", + "PEDINOMBRA", + "CARTAVETRO", + "MAGIDIFESA", + "LEVITAZIONE", + "SPARGISPORA", + "SINCRONISMO", + "CORPOCHIARO", + "ALTERNACURA", + "PARAFULMINE", + "LEGGIADRO", + "NUOTOVELOX", + "CLOROFILLA", + "RISPLENDI", + "TRACCIA", + "MACROFORZA", + "VELENOPUNTO", + "FUOCODENTRO", + "MAGMASCUDO", + "IDROVELO", + "MAGNETISMO", + "ANTISUONO", + "COPRIPIOGGIA", + "SABBIAFIUME", + "PRESSIONE", + "GRASSOSPESSO", + "SVEGLIALAMPO", + "CORPODIFUOCO", + "FUGAFACILE", + "SGUARDOFERMO", + "IPERTAGLIO", + "RACCOLTA", + "PIGRONE", + "TUTTAFRETTA", + "INCANTEVOLE", + "PI\xC3\x99", + "MENO", + "PREVISIONI", + "ANTIFURTO", + "MUTA", + "DENTISTRETTI", + "PELLEDURA", + "MELMA", + "ERBAIUTO", + "AIUTOFUOCO", + "ACQUAIUTO", + "AIUTINSETTO", + "TESTADURA", + "SICCIT\xC3\x80", + "TRAPPOARENA", + "SPIRITOVIVO", + "FUMOCHIARO", + "FORZAPURA", + "GUSCIOSCUDO", + "CACOFONIA", + "RIPARO", +}; + +const char *spanishNames[78] = { + "(Ninguno)", + "HEDOR", + "LLOVIZNA", + "IMPULSO", + "ARMAD. BAT.", + "ROBUSTEZ", + "HUMEDAD", + "FLEXIBILIDAD", + "VELO ARENA", + "ELEC. EST\xC3\x81T.", + "ABSOR. ELEC.", + "ABSOR. AGUA", + "DESPISTE", + "ACLIMATACI\xC3\x93N", + "OJOCOMPUESTO", + "INSOMNIO", + "CAMBIO COLOR", + "INMUNIDAD", + "ABSOR. FUEGO", + "POLVO ESCUDO", + "RITMO PROPIO", + "VENTOSAS", + "INTIMIDACI\xC3\x93N", + "SOMBRATRAMPA", + "PIEL TOSCA", + "SUPERGUARDA", + "LEVITACI\xC3\x93N", + "EFEC. ESPORA", + "SINCRON\xC3\x8D""A", + "CUERPO PURO", + "CURA NATURAL", + "PARARRAYOS", + "DICHA", + "NADO R\xC3\x81PIDO", + "CLOROFILA", + "ILUMINACI\xC3\x93N", + "RASTRO", + "POTENCIA", + "PUNTO T\xC3\x93XICO", + "FOCO INTERNO", + "ESCUDO MAGMA", + "VELO AGUA", + "IM\xC3\x81N", + "INSONORIZAR", + "CURA LLUVIA", + "CHORRO ARENA", + "PRESI\xC3\x93N", + "SEBO", + "MADRUGAR", + "CUERPO LLAMA", + "FUGA", + "VISTA LINCE", + "CORTE FUERTE", + "RECOGIDA", + "AUSENTE", + "ENTUSIASMO", + "GRAN ENCANTO", + "M\xC3\x81S", + "MENOS", + "PREDICCI\xC3\x93N", + "VISCOSIDAD", + "MUDAR", + "AGALLAS", + "ESCAMA ESP.", + "LODO L\xC3\x8DQUIDO", + "ESPESURA", + "MAR LLAMAS", + "TORRENTE", + "ENJAMBRE", + "CABEZA ROCA", + "SEQU\xC3\x8D""A", + "TRAMPA ARENA", + "ESP\xC3\x8DR. VITAL", + "HUMO BLANCO", + "ENERG\xC3\x8D""A PURA", + "CAPARAZ\xC3\x93N", + "CACOFON\xC3\x8D""A", + "BUCLE AIRE" +}; + +const char *japaneseNames[78] = { + "(\xe4\xbd\x95\xe3\x82\x82)", + "\xe3\x81\x82\xe3\x81\x8f\xe3\x81\x97\xe3\x82\x85\xe3\x81\x86", + "\xe3\x81\x82\xe3\x82\x81\xe3\x81\xb5\xe3\x82\x89\xe3\x81\x97", + "\xe3\x81\x8b\xe3\x81\x9d\xe3\x81\x8f", + "\xe3\x82\xab\xe3\x83\x96\xe3\x83\x88\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\x9e\xe3\x83\xbc", + "\xe3\x81\x8c\xe3\x82\x93\xe3\x81\x98\xe3\x82\x87\xe3\x81\x86", + "\xe3\x81\x97\xe3\x82\x81\xe3\x82\x8a\xe3\x81\x91", + "\xe3\x81\x98\xe3\x82\x85\xe3\x81\x86\xe3\x81\xaa\xe3\x82\x93", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x8c\xe3\x81\x8f\xe3\x82\x8c", + "\xe3\x81\x9b\xe3\x81\x84\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x8d", + "\xe3\x81\xa1\xe3\x81\x8f\xe3\x81\xa7\xe3\x82\x93", + "\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x99\xe3\x81\x84", + "\xe3\x81\xa9\xe3\x82\x93\xe3\x81\x8b\xe3\x82\x93", + "\xe3\x83\x8e\xe3\x83\xbc\xe3\x81\xa6\xe3\x82\x93\xe3\x81\x8d", + "\xe3\x81\xb5\xe3\x81\x8f\xe3\x81\x8c\xe3\x82\x93", + "\xe3\x81\xb5\xe3\x81\xbf\xe3\x82\x93", + "\xe3\x81\xb8\xe3\x82\x93\xe3\x81\x97\xe3\x82\x87\xe3\x81\x8f", + "\xe3\x82\x81\xe3\x82\x93\xe3\x81\x88\xe3\x81\x8d", + "\xe3\x82\x82\xe3\x82\x89\xe3\x81\x84\xe3\x81\xb3", + "\xe3\x82\x8a\xe3\x82\x93\xe3\x81\xb7\xe3\x82\x93", + "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\x9a\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x81\x8d\xe3\x82\x85\xe3\x81\x86\xe3\x81\xb0\xe3\x82\x93", + "\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x8f", + "\xe3\x81\x8b\xe3\x81\x92\xe3\x81\xb5\xe3\x81\xbf", + "\xe3\x81\x95\xe3\x82\x81\xe3\x81\xaf\xe3\x81\xa0", + "\xe3\x81\xb5\xe3\x81\x97\xe3\x81\x8e\xe3\x81\xaa\xe3\x81\xbe\xe3\x82\x82\xe3\x82\x8a", + "\xe3\x81\xb5\xe3\x82\x86\xe3\x81\x86", + "\xe3\x81\xbb\xe3\x81\x86\xe3\x81\x97", + "\xe3\x82\xb7\xe3\x83\xb3\xe3\x82\xaf\xe3\x83\xad", + "\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xa2\xe3\x83\x9c\xe3\x83\x87\xe3\x82\xa3", + "\xe3\x81\x97\xe3\x81\x9c\xe3\x82\x93\xe3\x81\x8b\xe3\x81\x84\xe3\x81\xb5\xe3\x81\x8f", + "\xe3\x81\xb2\xe3\x82\x89\xe3\x81\x84\xe3\x81\x97\xe3\x82\x93", + "\xe3\x81\xa6\xe3\x82\x93\xe3\x81\xae\xe3\x82\x81\xe3\x81\x90\xe3\x81\xbf", + "\xe3\x81\x99\xe3\x81\x84\xe3\x81\x99\xe3\x81\x84", + "\xe3\x82\x88\xe3\x81\x86\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x8f\xe3\x81\x9d", + "\xe3\x81\xaf\xe3\x81\xa3\xe3\x81\x93\xe3\x81\x86", + "\xe3\x83\x88\xe3\x83\xac\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89\xe3\x82\x82\xe3\x81\xa1", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xae\xe3\x83\x88\xe3\x82\xb2", + "\xe3\x81\x9b\xe3\x81\x84\xe3\x81\x97\xe3\x82\x93\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x8f", + "\xe3\x83\x9e\xe3\x82\xb0\xe3\x83\x9e\xe3\x81\xae\xe3\x82\x88\xe3\x82\x8d\xe3\x81\x84", + "\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\xae\xe3\x83\x99\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x81\x98\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x8f", + "\xe3\x81\xbc\xe3\x81\x86\xe3\x81\x8a\xe3\x82\x93", + "\xe3\x81\x82\xe3\x82\x81\xe3\x81\x86\xe3\x81\x91\xe3\x81\x96\xe3\x82\x89", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\x93\xe3\x81\x97", + "\xe3\x83\x97\xe3\x83\xac\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\xbc", + "\xe3\x81\x82\xe3\x81\xa4\xe3\x81\x84\xe3\x81\x97\xe3\x81\xbc\xe3\x81\x86", + "\xe3\x81\xaf\xe3\x82\x84\xe3\x81\x8a\xe3\x81\x8d", + "\xe3\x81\xbb\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xae\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xa0", + "\xe3\x81\xab\xe3\x81\x92\xe3\x81\x82\xe3\x81\x97", + "\xe3\x81\x99\xe3\x82\x8b\xe3\x81\xa9\xe3\x81\x84\xe3\x82\x81", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x82\x8a\xe3\x81\x8d\xe3\x83\x90\xe3\x82\xb5\xe3\x83\x9f", + "\xe3\x82\x82\xe3\x81\xae\xe3\x81\xb2\xe3\x82\x8d\xe3\x81\x84", + "\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x91", + "\xe3\x81\xaf\xe3\x82\x8a\xe3\x81\x8d\xe3\x82\x8a", + "\xe3\x83\xa1\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xad\xe3\x83\x9c\xe3\x83\x87\xe3\x82\xa3", + "\xe3\x83\x97\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\x8a\xe3\x82\xb9", + "\xe3\x81\xa6\xe3\x82\x93\xe3\x81\x8d\xe3\x82\x84", + "\xe3\x81\xad\xe3\x82\x93\xe3\x81\xa1\xe3\x82\x83\xe3\x81\x8f", + "\xe3\x81\xa0\xe3\x81\xa3\xe3\x81\xb4", + "\xe3\x81\x93\xe3\x82\x93\xe3\x81\x98\xe3\x82\x87\xe3\x81\x86", + "\xe3\x81\xb5\xe3\x81\x97\xe3\x81\x8e\xe3\x81\xaa\xe3\x82\xa6\xe3\x83\xad\xe3\x82\xb3", + "\xe3\x83\x98\xe3\x83\x89\xe3\x83\xad\xe3\x81\x88\xe3\x81\x8d", + "\xe3\x81\x97\xe3\x82\x93\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x8f", + "\xe3\x82\x82\xe3\x81\x86\xe3\x81\x8b", + "\xe3\x81\x92\xe3\x81\x8d\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86", + "\xe3\x82\x80\xe3\x81\x97\xe3\x81\xae\xe3\x81\x97\xe3\x82\x89\xe3\x81\x9b", + "\xe3\x81\x84\xe3\x81\x97\xe3\x81\x82\xe3\x81\x9f\xe3\x81\xbe", + "\xe3\x81\xb2\xe3\x81\xa7\xe3\x82\x8a", + "\xe3\x81\x82\xe3\x82\x8a\xe3\x81\x98\xe3\x81\x94\xe3\x81\x8f", + "\xe3\x82\x84\xe3\x82\x8b\xe3\x81\x8d", + "\xe3\x81\x97\xe3\x82\x8d\xe3\x81\x84\xe3\x81\x91\xe3\x82\x80\xe3\x82\x8a", + "\xe3\x83\xa8\xe3\x82\xac\xe3\x83\x91\xe3\x83\xaf\xe3\x83\xbc", + "\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xab\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\x9e\xe3\x83\xbc", + "\xe3\x81\x9d\xe3\x81\x86\xe3\x81\x8a\xe3\x82\x93", + "\xe3\x82\xa8\xe3\x82\xa2\xe3\x83\xad\xe3\x83\x83\xe3\x82\xaf" +}; + +} +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Core/Detail/ItemNames.cpp b/LibPkmGC/src/LibPkmGC/Core/Detail/ItemNames.cpp new file mode 100644 index 0000000..692f9e4 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Detail/ItemNames.cpp @@ -0,0 +1,2394 @@ +#include + + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + + +namespace GivableItems { + +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const char *englishNames[245] = { + "(None)", + "MASTER BALL", + "ULTRA BALL", + "GREAT BALL", + "POK\xc3\xa9 BALL", + "SAFARI BALL", + "NET BALL", + "DIVE BALL", + "NEST BALL", + "REPEAT BALL", + "TIMER BALL", + "LUXURY BALL", + "PREMIER BALL", + "POTION", + "ANTIDOTE", + "BURN HEAL", + "ICE HEAL", + "AWAKENING", + "PARLYZ HEAL", + "FULL RESTORE", + "MAX POTION", + "HYPER POTION", + "SUPER POTION", + "FULL HEAL", + "REVIVE", + "MAX REVIVE", + "FRESH WATER", + "SODA POP", + "LEMONADE", + "MOOMOO MILK", + "ENERGYPOWDER", + "ENERGY ROOT", + "HEAL POWDER", + "REVIVAL HERB", + "ETHER", + "MAX ETHER", + "ELIXIR", + "MAX ELIXIR", + "LAVA COOKIE", + "BLUE FLUTE", + "YELLOW FLUTE", + "RED FLUTE", + "BLACK FLUTE", + "WHITE FLUTE", + "BERRY JUICE", + "SACRED ASH", + "SHOAL SALT", + "SHOAL SHELL", + "RED SHARD", + "BLUE SHARD", + "YELLOW SHARD", + "GREEN SHARD", + "HP UP", + "PROTEIN", + "IRON", + "CARBOS", + "CALCIUM", + "RARE CANDY", + "PP UP", + "ZINC", + "PP MAX", + "GUARD SPEC", + "DIRE HIT", + "X ATTACK", + "X DEFEND", + "X SPEED", + "X ACCURACY", + "X SPECIAL", + "POK\xc3\xa9 DOLL", + "FLUFFY TAIL", + "SUPER REPEL", + "MAX REPEL", + "ESCAPE ROPE", + "REPEL", + "SUN STONE", + "MOON STONE", + "FIRE STONE", + "THUNDERSTONE", + "WATER STONE", + "LEAF STONE", + "TINYMUSHROOM", + "BIG MUSHROOM", + "PEARL", + "BIG PEARL", + "STARDUST", + "STAR PIECE", + "NUGGET", + "HEART SCALE", + "ORANGE MAIL", + "HARBOR MAIL", + "GLITTER MAIL", + "MECH MAIL", + "WOOD MAIL", + "WAVE MAIL", + "BEAD MAIL", + "SHADOW MAIL", + "TROPIC MAIL", + "DREAM MAIL", + "FAB MAIL", + "RETRO MAIL", + "CHERI BERRY", + "CHESTO BERRY", + "PECHA BERRY", + "RAWST BERRY", + "ASPEAR BERRY", + "LEPPA BERRY", + "ORAN BERRY", + "PERSIM BERRY", + "LUM BERRY", + "SITRUS BERRY", + "FIGY BERRY", + "WIKI BERRY", + "MAGO BERRY", + "AGUAV BERRY", + "IAPAPA BERRY", + "RAZZ BERRY", + "BLUK BERRY", + "NANAB BERRY", + "WEPEAR BERRY", + "PINAP BERRY", + "POMEG BERRY", + "KELPSY BERRY", + "QUALOT BERRY", + "HONDEW BERRY", + "GREPA BERRY", + "TAMATO BERRY", + "CORNN BERRY", + "MAGOST BERRY", + "RABUTA BERRY", + "NOMEL BERRY", + "SPELON BERRY", + "PAMTRE BERRY", + "WATMEL BERRY", + "DURIN BERRY", + "BELUE BERRY", + "LIECHI BERRY", + "GANLON BERRY", + "SALAC BERRY", + "PETAYA BERRY", + "APICOT BERRY", + "LANSAT BERRY", + "STARF BERRY", + "ENIGMA BERRY", + "BRIGHTPOWDER", + "WHITE HERB", + "MACHO BRACE", + "EXP. SHARE", + "QUICK CLAW", + "SOOTHE BELL", + "MENTAL HERB", + "CHOICE BAND", + "KING'S ROCK", + "SILVERPOWDER", + "AMULET COIN", + "CLEANSE TAG", + "SOUL DEW", + "DEEPSEATOOTH", + "DEEPSEASCALE", + "SMOKE BALL", + "EVERSTONE", + "FOCUS BAND", + "LUCKY EGG", + "SCOPE LENS", + "METAL COAT", + "LEFTOVERS", + "DRAGON SCALE", + "LIGHT BALL", + "SOFT SAND", + "HARD STONE", + "MIRACLE SEED", + "BLACKGLASSES", + "BLACK BELT", + "MAGNET", + "MYSTIC WATER", + "SHARP BEAK", + "POISON BARB", + "NEVERMELTICE", + "SPELL TAG", + "TWISTEDSPOON", + "CHARCOAL", + "DRAGON FANG", + "SILK SCARF", + "UP-GRADE", + "SHELL BELL", + "SEA INCENSE", + "LAX INCENSE", + "LUCKY PUNCH", + "METAL POWDER", + "THICK CLUB", + "STICK", + "RED SCARF", + "BLUE SCARF", + "PINK SCARF", + "GREEN SCARF", + "YELLOW SCARF", + "TM01", + "TM02", + "TM03", + "TM04", + "TM05", + "TM06", + "TM07", + "TM08", + "TM09", + "TM10", + "TM11", + "TM12", + "TM13", + "TM14", + "TM15", + "TM16", + "TM17", + "TM18", + "TM19", + "TM20", + "TM21", + "TM22", + "TM23", + "TM24", + "TM25", + "TM26", + "TM27", + "TM28", + "TM29", + "TM30", + "TM31", + "TM32", + "TM33", + "TM34", + "TM35", + "TM36", + "TM37", + "TM38", + "TM39", + "TM40", + "TM41", + "TM42", + "TM43", + "TM44", + "TM45", + "TM46", + "TM47", + "TM48", + "TM49", + "TM50" +}; + +const char *frenchNames[245] = { + "(Rien)", + "MASTER BALL", + "HYPER BALL", + "SUPER BALL", + "POK\xc3\xa9 BALL", + "SAFARI BALL", + "FILET BALL", + "SCUBA BALL", + "FAIBLO BALL", + "BIS BALL", + "CHRONO BALL", + "LUXE BALL", + "HONOR BALL", + "POTION", + "ANTIDOTE", + "ANTI-BRULE", + "ANTIGEL", + "REVEIL", + "ANTI-PARA", + "GUERISON", + "POTION MAX", + "HYPER POTION", + "SUPER POTION", + "TOTAL SOIN", + "RAPPEL", + "RAPPEL MAX", + "EAU FRAICHE", + "SODA COOL", + "LIMONADE", + "LAIT MEUMEU", + "POUDRENERGIE", + "RACINENERGIE", + "POUDRE SOIN", + "HERBE RAPPEL", + "HUILE", + "HUILE MAX", + "ELIXIR", + "MAX ELIXIR", + "LAVA COOKIE", + "FLUTE BLEUE", + "FLUTE JAUNE", + "FLUTE ROUGE", + "FLUTE NOIRE", + "FLUTEBLANCHE", + "JUS DE BAIE", + "CENDRESACREE", + "SEL TREFONDS", + "CO. TREFONDS", + "TESSON ROUGE", + "TESSON BLEU", + "TESSON JAUNE", + "TESSON VERT", + "PV PLUS", + "PROTEINE", + "FER", + "CARBONE", + "CALCIUM", + "SUPER BONBON", + "PP PLUS", + "ZINC", + "PP MAX", + "DEFENSE SPEC", + "MUSCLE +", + "ATTAQUE +", + "DEFENSE +", + "VITESSE +", + "PRECISION +", + "SPECIAL +", + "POK\xc3\xa9POUPEE", + "QUEUE SKITTY", + "SUPEREPOUSSE", + "MAX REPOUSSE", + "CORDE SORTIE", + "REPOUSSE", + "PIERRESOLEIL", + "PIERRE LUNE", + "PIERRE FEU", + "PIERREFOUDRE", + "PIERRE EAU", + "PIERREPLANTE", + "PETIT CHAMPI", + "GROS CHAMPI", + "PERLE", + "GRANDE PERLE", + "POUSS.ETOILE", + "MORC. ETOILE", + "PEPITE", + "ECAILLECOEUR", + "LETTRE ORANJ", + "LETTRE PORT", + "LETTRE BRILL", + "LETTRE MECA", + "LETTRE BOIS", + "LETTRE VAGUE", + "LETTRE BULLE", + "LETTRE OMBRE", + "LETTRE TROPI", + "LETTRE SONGE", + "LETTRE COOL", + "LETTRE RETRO", + "BAIE CERIZ", + "BAIE MARON", + "BAIE PECHA", + "BAIE FRAIVE", + "BAIE WILLIA", + "BAIE MEPO", + "BAIE ORAN", + "BAIE KIKA", + "BAIE PRINE", + "BAIE SITRUS", + "BAIE FIGUY", + "BAIE WIKI", + "BAIE MAGO", + "BAIE GOWAV", + "BAIE PAPAYA", + "BAIE FRAMBY", + "BAIE REMU", + "BAIE NANAB", + "BAIE REPOI", + "BAIE NANANA", + "BAIE GRENA", + "BAIE ALGA", + "BAIE QUALOT", + "BAIE LONME", + "BAIE RESIN", + "BAIE TAMATO", + "BAIE SIAM", + "BAIE MANGOU", + "BAIE RABUTA", + "BAIE TRONCI", + "BAIE KIWAN", + "BAIE PALMA", + "BAIE STEKPA", + "BAIE DURIN", + "BAIE MYRTE", + "BAIE LICHII", + "BAIE LINGAN", + "BAIE SAILAK", + "BAIE PITAYE", + "BAIE ABRIKO", + "BAIE LANSAT", + "BAIE FRISTA", + "BAIE ENIGMA", + "POUDRECLAIRE", + "HERBEBLANCHE", + "BRAC. MACHO", + "MULTI EXP", + "VIVE GRIFFE", + "GRELOT ZEN", + "HERBE MENTAL", + "BAND. CHOIX", + "ROCHE ROYALE", + "POUDRE ARG.", + "PIECE RUNE", + "RUNE PURIF.", + "ROSEE AME", + "DENT OCEAN", + "ECAILLEOCEAN", + "BOULE FUMEE", + "PIERRE STASE", + "BANDEAU", + "OEUF CHANCE", + "LENTILSCOPE", + "PEAU METAL", + "RESTES", + "ECAILLEDRACO", + "BALLELUMIERE", + "SABLE DOUX", + "PIERRE DURE", + "GRAIN MIRACL", + "LUNET.NOIRES", + "CEINT.NOIRE", + "AIMANT", + "EAU MYSTIQUE", + "BEC POINTU", + "PIC VENIN", + "GLACETERNEL", + "RUNE SORT", + "CUILLERTORDU", + "CHARBON", + "CROC DRAGON", + "MOUCH. SOIE", + "AMELIORATOR", + "GRELOT COQUE", + "ENCENS MER", + "ENCENS DOUX", + "POING CHANCE", + "POUDRE METAL", + "MASSE OS", + "BATON", + "FOUL. ROUGE", + "FOUL. BLEU", + "FOUL. ROSE", + "FOUL. VERT", + "FOUL. JAUNE", + "CT01", + "CT02", + "CT03", + "CT04", + "CT05", + "CT06", + "CT07", + "CT08", + "CT09", + "CT10", + "CT11", + "CT12", + "CT13", + "CT14", + "CT15", + "CT16", + "CT17", + "CT18", + "CT19", + "CT20", + "CT21", + "CT22", + "CT23", + "CT24", + "CT25", + "CT26", + "CT27", + "CT28", + "CT29", + "CT30", + "CT31", + "CT32", + "CT33", + "CT34", + "CT35", + "CT36", + "CT37", + "CT38", + "CT39", + "CT40", + "CT41", + "CT42", + "CT43", + "CT44", + "CT45", + "CT46", + "CT47", + "CT48", + "CT49", + "CT50" +}; + +const char *germanNames[245] = { + "(Nichts)", + "MEISTERBALL", + "HYPERBALL", + "SUPERBALL", + "POK\xC3\xA9""BALL", + "SAFARIBALL", + "NETZBALL", + "TAUCHBALL", + "NESTBALL", + "WIEDERBALL", + "TIMERBALL", + "LUXUSBALL", + "PREMIERBALL", + "TRANK", + "GEGENGIFT", + "FEUERHEILER", + "EISHEILER", + "AUFWECKER", + "PARA-HEILER", + "TOP-GENESUNG", + "TOP-TRANK", + "HYPERTRANK", + "SUPERTRANK", + "HYPERHEILER", + "BELEBER", + "TOP-BELEBER", + "TAFELWASSER", + "SPRUDEL", + "LIMONADE", + "KUHMUH-MILCH", + "ENERGIESTAUB", + "KRAFTWURZEL", + "HEILPUDER", + "VITALKRAUT", + "\xC3\x84THER", + "TOP-\xC3\x84THER", + "ELIXIER", + "TOP-ELIXIER", + "LAVAKEKS", + "BLAUE FL\xC3\x96TE", + "GELBE FL\xC3\x96TE", + "ROTE FL\xC3\x96TE", + "SCHWARZE FL\xC3\x96TE", + "WEISSE FL\xC3\x96TE", + "BEERENSAFT", + "ZAUBERASCHE", + "K\xC3\x9CSTENSALZ", + "K\xC3\x9CSTENSCHALE", + "PURPURST\xC3\x9C""CK", + "INDIGOST\xC3\x9C""CK", + "GELBST\xC3\x9C""CK", + "GR\xC3\x9CNST\xC3\x9C""CK", + "KP-PLUS", + "PROTEIN", + "EISEN", + "CARBON", + "KALZIUM", + "SONDERBONBON", + "AP-PLUS", + "ZINK", + "AP-TOP", + "MEGABLOCK", + "ANGRIFFPLUS", + "X-ANGRIFF", + "X-ABWEHR", + "X-TEMPO", + "X-TREFFER", + "X-SPEZIAL", + "POK\xC3\xA9PUPPE", + "ENECO-RUTE", + "SUPERSCHUTZ", + "TOP-SCHUTZ", + "FLUCHTSEIL", + "SCHUTZ", + "SONNENSTEIN", + "MONDSTEIN", + "FEUERSTEIN", + "DONNERSTEIN", + "WASSERSTEIN", + "BLATTSTEIN", + "MINIPILZ", + "RIESENPILZ", + "PERLE", + "RIESENPERLE", + "STERNENSTAUB", + "STERNENST\xC3\x9C""CK", + "NUGGET", + "HERZSCHUPPE", + "ZIGZAGBRIEF", + "HAFENBRIEF", + "GLITZERBRIEF", + "EILBRIEF", + "WALDBRIEF", + "WELLENBRIEF", + "PERLENBRIEF", + "DUNKELBRIEF", + "TROPENBRIEF", + "TRAUMBRIEF", + "EDELBRIEF", + "RETROBRIEF", + "AMRENABEERE", + "MARONBEERE", + "PIRSIFBEERE", + "FRAGIABEERE", + "WILBIRBEERE", + "JONAGOBEERE", + "SINELBEERE", + "PERSIMBEERE", + "PRUNUSBEERE", + "TSITRUBEERE", + "GIEFEBEERE", + "WIKIBEERE", + "MAGOBEERE", + "GAUVEBEERE", + "YAPABEERE", + "HIMMIHBEERE", + "MORBBEERE", + "NANABBEERE", + "NIRBEBEERE", + "SANANABEERE", + "GRANABEERE", + "SETANGBEERE", + "QUALOTBEERE", + "HONMELBEERE", + "LABRUSBEERE", + "TAMOTBEERE", + "SAIMBEERE", + "MAGOSTBEERE", + "RABUTABEERE", + "TRONZIBEERE", + "KIWANBEERE", + "PALLMBEERE", + "WASMELBEERE", + "DURINBEERE", + "MYRTILBEERE", + "LYDZIBEERE", + "LINGANBEERE", + "SALKABEERE", + "TAHAYBEERE", + "APIKOBEERE", + "LANSATBEERE", + "KRAMBOBEERE", + "ENIGMABEERE", + "BLENDPUDER", + "SCHLOHKRAUT", + "MACHOBAND", + "EP-TEILER", + "FLINKKLAUE", + "SANFTGLOCKE", + "MENTALKRAUT", + "WAHLBAND", + "KING-STEIN", + "SILBERSTAUB", + "M\xC3\x9CNZAMULETT", + "SCHUTZBAND", + "SEELENTAU", + "ABYSSZAHN", + "ABYSSPLATTE", + "RAUCHBALL", + "EWIGSTEIN", + "FOKUS-BAND", + "GL\xC3\x9C""CKS-EI", + "SCOPE-LINSE", + "METALLMANTEL", + "\xC3\x9C""BERRESTE", + "DRACHENHAUT", + "KUGELBLITZ", + "PUDERSAND", + "GRANITSTEIN", + "WUNDERSAAT", + "SCHATTENGLAS", + "SCHWARZGURT", + "MAGNET", + "ZAUBERWASSER", + "HACKATTACK", + "GIFTSTICH", + "EWIGES EIS", + "BANNSTICKER", + "KR\xC3\x9CMML\xC3\x96""FFEL", + "HOLZKOHLE", + "DRACHENZAHN", + "SEIDENSCHAL", + "UP-GRADE", + "SEEGESANG", + "SEERAUCH", + "LAXRAUCH", + "LUCKY PUNCH", + "METALLSTAUB", + "KAMPFKNOCHEN", + "LAUCHSTANGE", + "ROTER SCHAL", + "BLAUER SCHAL", + "ROSA SCHAL", + "GR\xC3\x9CNER SCHAL", + "GELBER SCHAL", + "TM01", + "TM02", + "TM03", + "TM04", + "TM05", + "TM06", + "TM07", + "TM08", + "TM09", + "TM10", + "TM11", + "TM12", + "TM13", + "TM14", + "TM15", + "TM16", + "TM17", + "TM18", + "TM19", + "TM20", + "TM21", + "TM22", + "TM23", + "TM24", + "TM25", + "TM26", + "TM27", + "TM28", + "TM29", + "TM30", + "TM31", + "TM32", + "TM33", + "TM34", + "TM35", + "TM36", + "TM37", + "TM38", + "TM39", + "TM40", + "TM41", + "TM42", + "TM43", + "TM44", + "TM45", + "TM46", + "TM47", + "TM48", + "TM49", + "TM50" +}; + +const char *italianNames[245] = { + "(Nessuno)", + "MASTER BALL", + "ULTRA BALL", + "MEGA BALL", + "POK\xC3\xA9 BALL", + "SAFARI BALL", + "RETE BALL", + "SUB BALL", + "MINOR BALL", + "BIS BALL", + "TIMER BALL", + "CHIC BALL", + "PREMIER BALL", + "POZIONE", + "ANTIDOTO", + "ANTISCOTTAT.", + "ANTIGELO", + "SVEGLIA", + "ANTIPARALISI", + "RICARICA TOT", + "POZIONE MAX", + "IPERPOZIONE", + "SUPERPOZIONE", + "CURA TOTALE", + "REVITALIZ.", + "REVITAL. MAX", + "ACQUA FRESCA", + "GASSOSA", + "LEMONSUCCO", + "LATTE MUMU", + "POLVENERGIA", + "RADICENERGIA", + "POLVOCURA", + "VITALERBA", + "ETERE", + "ETERE MAX", + "ELISIR", + "ELISIR MAX", + "LAVOTTINO", + "FLAUTO BLU", + "FLAUTO GIAL.", + "FLAUTO ROSSO", + "FLAUTO NERO", + "FLAUTO B.NCO", + "SUCCODIBACCA", + "CENEREMAGICA", + "SALE ONDOSO", + "GUSCIONDOSO", + "COCCIO ROSSO", + "COCCIO BLU", + "COCCIO GIAL.", + "COCCIO VERDE", + "PS-SU", + "PROTEINA", + "FERRO", + "CARBURANTE", + "CALCIO", + "CARAM. RARA", + "PP-SU", + "ZINCO", + "PP-MAX", + "SUPERGUARDIA", + "SUPERCOLPO", + "ATTACCO X", + "DIFESA X", + "VELOCIT\xC3\x80 X", + "PRECISIONE X", + "SPECIAL X", + "POK\xC3\xA9 BAMBOLA", + "CODA SKITTY", + "SUPERREPELL.", + "REPELL. MAX", + "FUNE DI FUGA", + "REPELLENTE", + "PIETRASOLARE", + "PIETRALUNARE", + "PIETRAFOCAIA", + "PIETRATUONO", + "PIETRAIDRICA", + "PIETRAFOGLIA", + "MINIFUNGO", + "GRANDE FUNGO", + "PERLA", + "GRANDE PERLA", + "POLVOSTELLA", + "PEZZO STELLA", + "PEPITA", + "SQUAMA CUORE", + "MESS. AGRUME", + "MESS. PORTO", + "MESS. LUCI", + "MESS. TECNO", + "MESS. BOSCO", + "MESS. ONDA", + "MESS. PERLE", + "MESS. OMBRA", + "MESS. TROPIC", + "MESS. SOGNO", + "MESS. LUSSO", + "MESS. R\xC3\x89TRO", + "BACCALIEGIA", + "BACCASTAGNA", + "BACCAPESCA", + "BACCAFRAGO", + "BACCAPERINA", + "BACCAMELA", + "BACCARANCIA", + "BACCAKI", + "BACCAPRUGNA", + "BACCACEDRO", + "BACCAFICO", + "BACCAKIWI", + "BACCAMANGO", + "BACCAGUAVA", + "BACCAPAIA", + "BACCALAMPON", + "BACCAMORA", + "BACCABANA", + "BACCAPERA", + "BACCANANAS", + "BACCAGRANA", + "BACCALGA", + "BACCALOQUAT", + "BACCAMELON", + "BACCAUVA", + "BACCAMODORO", + "BACCAVENA", + "BACCAGOSTAN", + "BACCAMBUTAN", + "BACCALEMON", + "BACCAMELOS", + "BACCAPALMA", + "BACCACOMERO", + "BACCADURIAN", + "BACCARTILLO", + "BACCALICI", + "BACCALONGAN", + "BACCASALAK", + "BACCAPITAYA", + "BACCACOCCA", + "BACCALANGSA", + "BACCAMBOLA", + "BACCAENIGMA", + "LUMINPOLVERE", + "ERBACHIARA", + "CRESCICAPPA", + "CONDIV. ESP.", + "RAPIDARTIGLI", + "CALMANELLA", + "MENTALERBA", + "BENDASCELTA", + "ROCCIA DI RE", + "ARGENPOLVERE", + "MONETAMULETO", + "VELOPURO", + "CUORUGIADA", + "DENTE ABISSI", + "SQUAMABISSI", + "PALLA FUMO", + "PIETRASTANTE", + "BANDANA", + "FORTUNUOVO", + "MIRINO", + "METALCOPERTA", + "AVANZI", + "SQUAMA DRAGO", + "ELETTROPALLA", + "SABBIA SOFF.", + "PIETRADURA", + "MIRACOLSEME", + "OCCHIALINERI", + "CINTURANERA", + "CALAMITA", + "ACQUA MAGICA", + "BECCAFFILATO", + "VELENACULEO", + "GELOMAI", + "SPETTROTARGA", + "CUCCH. TORTO", + "CARBONELLA", + "DENTEDIDRAGO", + "SCIARPA SETA", + "UPGRADE", + "CONCHINELLA", + "MAREAROMA", + "DISTRAROMA", + "FORTUNPUGNO", + "METALPOLVERE", + "OSSOSPESSO", + "GAMBO", + "FASCIA ROSSA", + "FASCIA BLU", + "FASCIA ROSA", + "FASCIA VERDE", + "FASCIA GIAL.", + "MT01", + "MT02", + "MT03", + "MT04", + "MT05", + "MT06", + "MT07", + "MT08", + "MT09", + "MT10", + "MT11", + "MT12", + "MT13", + "MT14", + "MT15", + "MT16", + "MT17", + "MT18", + "MT19", + "MT20", + "MT21", + "MT22", + "MT23", + "MT24", + "MT25", + "MT26", + "MT27", + "MT28", + "MT29", + "MT30", + "MT31", + "MT32", + "MT33", + "MT34", + "MT35", + "MT36", + "MT37", + "MT38", + "MT39", + "MT40", + "MT41", + "MT42", + "MT43", + "MT44", + "MT45", + "MT46", + "MT47", + "MT48", + "MT49", + "MT50" +}; + +const char *spanishNames[245] = { + "(Ninguno)", + "MASTER BALL", + "ULTRABALL", + "SUPERBALL", + "POK\xC3\xA9 BALL", + "SAFARI BALL", + "MALLA BALL", + "BUCEO BALL", + "NIDO BALL", + "ACOPIO BALL", + "TURNO BALL", + "LUJO BALL", + "HONOR BALL", + "POCI\xC3\x93N", + "ANT\xC3\x8D""DOTO", + "ANTIQUEMAR", + "ANTIHIELO", + "DESPERTAR", + "ANTIPARALIZ", + "RESTAU. TODO", + "M\xC3\x81X. POCI\xC3\x93N", + "HIPERPOCI\xC3\x93N", + "SUPERPOCI\xC3\x93N", + "CURA TOTAL", + "REVIVIR", + "M\xC3\x81X. REVIVIR", + "AGUA FRESCA", + "REFRESCO", + "LIMONADA", + "LECHE MU-MU", + "POLVOENERG\xC3\x8D""A", + "RA\xC3\x8DZ ENERG\xC3\x8D""A", + "POL.CURACI\xC3\x93N", + "HIERBA REV.", + "\xC3\x89TER", + "\xC3\x89TER M\xC3\x81X.", + "ELIXIR", + "ELIXIR M\xC3\x81X.", + "GALLETA LAVA", + "FLAUTA AZUL", + "FL. AMARILLA", + "FLAUTA ROJA", + "FLAUTA NEGRA", + "FL. BLANCA", + "ZUMO DE BAYA", + "CEN. SAGRADA", + "SAL CARDUMEN", + "C. CARDUMEN", + "PARTE ROJA", + "PARTE AZUL", + "P. AMARILLA", + "PARTE VERDE", + "M\xC3\x81S PS", + "PROTE\xC3\x8DNA", + "HIERRO", + "CARBURANTE", + "CALCIO", + "CARAMELORARO", + "M\xC3\x81S PP", + "ZINC", + "M\xC3\x81X. PP", + "PROTEC. ESP.", + "DIRECTO", + "ATAQUE X", + "DEFENSA X", + "VELOCIDAD X", + "PRECISI\xC3\x93N X", + "ESPECIAL X", + "POK\xC3\xA9 MU\xC3\x91""ECO", + "COLA SKITTY", + "SUPERREPEL", + "M\xC3\x81X. REPEL", + "CUERDA HUIDA", + "REPELENTE", + "PIEDRA SOLAR", + "PIEDRA LUNAR", + "PIEDRA FUEGO", + "PIEDRATRUENO", + "PIEDRA AGUA", + "PIEDRA HOJA", + "MINI SETA", + "SETA GRANDE", + "PERLA", + "PERLA GRANDE", + "POLVOESTELAR", + "TR. ESTRELLA", + "PEPITA", + "ESC. CORAZ\xC3\x93N", + "CAR. NARANJA", + "CARTA PUERTO", + "CARTA BRILLO", + "CARTA IM\xC3\x81N", + "CARTA MADERA", + "CARTA OLA", + "CARTA IMAGEN", + "CARTA SOMBRA", + "CAR. TROPIC.", + "CARTA SUE\xC3\x91O", + "CARTA FAB.", + "CARTA RETRO.", + "BAYA ZREZA", + "BAYA ATANIA", + "BAYA MELOC", + "BAYA SAFRE", + "BAYA PERASI", + "BAYA ZANAMA", + "BAYA ARANJA", + "BAYA CAQUIC", + "BAYA ZIUELA", + "BAYA ZIDRA", + "BAYA HIGOG", + "BAYA WIKI", + "BAYA ANGO", + "BAYA GUAYA", + "BAYA PABAYA", + "BAYA FRAMBU", + "BAYA ORAM", + "BAYA LATANO", + "BAYA PERAGU", + "BAYA PINIA", + "BAYA GRANA", + "BAYA ALGAMA", + "BAYA ISPERO", + "BAYA MELUCE", + "BAYA UVAV", + "BAYA TAMATE", + "BAYA MAIS", + "BAYA AOSTAN", + "BAYA RAUTAN", + "BAYA MONLI", + "BAYA WIKANO", + "BAYA PLAMA", + "BAYA SAMBIA", + "BAYA RUDION", + "BAYA ANDANO", + "BAYA LICHI", + "BAYA GONLAN", + "BAYA ASLAC", + "BAYA YAPATI", + "BAYA ARICOC", + "BAYA ZONLAN", + "BAYA ARABOL", + "BAYA ENIGMA", + "POLVO BRILLO", + "HIER. BLANCA", + "VESTIDURA", + "REPARTIR EXP", + "GARRA R\xC3\x81PIDA", + "CAMP. ALIVIO", + "HIER. MENTAL", + "CIN. ELEGIDA", + "ROCA DEL REY", + "POLVO PLATA", + "MON. AMULETO", + "AMULETO", + "ROC\xC3\x8DO BONDAD", + "DIENTE MAR.", + "ESCAMA MAR.", + "BOLA HUMO", + "PIEDRAETERNA", + "CINTA FOCUS", + "HUEVO SUERTE", + "PERISCOPIO", + "REV.MET\xC3\x81LICO", + "RESTOS", + "ESCAMADRAG\xC3\x93N", + "BOLALUMINOSA", + "ARENA FINA", + "PIEDRA DURA", + "SEM. MILAGRO", + "GAFAS DE SOL", + "CINT. NEGRO", + "IM\xC3\x81N", + "AGUA M\xC3\x8DSTICA", + "PICO AFILADO", + "FLECHA VEN.", + "ANTIDERRETIR", + "HECHIZO", + "CUCHARA TOR", + "CARB\xC3\x93N", + "COLMILLODRAG", + "PA\xC3\x91UELO SEDA", + "MEJORA", + "CAMP. CONCHA", + "INCIE. MAR.", + "INCIE. SUAVE", + "PU\xC3\x91O SUERTE", + "POL.MET\xC3\x81LICO", + "HUESO GRUESO", + "PALO", + "PA\xC3\x91UELO ROJO", + "PA\xC3\x91UELO AZUL", + "PA\xC3\x91UELO ROSA", + "PA\xC3\x91. VERDE", + "P. AMARILLO", + "MT01", + "MT02", + "MT03", + "MT04", + "MT05", + "MT06", + "MT07", + "MT08", + "MT09", + "MT10", + "MT11", + "MT12", + "MT13", + "MT14", + "MT15", + "MT16", + "MT17", + "MT18", + "MT19", + "MT20", + "MT21", + "MT22", + "MT23", + "MT24", + "MT25", + "MT26", + "MT27", + "MT28", + "MT29", + "MT30", + "MT31", + "MT32", + "MT33", + "MT34", + "MT35", + "MT36", + "MT37", + "MT38", + "MT39", + "MT40", + "MT41", + "MT42", + "MT43", + "MT44", + "MT45", + "MT46", + "MT47", + "MT48", + "MT49", + "MT50", +}; + +const char *japaneseNames[245] = { + "(\xe4\xbd\x95\xe3\x82\x82)", + "\xe3\x83\x9e\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb9\xe3\x83\xbc\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xa2\xe3\x83\xb3\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb5\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xaa\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x80\xe3\x82\xa4\xe3\x83\x96\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8d\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xaa\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x88\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\x9e\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb4\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa3\xe3\x82\xb9\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x97\xe3\x83\xac\xe3\x83\x9f\xe3\x82\xa2\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xad\xe3\x82\xba\xe3\x81\x90\xe3\x81\x99\xe3\x82\x8a", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x97", + "\xe3\x82\x84\xe3\x81\x91\xe3\x81\xa9\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\x97", + "\xe3\x81\x93\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\x97", + "\xe3\x81\xad\xe3\x82\x80\xe3\x81\x91\xe3\x81\x96\xe3\x81\xbe\xe3\x81\x97", + "\xe3\x81\xbe\xe3\x81\xb2\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\x97", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x81\xb5\xe3\x81\x8f\xe3\x81\xae\xe3\x81\x8f\xe3\x81\x99\xe3\x82\x8a", + "\xe3\x81\xbe\xe3\x82\x93\xe3\x81\x9f\xe3\x82\x93\xe3\x81\xae\xe3\x81\x8f\xe3\x81\x99\xe3\x82\x8a", + "\xe3\x81\x99\xe3\x81\x94\xe3\x81\x84\xe3\x82\xad\xe3\x82\xba\xe3\x81\x90\xe3\x81\x99\xe3\x82\x8a", + "\xe3\x81\x84\xe3\x81\x84\xe3\x82\xad\xe3\x82\xba\xe3\x81\x90\xe3\x81\x99\xe3\x82\x8a", + "\xe3\x81\xaa\xe3\x82\x93\xe3\x81\xa7\xe3\x82\x82\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\x97", + "\xe3\x81\x92\xe3\x82\x93\xe3\x81\x8d\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\x92\xe3\x82\x93\xe3\x81\x8d\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x9f\xe3\x81\xbe\xe3\x82\x8a", + "\xe3\x81\x8a\xe3\x81\x84\xe3\x81\x97\xe3\x81\x84\xe3\x81\xbf\xe3\x81\x9a", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xb3\xe3\x82\xbd\xe3\x83\xbc\xe3\x83\x80", + "\xe3\x83\x9f\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9\xe3\x82\xaa\xe3\x83\xac", + "\xe3\x83\xa2\xe3\x83\xbc\xe3\x83\xa2\xe3\x83\xbc\xe3\x83\x9f\xe3\x83\xab\xe3\x82\xaf", + "\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xae\xe3\x81\x93\xe3\x81\xaa", + "\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xae\xe3\x81\xad\xe3\x81\xa3\xe3\x81\x93", + "\xe3\x81\xb0\xe3\x82\x93\xe3\x81\xae\xe3\x81\x86\xe3\x81\x94\xe3\x81\xaa", + "\xe3\x81\xb5\xe3\x81\xa3\xe3\x81\x8b\xe3\x81\xa4\xe3\x81\x9d\xe3\x81\x86", + "\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x94\xe3\x83\xbc\xe3\x82\xa8\xe3\x82\xa4\xe3\x83\x89", + "\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x94\xe3\x83\xbc\xe3\x83\xaa\xe3\x82\xab\xe3\x83\x90\xe3\x83\xbc", + "\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x94\xe3\x83\xbc\xe3\x82\xa8\xe3\x82\xa4\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x9e\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9", + "\xe3\x83\x95\xe3\x82\xa8\xe3\x83\xb3\xe3\x81\x9b\xe3\x82\x93\xe3\x81\xb9\xe3\x81\x84", + "\xe3\x81\x82\xe3\x81\x8a\xe3\x81\x84\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xad", + "\xe3\x81\x8d\xe3\x81\x84\xe3\x82\x8d\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xad", + "\xe3\x81\x82\xe3\x81\x8b\xe3\x81\x84\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xad", + "\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\x84\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xad", + "\xe3\x81\x97\xe3\x82\x8d\xe3\x81\x84\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xad", + "\xe3\x81\x8d\xe3\x81\xae\xe3\x81\xbf\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x81\x9b\xe3\x81\x84\xe3\x81\xaa\xe3\x82\x8b\xe3\x81\xaf\xe3\x81\x84", + "\xe3\x81\x82\xe3\x81\x95\xe3\x81\x9b\xe3\x81\xae\xe3\x81\x97\xe3\x81\x8a", + "\xe3\x81\x82\xe3\x81\x95\xe3\x81\x9b\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x8c\xe3\x82\x89", + "\xe3\x81\x82\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\x82\xe3\x81\x8a\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\x8d\xe3\x81\x84\xe3\x82\x8d\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\xbf\xe3\x81\xa9\xe3\x82\x8a\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x83\x9e\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x97", + "\xe3\x82\xbf\xe3\x82\xa6\xe3\x83\xaa\xe3\x83\xb3", + "\xe3\x83\x96\xe3\x83\xad\xe3\x83\xa0\xe3\x83\x98\xe3\x82\xad\xe3\x82\xb7\xe3\x83\xb3", + "\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xa1\xe3\x82\xbf\xe3\x82\xb7\xe3\x83\xb3", + "\xe3\x83\xaa\xe3\x82\xbe\xe3\x83\x81\xe3\x82\xa6\xe3\x83\xa0", + "\xe3\x81\xb5\xe3\x81\x97\xe3\x81\x8e\xe3\x81\xaa\xe3\x82\xa2\xe3\x83\xa1", + "\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x97", + "\xe3\x82\xad\xe3\x83\x88\xe3\x82\xb5\xe3\x83\xb3", + "\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\xe3\x83\x9e\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9", + "\xe3\x82\xa8\xe3\x83\x95\xe3\x82\xa7\xe3\x82\xaf\xe3\x83\x88\xe3\x82\xac\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x82\xaf\xe3\x83\xaa\xe3\x83\x86\xe3\x82\xa3\xe3\x82\xab\xe3\x83\x83\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x83\x97\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\x91\xe3\x83\xaf\xe3\x83\xbc", + "\xe3\x83\x87\xe3\x82\xa3\xe3\x83\x95\xe3\x82\xa7\xe3\x83\xb3\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x82\xb9\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x83\xa8\xe3\x82\xaf\xe3\x82\xa2\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb9\xe3\x83\x9a\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\xab\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x97", + "\xe3\x83\x94\xe3\x83\x83\xe3\x83\x94\xe3\x81\xab\xe3\x82\x93\xe3\x81\x8e\xe3\x82\x87\xe3\x81\x86", + "\xe3\x82\xa8\xe3\x83\x8d\xe3\x82\xb3\xe3\x81\xae\xe3\x82\xb7\xe3\x83\x83\xe3\x83\x9d", + "\xe3\x82\xb7\xe3\x83\xab\xe3\x83\x90\xe3\x83\xbc\xe3\x82\xb9\xe3\x83\x97\xe3\x83\xac\xe3\x83\xbc", + "\xe3\x82\xb4\xe3\x83\xbc\xe3\x83\xab\xe3\x83\x89\xe3\x82\xb9\xe3\x83\x97\xe3\x83\xac\xe3\x83\xbc", + "\xe3\x81\x82\xe3\x81\xaa\xe3\x81\xac\xe3\x81\x91\xe3\x81\xae\xe3\x83\x92\xe3\x83\xa2", + "\xe3\x82\x80\xe3\x81\x97\xe3\x82\x88\xe3\x81\x91\xe3\x82\xb9\xe3\x83\x97\xe3\x83\xac\xe3\x83\xbc", + "\xe3\x81\x9f\xe3\x81\x84\xe3\x82\x88\xe3\x81\x86\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\xa4\xe3\x81\x8d\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\xbb\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\x8b\xe3\x81\xbf\xe3\x81\xaa\xe3\x82\x8a\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x95\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\xa1\xe3\x81\x84\xe3\x81\x95\xe3\x81\xaa\xe3\x82\xad\xe3\x83\x8e\xe3\x82\xb3", + "\xe3\x81\x8a\xe3\x81\x8a\xe3\x81\x8d\xe3\x81\xaa\xe3\x82\xad\xe3\x83\x8e\xe3\x82\xb3", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\x98\xe3\x82\x85", + "\xe3\x81\x8a\xe3\x81\x8a\xe3\x81\x8d\xe3\x81\xaa\xe3\x81\x97\xe3\x82\x93\xe3\x81\x98\xe3\x82\x85", + "\xe3\x81\xbb\xe3\x81\x97\xe3\x81\xae\xe3\x81\x99\xe3\x81\xaa", + "\xe3\x81\xbb\xe3\x81\x97\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\x8d\xe3\x82\x93\xe3\x81\xae\xe3\x81\x9f\xe3\x81\xbe", + "\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x88\xe3\x81\xae\xe3\x82\xa6\xe3\x83\xad\xe3\x82\xb3", + "\xe3\x82\xaa\xe3\x83\xac\xe3\x83\xb3\xe3\x82\xb8\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x90\xe3\x83\xbc\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xad\xe3\x83\xa9\xe3\x82\xad\xe3\x83\xa9\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xa1\xe3\x82\xab\xe3\x83\x8b\xe3\x82\xab\xe3\x83\xab\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xa6\xe3\x83\x83\xe3\x83\x87\xe3\x82\xa3\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xaf\xe3\x83\xad\xe3\x82\xb9\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x88\xe3\x83\xac\xe3\x82\xb8\xe3\x83\xa3\xe3\x83\xbc\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\x89\xe3\x83\xbc\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x88\xe3\x83\xad\xe3\x83\x94\xe3\x82\xab\xe3\x83\xab\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xa0\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x9f\xe3\x83\xa9\xe3\x82\xaf\xe3\x83\xab\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xac\xe3\x83\x88\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xaf\xe3\x83\xa9\xe3\x83\x9c\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xab\xe3\x82\xb4\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xa2\xe3\x83\xa2\xe3\x83\xb3\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x81\xe3\x83\xbc\xe3\x82\xb4\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8a\xe3\x83\x8a\xe3\x82\xb7\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x92\xe3\x83\xa1\xe3\x83\xaa\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xaa\xe3\x83\xac\xe3\x83\xb3\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xad\xe3\x83\xbc\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xa9\xe3\x83\xa0\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xaa\xe3\x83\x9c\xe3\x83\xb3\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xa9\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xa6\xe3\x82\xa4\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x9e\xe3\x82\xb4\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x90\xe3\x83\xb3\xe3\x82\xb8\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xa4\xe3\x82\xa2\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xba\xe3\x83\xaa\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x96\xe3\x83\xaa\xe3\x83\xbc\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8a\xe3\x83\x8a\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xbb\xe3\x82\xb7\xe3\x83\x8a\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x91\xe3\x82\xa4\xe3\x83\xab\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb6\xe3\x83\xad\xe3\x82\xaf\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8d\xe3\x82\xb3\xe3\x83\x96\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xbf\xe3\x83\x9d\xe3\x83\xab\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xad\xe3\x83\xa1\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xa6\xe3\x83\x96\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\x9e\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xa2\xe3\x82\xb3\xe3\x82\xb7\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb4\xe3\x82\xb9\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xa9\xe3\x83\x96\xe3\x82\xbf\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8e\xe3\x83\xa1\xe3\x83\xab\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8e\xe3\x83\xaf\xe3\x82\xad\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb7\xe3\x83\xbc\xe3\x83\xa4\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xab\xe3\x82\xa4\xe3\x82\xb9\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x89\xe3\x83\xaa\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x99\xe3\x83\xaa\xe3\x83\x96\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x81\xe3\x82\xa4\xe3\x83\xa9\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xaa\xe3\x83\xa5\xe3\x82\xac\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xab\xe3\x83\xa0\xe3\x83\xa9\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\xa4\xe3\x82\xbf\xe3\x83\x94\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xba\xe3\x82\xa2\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x83\x8a\xe3\x82\xbe\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x81\xb2\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\xae\xe3\x81\x93\xe3\x81\xaa", + "\xe3\x81\x97\xe3\x82\x8d\xe3\x81\x84\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x96", + "\xe3\x81\x8d\xe3\x82\x87\xe3\x81\x86\xe3\x81\x9b\xe3\x81\x84\xe3\x82\xae\xe3\x83\x97\xe3\x82\xb9", + "\xe3\x81\x8c\xe3\x81\x8f\xe3\x81\x97\xe3\x82\x85\xe3\x81\x86\xe3\x81\x9d\xe3\x81\x86\xe3\x81\xa1", + "\xe3\x81\x9b\xe3\x82\x93\xe3\x81\x9b\xe3\x81\x84\xe3\x81\xae\xe3\x83\x84\xe3\x83\xa1", + "\xe3\x82\x84\xe3\x81\x99\xe3\x82\x89\xe3\x81\x8e\xe3\x81\xae\xe3\x81\x99\xe3\x81\x9a", + "\xe3\x83\xa1\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xab\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x96", + "\xe3\x81\x93\xe3\x81\xa0\xe3\x82\x8f\xe3\x82\x8a\xe3\x83\x8f\xe3\x83\x81\xe3\x83\x9e\xe3\x82\xad", + "\xe3\x81\x8a\xe3\x81\x86\xe3\x81\x98\xe3\x82\x83\xe3\x81\xae\xe3\x81\x97\xe3\x82\x8b\xe3\x81\x97", + "\xe3\x81\x8e\xe3\x82\x93\xe3\x81\xae\xe3\x81\x93\xe3\x81\xaa", + "\xe3\x81\x8a\xe3\x81\xbe\xe3\x82\x82\xe3\x82\x8a\xe3\x81\x93\xe3\x81\xb0\xe3\x82\x93", + "\xe3\x81\x8d\xe3\x82\x88\xe3\x82\x81\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xb5\xe3\x81\xa0", + "\xe3\x81\x93\xe3\x81\x93\xe3\x82\x8d\xe3\x81\xae\xe3\x81\x97\xe3\x81\x9a\xe3\x81\x8f", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\x8b\xe3\x81\x84\xe3\x81\xae\xe3\x82\xad\xe3\x83\x90", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\x8b\xe3\x81\x84\xe3\x81\xae\xe3\x82\xa6\xe3\x83\xad\xe3\x82\xb3", + "\xe3\x81\x91\xe3\x82\x80\xe3\x82\x8a\xe3\x81\xa0\xe3\x81\xbe", + "\xe3\x81\x8b\xe3\x82\x8f\xe3\x82\x89\xe3\x81\x9a\xe3\x81\xae\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\x8d\xe3\x81\x82\xe3\x81\x84\xe3\x81\xae\xe3\x83\x8f\xe3\x83\x81\xe3\x83\x9e\xe3\x82\xad", + "\xe3\x81\x97\xe3\x81\x82\xe3\x82\x8f\xe3\x81\x9b\xe3\x82\xbf\xe3\x83\x9e\xe3\x82\xb4", + "\xe3\x83\x94\xe3\x83\xb3\xe3\x83\x88\xe3\x83\xac\xe3\x83\xb3\xe3\x82\xba", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\xab\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x81\x9f\xe3\x81\xb9\xe3\x81\xae\xe3\x81\x93\xe3\x81\x97", + "\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86\xe3\x81\xae\xe3\x82\xa6\xe3\x83\xad\xe3\x82\xb3", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x8d\xe3\x81\xa0\xe3\x81\xbe", + "\xe3\x82\x84\xe3\x82\x8f\xe3\x82\x89\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x99\xe3\x81\xaa", + "\xe3\x81\x8b\xe3\x81\x9f\xe3\x81\x84\xe3\x81\x84\xe3\x81\x97", + "\xe3\x81\x8d\xe3\x81\x9b\xe3\x81\x8d\xe3\x81\xae\xe3\x82\xbf\xe3\x83\x8d", + "\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\x84\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x8d", + "\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\x8a\xe3\x81\xb3", + "\xe3\x81\x98\xe3\x81\x97\xe3\x82\x83\xe3\x81\x8f", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\xb4\xe3\x81\xae\xe3\x81\x97\xe3\x81\x9a\xe3\x81\x8f", + "\xe3\x81\x99\xe3\x82\x8b\xe3\x81\xa9\xe3\x81\x84\xe3\x81\x8f\xe3\x81\xa1\xe3\x81\xb0\xe3\x81\x97", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x83\x90\xe3\x83\xaa", + "\xe3\x81\xa8\xe3\x81\x91\xe3\x81\xaa\xe3\x81\x84\xe3\x81\x93\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x81\xae\xe3\x82\x8d\xe3\x81\x84\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xb5\xe3\x81\xa0", + "\xe3\x81\xbe\xe3\x81\x8c\xe3\x81\xa3\xe3\x81\x9f\xe3\x82\xb9\xe3\x83\x97\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\x82\xe3\x81\x8f\xe3\x81\x9f\xe3\x82\x93", + "\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86\xe3\x81\xae\xe3\x82\xad\xe3\x83\x90", + "\xe3\x82\xb7\xe3\x83\xab\xe3\x82\xaf\xe3\x81\xae\xe3\x82\xb9\xe3\x82\xab\xe3\x83\xbc\xe3\x83\x95", + "\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x97\xe3\x82\xb0\xe3\x83\xac\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x8c\xe3\x82\x89\xe3\x81\xae\xe3\x81\x99\xe3\x81\x9a", + "\xe3\x81\x86\xe3\x81\x97\xe3\x81\x8a\xe3\x81\xae\xe3\x81\x8a\xe3\x81\x93\xe3\x81\x86", + "\xe3\x81\xae\xe3\x82\x93\xe3\x81\x8d\xe3\x81\xae\xe3\x81\x8a\xe3\x81\x93\xe3\x81\x86", + "\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xad\xe3\x83\xbc\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\xab\xe3\x83\x91\xe3\x82\xa6\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x81\xb5\xe3\x81\xa8\xe3\x81\x84\xe3\x83\x9b\xe3\x83\x8d", + "\xe3\x81\xaa\xe3\x81\x8c\xe3\x81\xad\xe3\x81\x8e", + "\xe3\x81\x82\xe3\x81\x8b\xe3\x81\x84\xe3\x83\x90\xe3\x83\xb3\xe3\x83\x80\xe3\x83\x8a", + "\xe3\x81\x82\xe3\x81\x8a\xe3\x81\x84\xe3\x83\x90\xe3\x83\xb3\xe3\x83\x80\xe3\x83\x8a", + "\xe3\x83\x94\xe3\x83\xb3\xe3\x82\xaf\xe3\x81\xae\xe3\x83\x90\xe3\x83\xb3\xe3\x83\x80\xe3\x83\x8a", + "\xe3\x81\xbf\xe3\x81\xa9\xe3\x82\x8a\xe3\x81\xae\xe3\x83\x90\xe3\x83\xb3\xe3\x83\x80\xe3\x83\x8a", + "\xe3\x81\x8d\xe3\x81\x84\xe3\x82\x8d\xe3\x81\xae\xe3\x83\x90\xe3\x83\xb3\xe3\x83\x80\xe3\x83\x8a", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x91", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x92", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x93", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x94", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x95", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x96", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x97", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x98", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x90\xef\xbc\x99", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x90", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x91", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x92", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x93", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x94", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x95", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x96", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x97", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x98", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x91\xef\xbc\x99", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x90", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x91", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x92", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x93", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x94", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x95", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x96", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x97", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x98", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x92\xef\xbc\x99", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x90", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x91", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x92", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x93", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x94", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x95", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x96", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x97", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x98", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x93\xef\xbc\x99", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x90", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x91", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x92", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x93", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x94", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x95", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x96", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x97", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x98", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x94\xef\xbc\x99", + "\xe3\x82\x8f\xe3\x81\x96\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xef\xbc\x95\xef\xbc\x90", +}; + +} + +namespace ColosseumExclusiveItems { + +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const char *englishNames[48] = { + "JAIL KEY", + "ELEVATOR KEY", + "SMALL TABLET", + "F-DISK", + "R-DISK", + "L-DISK", + "D-DISK", + "U-DISK", + "SUBWAY KEY", + "MAINGATE KEY", + "CARD KEY", + "DOWN ST. KEY", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DNA SAMPLE", + "DATA ROM", + "STEEL TEETH", + "GEAR", + "RED ID BADGE", + "GRN ID BADGE", + "BLU ID BADGE", + "YLW ID BADGE", + "TIME FLUTE", + "EIN FILE S", + "EIN FILE H", + "EIN FILE C", + "EIN FILE P", + "COLOGNE CASE", + "JOY SCENT", + "EXCITE SCENT", + "VIVID SCENT", + "POWERUP PART", + "EIN FILE F" +}; + +const char *frenchNames[48] = { + "CLE DE LA PRISON", + "CLE DE L'ASCENSEUR", + "ARDOISE", + "DISQUE-A", + "DISQUE-D", + "DISQUE-G", + "DISQUE-B", + "DISQUE-H", + "CLE DE CONTACT", + "CLE LABO", + "CLE MAGNETIQUE", + "CLE DU SOUS-SOL", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "ECHANTILLON ADN", + "DISQUE-ROM", + "DENTIER D'ACIER", + "ROUE DENTEE", + "PASSE ROUGE", + "PASSE VERT", + "PASSE BLEU", + "PASSE JAUNE", + "FLUTE DU TEMPS", + "DOSSIER TECK O", + "DOSSIER TECK H", + "DOSSIER TECK C", + "DOSSIER TECK P", + "BOITE A PARFUMS", + "P. DOUX", + "P. TONIFIANT", + "P. PALPITANT", + "AMPLIFICATEUR", + "DOSSIER TECK F", +}; + +const char *germanNames[48] = { + "ZELLENSCHL\xC3\x9CSSEL", + "LIFTSCHL\xC3\x9CSSEL", + "STEINTAFEL", + "V-DISC", + "R-DISC", + "L-DISC", + "U-DISC", + "O-DISC", + "ZUGSCHL\xC3\x9CSSEL", + "TORSCHL\xC3\x9CSSEL", + "SCHL\xC3\x9CSSELKARTE", + "UG-SCHL\xC3\x9CSSEL", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "DNS-PROBE", + "CD-ROM", + "ZAHNPROTHESE", + "ZAHNRAD", + "ROTE ID-MARKE", + "GR\xC3\x9CNE ID-MARKE", + "BLAUE ID-MARKE", + "GELBE ID-MARKE", + "ZEITFL\xC3\x96TE", + "CULPA-AKTE C-P", + "CULPA-AKTE F-M", + "CULPA-AKTE C", + "CULPA-AKTE C-E", + "ESSENZ-KISTE", + "FROH-E.", + "GL\xC3\x9C""CKS-E.", + "PARADIES-E.", + "ERSATZTEIL", + "CULPA-AKTE A-B", +}; + +const char *italianNames[48] = { + "CHIAVE CELLE", + "CHIAVE ASC.", + "TAVOLA", + "DISCO AVANTI", + "DISCO DX", + "DISCO SX", + "DISCO GI\xC3\x99", + "DISCO SU", + "CHIAVE METRO", + "CHIAVE CANC.", + "APRIPORTA", + "CHIAVE SOTT.", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "CAMPIONE DNA", + "SCHEDA DATI", + "DENTACCIAIO", + "INGRANAGGIO", + "PASS ROSSO", + "PASS VERDE", + "PASS BLU", + "PASS GIALLO", + "FLAUTO TEMPO", + "GENUS.FILE O", + "GENUS.FILE I", + "GENUS.FILE C", + "GENUS.FILE P", + "PORTAOLIO", + "OLIO DI PINO", + "OLIO DI ROSA", + "OLIO SUBLIME", + "ESPANSIONE", + "GENUS.FILE F", +}; + +const char *spanishNames[48] = { + "LLAVE CELDAS", + "LL. ASCENSOR", + "TABLILLA", + "DISCO A", + "DISCO D", + "DISCO I", + "DISCO B", + "DISCO S", + "LLAVE METRO", + "LL. ENTRADA", + "T. MAGN\xC3\x89TICA", + "LLAVE S\xC3\x93TANO", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "MUESTRA ADN", + "DISQUETE", + "DENTADURA", + "RUEDA", + "PASE ROJO", + "PASE VERDE", + "PASE AZUL", + "P. AMARILLO", + "FL. TIEMPO", + "PARTE EIN: O", + "PARTE EIN: H", + "PARTE EIN: C", + "PARTE EIN: P", + "CAJA AROMAS", + "AR. ALEGR\xC3\x8D""A", + "AR. EMOCI\xC3\x93N", + "AR. ENERG\xC3\x8D""A", + "POTENCIADOR", + "PARTE EIN: F", +}; + +const char *japaneseNames[48] = { + "\xe3\x82\x8d\xe3\x81\x86\xe3\x82\x84\xe3\x81\xae\xe3\x82\xab\xe3\x82\xae", + "\xe3\x82\xa8\xe3\x83\xac\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\xbc\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x81\xa1\xe3\x81\x84\xe3\x81\x95\xe3\x81\xaa\xe3\x81\x9b\xe3\x81\x8d\xe3\x81\xb0\xe3\x82\x93", + "\xef\xbc\xa6\xef\xbc\x8d\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf", + "\xef\xbc\xb2\xef\xbc\x8d\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf", + "\xef\xbc\xac\xef\xbc\x8d\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf", + "\xef\xbc\xa4\xef\xbc\x8d\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf", + "\xef\xbc\xb5\xef\xbc\x8d\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf", + "\xe3\x81\xa1\xe3\x81\x8b\xe3\x81\xa6\xe3\x81\xa4\xe3\x81\xae\xe3\x82\xab\xe3\x82\xae", + "\xe3\x83\xa1\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xb2\xe3\x83\xbc\xe3\x83\x88\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x83\xbc\xe3\x83\x89\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x81\xa1\xe3\x81\x8b\xe3\x81\xa4\xe3\x81\x86\xe3\x82\x8d\xe3\x81\xae\xe3\x82\xab\xe3\x82\xae", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xef\xbc\xa4\xef\xbc\xae\xef\xbc\xa1\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab", + "\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\xad\xe3\x83\xa0", + "\xe3\x81\xaf\xe3\x81\x8c\xe3\x81\xad\xe3\x81\xae\xe3\x81\x84\xe3\x82\x8c\xe3\x81\xb0", + "\xe3\x81\xaf\xe3\x81\x90\xe3\x82\x8b\xe3\x81\xbe", + "\xef\xbc\xa9\xef\xbc\xa4\xe3\x83\x90\xe3\x83\x83\xe3\x82\xb8\xe3\x81\x82\xe3\x81\x8b", + "\xef\xbc\xa9\xef\xbc\xa4\xe3\x83\x90\xe3\x83\x83\xe3\x82\xb8\xe3\x81\xbf\xe3\x81\xa9\xe3\x82\x8a", + "\xef\xbc\xa9\xef\xbc\xa4\xe3\x83\x90\xe3\x83\x83\xe3\x82\xb8\xe3\x81\x82\xe3\x81\x8a", + "\xef\xbc\xa9\xef\xbc\xa4\xe3\x83\x90\xe3\x83\x83\xe3\x82\xb8\xe3\x81\x8d\xe3\x81\x84\xe3\x82\x8d", + "\xe3\x81\xa8\xe3\x81\x8d\xe3\x81\xae\xe3\x81\xb5\xe3\x81\x88", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x82\xb0\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xef\xbc\xa4", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x82\xb0\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xef\xbc\xa8", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x82\xb0\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xef\xbc\xa3", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x82\xb0\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xef\xbc\xb2", + "\xe3\x82\xb3\xe3\x83\xad\xe3\x83\xb3\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\xab\xe3\x83\xb3\xe3\x83\xab\xe3\x83\xb3\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x83\xaf\xe3\x82\xaf\xe3\x83\xaf\xe3\x82\xaf\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x83\x89\xe3\x82\xad\xe3\x83\x89\xe3\x82\xad\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x81\x8d\xe3\x82\x87\xe3\x81\x86\xe3\x81\x8b\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x84", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x82\xb0\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xef\xbc\xa6", +}; + +} + +namespace XDExclusiveItems { +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const size_t namesByIndex[94] = { + 0,1,83,2,81,3,4,5,8,80,82,13,9,10,11,12,14,15,84,90,(size_t)-1, (size_t)-1, (size_t)-1, + 6,7,77,78,79,85,86,87,88,89,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 +}; +// + 0x1f4 +const char *englishNames[91] = { + "SAFE KEY", + "ELEVATOR KEY", + "MACHINE PART", + "DATA ROM", + "ID CARD", + "MUSIC DISC", + "KRANE MEMO 1", + "KRANE MEMO 2", + "SYSTEM LEVER", + "COLOGNE CASE", + "JOY SCENT", + "EXCITE SCENT", + "VIVID SCENT", + "POK\xc3\xa9 SNACK", + "SUN SHARD", + "MOON SHARD", + "DISC CASE", + "BATTLE CD 01", + "BATTLE CD 02", + "BATTLE CD 03", + "BATTLE CD 04", + "BATTLE CD 05", + "BATTLE CD 06", + "BATTLE CD 07", + "BATTLE CD 08", + "BATTLE CD 09", + "BATTLE CD 10", + "BATTLE CD 11", + "BATTLE CD 12", + "BATTLE CD 13", + "BATTLE CD 14", + "BATTLE CD 15", + "BATTLE CD 16", + "BATTLE CD 17", + "BATTLE CD 18", + "BATTLE CD 19", + "BATTLE CD 20", + "BATTLE CD 21", + "BATTLE CD 22", + "BATTLE CD 23", + "BATTLE CD 24", + "BATTLE CD 25", + "BATTLE CD 26", + "BATTLE CD 27", + "BATTLE CD 28", + "BATTLE CD 29", + "BATTLE CD 30", + "BATTLE CD 31", + "BATTLE CD 32", + "BATTLE CD 33", + "BATTLE CD 34", + "BATTLE CD 35", + "BATTLE CD 36", + "BATTLE CD 37", + "BATTLE CD 38", + "BATTLE CD 39", + "BATTLE CD 40", + "BATTLE CD 41", + "BATTLE CD 42", + "BATTLE CD 43", + "BATTLE CD 44", + "BATTLE CD 45", + "BATTLE CD 46", + "BATTLE CD 47", + "BATTLE CD 48", + "BATTLE CD 49", + "BATTLE CD 50", + "BATTLE CD 51", + "BATTLE CD 52", + "BATTLE CD 53", + "BATTLE CD 54", + "BATTLE CD 55", + "BATTLE CD 56", + "BATTLE CD 57", + "BATTLE CD 58", + "BATTLE CD 59", + "BATTLE CD 60", + "KRANE MEMO 3", + "KRANE MEMO 4", + "KRANE MEMO 5", + "MAYOR'S NOTE", + //"OUTPUT LIST", + "GONZAP'S KEY", + "MIROR RADAR", + "BONSLY CARD", + "BONSLY PHOTO", + "VOICE CASE 1", + "VOICE CASE 2", + "VOICE CASE 3", + "VOICE CASE 4", + "VOICE CASE 5", + "CRY ANALYZER", +}; + +const char *frenchNames[] = { + "CLE COFFRE", + "CLE ASCENS.", + "PIECE MECA.", + "DISQUE-ROM", + "BADGE", + "CD MUSIQUE", + "MEMO SYRUS 1", + "MEMO SYRUS 2", + "LEVIER", + "BOITE A PARFUMS", + "P. DOUX", + "P. TONIFIANT", + "P. PALPITANT", + "POK\xc3\xa9 SNACK", + "ECLAT SOLEIL", + "ECLAT LUNE", + "BOITE HOLOG.", + "HOLODISK 01", + "HOLODISK 02", + "HOLODISK 03", + "HOLODISK 04", + "HOLODISK 05", + "HOLODISK 06", + "HOLODISK 07", + "HOLODISK 08", + "HOLODISK 09", + "HOLODISK 10", + "HOLODISK 11", + "HOLODISK 12", + "HOLODISK 13", + "HOLODISK 14", + "HOLODISK 15", + "HOLODISK 16", + "HOLODISK 17", + "HOLODISK 18", + "HOLODISK 19", + "HOLODISK 20", + "HOLODISK 21", + "HOLODISK 22", + "HOLODISK 23", + "HOLODISK 24", + "HOLODISK 25", + "HOLODISK 26", + "HOLODISK 27", + "HOLODISK 28", + "HOLODISK 29", + "HOLODISK 30", + "HOLODISK 31", + "HOLODISK 32", + "HOLODISK 33", + "HOLODISK 34", + "HOLODISK 35", + "HOLODISK 36", + "HOLODISK 37", + "HOLODISK 38", + "HOLODISK 39", + "HOLODISK 40", + "HOLODISK 41", + "HOLODISK 42", + "HOLODISK 43", + "HOLODISK 44", + "HOLODISK 45", + "HOLODISK 46", + "HOLODISK 47", + "HOLODISK 48", + "HOLODISK 49", + "HOLODISK 50", + "HOLODISK 51", + "HOLODISK 52", + "HOLODISK 53", + "HOLODISK 54", + "HOLODISK 55", + "HOLODISK 56", + "HOLODISK 57", + "HOLODISK 58", + "HOLODISK 59", + "HOLODISK 60", + "MEMO SYRUS 3", + "MEMO SYRUS 4", + "MEMO SYRUS 5", + "LETTRE MAIRE", + "CLE HELGONZA", + "RADAR DISCO", + "CARTE MANZAI", + "PHOTO MANZAI", + "BOITE CRI 1", + "BOITE CRI 2", + "BOITE CRI 3", + "BOITE CRI 4", + "BOITE CRI 5", + "DECODEUR CRI", +}; + +const char *germanNames[91] = { + "SAFE\xC3\x96""FFNER", + "LIFTKARTE", + "ERSATZTEIL", + "CD-ROM", + "ID-KARTE", + "MUSIK-CD", + "KLEIN-MEMO 1", + "KLEIN-MEMO 2", + "SYSTEMHEBEL", + "ESSENZ-KISTE", + "FROH-E.", + "GL\xC3\x9C""CKS-E.", + "PARADIES-E.", + "POK\xC3\xA9SNACK", + "SONNSPLITTER", + "MONDSPLITTER", + "CD-BOX", + "KAMPF-CD 01", + "KAMPF-CD 02", + "KAMPF-CD 03", + "KAMPF-CD 04", + "KAMPF-CD 05", + "KAMPF-CD 06", + "KAMPF-CD 07", + "KAMPF-CD 08", + "KAMPF-CD 09", + "KAMPF-CD 10", + "KAMPF-CD 11", + "KAMPF-CD 12", + "KAMPF-CD 13", + "KAMPF-CD 14", + "KAMPF-CD 15", + "KAMPF-CD 16", + "KAMPF-CD 17", + "KAMPF-CD 18", + "KAMPF-CD 19", + "KAMPF-CD 20", + "KAMPF-CD 21", + "KAMPF-CD 22", + "KAMPF-CD 23", + "KAMPF-CD 24", + "KAMPF-CD 25", + "KAMPF-CD 26", + "KAMPF-CD 27", + "KAMPF-CD 28", + "KAMPF-CD 29", + "KAMPF-CD 30", + "KAMPF-CD 31", + "KAMPF-CD 32", + "KAMPF-CD 33", + "KAMPF-CD 34", + "KAMPF-CD 35", + "KAMPF-CD 36", + "KAMPF-CD 37", + "KAMPF-CD 38", + "KAMPF-CD 39", + "KAMPF-CD 40", + "KAMPF-CD 41", + "KAMPF-CD 42", + "KAMPF-CD 43", + "KAMPF-CD 44", + "KAMPF-CD 45", + "KAMPF-CD 46", + "KAMPF-CD 47", + "KAMPF-CD 48", + "KAMPF-CD 49", + "KAMPF-CD 50", + "KAMPF-CD 51", + "KAMPF-CD 52", + "KAMPF-CD 53", + "KAMPF-CD 54", + "KAMPF-CD 55", + "KAMPF-CD 56", + "KAMPF-CD 57", + "KAMPF-CD 58", + "KAMPF-CD 59", + "KAMPF-CD 60", + "KLEIN-MEMO 3", + "KLEIN-MEMO 4", + "KLEIN-MEMO 5", + "ZETTEL", + "SCHL\xC3\x9CSSEL", + "QUEEN-RADAR", + "MOBAI-KARTE", + "MOBAI-FOTO", + "STIMMBOX 1", + "STIMMBOX 2", + "STIMMBOX 3", + "STIMMBOX 4", + "STIMMBOX 5", + "STIMMKENNER", +}; + +const char *italianNames[91] = { + "CHIAVE FORZIERE", + "CHIAVE ASC.", + "MECCANISMO", + "CD ROM", + "TESSERA", + "CD MUSICALE", + "APPUNTI 1", + "APPUNTI 2", + "LEVA", + "PORTAOLIO", + "OLIO di PINO", + "OLIO di ROSA", + "OLIO SUBLIME", + "POK\xC3\xA9 SNACK", + "SCHEGGIASOLE", + "SCHEGGIALUNA", + "PORTA-CD", + "CD LOTTA 01", + "CD LOTTA 02", + "CD LOTTA 03", + "CD LOTTA 04", + "CD LOTTA 05", + "CD LOTTA 06", + "CD LOTTA 07", + "CD LOTTA 08", + "CD LOTTA 09", + "CD LOTTA 10", + "CD LOTTA 11", + "CD LOTTA 12", + "CD LOTTA 13", + "CD LOTTA 14", + "CD LOTTA 15", + "CD LOTTA 16", + "CD LOTTA 17", + "CD LOTTA 18", + "CD LOTTA 19", + "CD LOTTA 20", + "CD LOTTA 21", + "CD LOTTA 22", + "CD LOTTA 23", + "CD LOTTA 24", + "CD LOTTA 25", + "CD LOTTA 26", + "CD LOTTA 27", + "CD LOTTA 28", + "CD LOTTA 29", + "CD LOTTA 30", + "CD LOTTA 31", + "CD LOTTA 32", + "CD LOTTA 33", + "CD LOTTA 34", + "CD LOTTA 35", + "CD LOTTA 36", + "CD LOTTA 37", + "CD LOTTA 38", + "CD LOTTA 39", + "CD LOTTA 40", + "CD LOTTA 41", + "CD LOTTA 42", + "CD LOTTA 43", + "CD LOTTA 44", + "CD LOTTA 45", + "CD LOTTA 46", + "CD LOTTA 47", + "CD LOTTA 48", + "CD LOTTA 49", + "CD LOTTA 50", + "CD LOTTA 51", + "CD LOTTA 52", + "CD LOTTA 53", + "CD LOTTA 54", + "CD LOTTA 55", + "CD LOTTA 56", + "CD LOTTA 57", + "CD LOTTA 58", + "CD LOTTA 59", + "CD LOTTA 60", + "APPUNTI 3", + "APPUNTI 4", + "APPUNTI 5", + "NOTA SINDACO", + "CHIAVE HELG.", + "DISCORADAR", + "SCHEDA BONSLY", + "FOTO BONSLY", + "DISCO VERSO 1", + "DISCO VERSO 2", + "DISCO VERSO 3", + "DISCO VERSO 4", + "DISCO VERSO 5", + "ANALIZ.VERSO" +}; + +const char *spanishNames[91] = { + "LLAVE CAJA", + "LL. ASCENSOR", + "PIEZA ESP.", + "DISQUETE", + "TARJETA ID", + "DISCO M\xC3\x9ASICA", + "PARTE C\xC3\x8DO 1", + "PARTE C\xC3\x8DO 2", + "PALANCA", + "CAJA AROMAS", + "AR. ALEGR\xC3\x8D""A", + "AR. EMOCI\xC3\x93N", + "AR. ENERG\xC3\x8D""A", + "POK\xC3\xA9 DULCE", + "\xC3\x81PICE SOL", + "\xC3\x81PICE LUNA", + "CAJA DISCOS", + "DISCO C. 1", + "DISCO C. 2", + "DISCO C. 3", + "DISCO C. 4", + "DISCO C. 5", + "DISCO C. 6", + "DISCO C. 7", + "DISCO C. 8", + "DISCO C. 9", + "DISCO C. 10", + "DISCO C. 11", + "DISCO C. 12", + "DISCO C. 13", + "DISCO C. 14", + "DISCO C. 15", + "DISCO C. 16", + "DISCO C. 17", + "DISCO C. 18", + "DISCO C. 19", + "DISCO C. 20", + "DISCO C. 21", + "DISCO C. 22", + "DISCO C. 23", + "DISCO C. 24", + "DISCO C. 25", + "DISCO C. 26", + "DISCO C. 27", + "DISCO C. 28", + "DISCO C. 29", + "DISCO C. 30", + "DISCO C. 31", + "DISCO C. 32", + "DISCO C. 33", + "DISCO C. 34", + "DISCO C. 35", + "DISCO C. 36", + "DISCO C. 37", + "DISCO C. 38", + "DISCO C. 39", + "DISCO C. 40", + "DISCO C. 41", + "DISCO C. 42", + "DISCO C. 43", + "DISCO C. 44", + "DISCO C. 45", + "DISCO C. 46", + "DISCO C. 47", + "DISCO C. 48", + "DISCO C. 49", + "DISCO C. 50", + "DISCO C. 51", + "DISCO C. 52", + "DISCO C. 53", + "DISCO C. 54", + "DISCO C. 55", + "DISCO C. 56", + "DISCO C. 57", + "DISCO C. 58", + "DISCO C. 59", + "DISCO C. 60", + "PARTE C\xC3\x8DO 3", + "PARTE C\xC3\x8DO 4", + "PARTE C\xC3\x8DO 5", + "NOTA ALCALDE", + "LLAVE GOLKA", + "RADAR DISCAL", + "CART. BONSLY", + "FOTO BONSLY", + "GRABACI\xC3\x93N 1", + "GRABACI\xC3\x93N 2", + "GRABACI\xC3\x93N 3", + "GRABACI\xC3\x93N 4", + "GRABACI\xC3\x93N 5", + "GRITOLECTOR", +}; + +const char *japaneseNames[91] = { + "\xe3\x81\x8d\xe3\x82\x93\xe3\x81\x93\xe3\x81\xae\xe3\x82\xab\xe3\x82\xae", + "\xe3\x82\xa8\xe3\x83\xac\xe3\x83\x99\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\xbc\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x84", + "\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x83\xad\xe3\x83\xa0", + "\xe2\x85\xa0\xef\xbc\xa4\xe3\x82\xab\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x81\x8a\xe3\x82\x93\xe3\x81\x8c\xe3\x81\x8f\xe3\x82\xbd\xe3\x83\x95\xe3\x83\x88", + "\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xa2\xef\xbc\x91", + "\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xa2\xef\xbc\x92", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x98\xe3\x82\x87\xe3\x83\xac\xe3\x83\x90\xe3\x83\xbc", + "\xe3\x82\xb3\xe3\x83\xad\xe3\x83\xb3\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\xab\xe3\x83\xb3\xe3\x83\xab\xe3\x83\xb3\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x83\xaf\xe3\x82\xaf\xe3\x83\xaf\xe3\x82\xaf\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x83\x89\xe3\x82\xad\xe3\x83\x89\xe3\x82\xad\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x83\x9d\xe3\x82\xb1\xe3\x81\xbe\xe3\x82\x93\xe3\x81\xbe", + "\xe3\x81\x9f\xe3\x81\x84\xe3\x82\x88\xe3\x81\x86\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x81\xa4\xe3\x81\x8d\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x91\xe3\x82\x89", + "\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x90\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x90", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x91\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x90", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x92\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x90", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x93\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x90", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x94\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x90", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x91", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x92", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x93", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x94", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x95", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x96", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x97", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x98", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x95\xef\xbc\x99", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb9\xe3\x82\xaf\xef\xbc\x96\xef\xbc\x90", + "\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xa2\xef\xbc\x93", + "\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xa2\xef\xbc\x94", + "\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xa2\xef\xbc\x95", + "\xe3\x81\x97\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x86\xe3\x81\xae\xe3\x81\xa6\xe3\x81\x8c\xe3\x81\xbf", + "\xe3\x82\xb4\xe3\x83\xb3\xe3\x82\xb6\xe3\x81\xae\xe3\x82\xab\xe3\x82\xae", + "\xe3\x83\x9f\xe3\x83\xa9\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xac\xe3\x83\xbc\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x82\xa6\xe3\x82\xbd\xe3\x83\x8f\xe3\x83\x81\xe3\x82\xb7\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x82\xa6\xe3\x82\xbd\xe3\x83\x8f\xe3\x83\x81\xe3\x83\xbb\xe3\x83\x95\xe3\x82\xa9\xe3\x83\x88", + "\xe3\x81\x93\xe3\x81\x88\xe3\x82\xab\xe3\x83\x97\xe3\x82\xbb\xe3\x83\xab\xef\xbc\x91", + "\xe3\x81\x93\xe3\x81\x88\xe3\x82\xab\xe3\x83\x97\xe3\x82\xbb\xe3\x83\xab\xef\xbc\x92", + "\xe3\x81\x93\xe3\x81\x88\xe3\x82\xab\xe3\x83\x97\xe3\x82\xbb\xe3\x83\xab\xef\xbc\x93", + "\xe3\x81\x93\xe3\x81\x88\xe3\x82\xab\xe3\x83\x97\xe3\x82\xbb\xe3\x83\xab\xef\xbc\x94", + "\xe3\x81\x93\xe3\x81\x88\xe3\x82\xab\xe3\x83\x97\xe3\x82\xbb\xe3\x83\xab\xef\xbc\x95", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\x9d\xe3\x81\x86\xe3\x81\xa1", + +}; + +} +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Core/Detail/MoveNames.cpp b/LibPkmGC/src/LibPkmGC/Core/Detail/MoveNames.cpp new file mode 100644 index 0000000..b7198c3 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Detail/MoveNames.cpp @@ -0,0 +1,2163 @@ +#include + + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Moves { +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const char *englishNames[355] = { + "(None)", + "POUND", + "KARATE CHOP", + "DOUBLESLAP", + "COMET PUNCH", + "MEGA PUNCH", + "PAY DAY", + "FIRE PUNCH", + "ICE PUNCH", + "THUNDERPUNCH", + "SCRATCH", + "VICEGRIP", + "GUILLOTINE", + "RAZOR WIND", + "SWORDS DANCE", + "CUT", + "GUST", + "WING ATTACK", + "WHIRLWIND", + "FLY", + "BIND", + "SLAM", + "VINE WHIP", + "STOMP", + "DOUBLE KICK", + "MEGA KICK", + "JUMP KICK", + "ROLLING KICK", + "SAND-ATTACK", + "HEADBUTT", + "HORN ATTACK", + "FURY ATTACK", + "HORN DRILL", + "TACKLE", + "BODY SLAM", + "WRAP", + "TAKE DOWN", + "THRASH", + "DOUBLE-EDGE", + "TAIL WHIP", + "POISON STING", + "TWINEEDLE", + "PIN MISSILE", + "LEER", + "BITE", + "GROWL", + "ROAR", + "SING", + "SUPERSONIC", + "SONICBOOM", + "DISABLE", + "ACID", + "EMBER", + "FLAMETHROWER", + "MIST", + "WATER GUN", + "HYDRO PUMP", + "SURF", + "ICE BEAM", + "BLIZZARD", + "PSYBEAM", + "BUBBLEBEAM", + "AURORA BEAM", + "HYPER BEAM", + "PECK", + "DRILL PECK", + "SUBMISSION", + "LOW KICK", + "COUNTER", + "SEISMIC TOSS", + "STRENGTH", + "ABSORB", + "MEGA DRAIN", + "LEECH SEED", + "GROWTH", + "RAZOR LEAF", + "SOLARBEAM", + "POISONPOWDER", + "STUN SPORE", + "SLEEP POWDER", + "PETAL DANCE", + "STRING SHOT", + "DRAGON RAGE", + "FIRE SPIN", + "THUNDERSHOCK", + "THUNDERBOLT", + "THUNDER WAVE", + "THUNDER", + "ROCK THROW", + "EARTHQUAKE", + "FISSURE", + "DIG", + "TOXIC", + "CONFUSION", + "PSYCHIC", + "HYPNOSIS", + "MEDITATE", + "AGILITY", + "QUICK ATTACK", + "RAGE", + "TELEPORT", + "NIGHT SHADE", + "MIMIC", + "SCREECH", + "DOUBLE TEAM", + "RECOVER", + "HARDEN", + "MINIMIZE", + "SMOKESCREEN", + "CONFUSE RAY", + "WITHDRAW", + "DEFENSE CURL", + "BARRIER", + "LIGHT SCREEN", + "HAZE", + "REFLECT", + "FOCUS ENERGY", + "BIDE", + "METRONOME", + "MIRROR MOVE", + "SELFDESTRUCT", + "EGG BOMB", + "LICK", + "SMOG", + "SLUDGE", + "BONE CLUB", + "FIRE BLAST", + "WATERFALL", + "CLAMP", + "SWIFT", + "SKULL BASH", + "SPIKE CANNON", + "CONSTRICT", + "AMNESIA", + "KINESIS", + "SOFTBOILED", + "HI JUMP KICK", + "GLARE", + "DREAM EATER", + "POISON GAS", + "BARRAGE", + "LEECH LIFE", + "LOVELY KISS", + "SKY ATTACK", + "TRANSFORM", + "BUBBLE", + "DIZZY PUNCH", + "SPORE", + "FLASH", + "PSYWAVE", + "SPLASH", + "ACID ARMOR", + "CRABHAMMER", + "EXPLOSION", + "FURY SWIPES", + "BONEMERANG", + "REST", + "ROCK SLIDE", + "HYPER FANG", + "SHARPEN", + "CONVERSION", + "TRI ATTACK", + "SUPER FANG", + "SLASH", + "SUBSTITUTE", + "STRUGGLE", + "SKETCH", + "TRIPLE KICK", + "THIEF", + "SPIDER WEB", + "MIND READER", + "NIGHTMARE", + "FLAME WHEEL", + "SNORE", + "CURSE", + "FLAIL", + "CONVERSION 2", + "AEROBLAST", + "COTTON SPORE", + "REVERSAL", + "SPITE", + "POWDER SNOW", + "PROTECT", + "MACH PUNCH", + "SCARY FACE", + "FAINT ATTACK", + "SWEET KISS", + "BELLY DRUM", + "SLUDGE BOMB", + "MUD-SLAP", + "OCTAZOOKA", + "SPIKES", + "ZAP CANNON", + "FORESIGHT", + "DESTINY BOND", + "PERISH SONG", + "ICY WIND", + "DETECT", + "BONE RUSH", + "LOCK-ON", + "OUTRAGE", + "SANDSTORM", + "GIGA DRAIN", + "ENDURE", + "CHARM", + "ROLLOUT", + "FALSE SWIPE", + "SWAGGER", + "MILK DRINK", + "SPARK", + "FURY CUTTER", + "STEEL WING", + "MEAN LOOK", + "ATTRACT", + "SLEEP TALK", + "HEAL BELL", + "RETURN", + "PRESENT", + "FRUSTRATION", + "SAFEGUARD", + "PAIN SPLIT", + "SACRED FIRE", + "MAGNITUDE", + "DYNAMICPUNCH", + "MEGAHORN", + "DRAGONBREATH", + "BATON PASS", + "ENCORE", + "PURSUIT", + "RAPID SPIN", + "SWEET SCENT", + "IRON TAIL", + "METAL CLAW", + "VITAL THROW", + "MORNING SUN", + "SYNTHESIS", + "MOONLIGHT", + "HIDDEN POWER", + "CROSS CHOP", + "TWISTER", + "RAIN DANCE", + "SUNNY DAY", + "CRUNCH", + "MIRROR COAT", + "PSYCH UP", + "EXTREMESPEED", + "ANCIENTPOWER", + "SHADOW BALL", + "FUTURE SIGHT", + "ROCK SMASH", + "WHIRLPOOL", + "BEAT UP", + "FAKE OUT", + "UPROAR", + "STOCKPILE", + "SPIT UP", + "SWALLOW", + "HEAT WAVE", + "HAIL", + "TORMENT", + "FLATTER", + "WILL-O-WISP", + "MEMENTO", + "FACADE", + "FOCUS PUNCH", + "SMELLINGSALT", + "FOLLOW ME", + "NATURE POWER", + "CHARGE", + "TAUNT", + "HELPING HAND", + "TRICK", + "ROLE PLAY", + "WISH", + "ASSIST", + "INGRAIN", + "SUPERPOWER", + "MAGIC COAT", + "RECYCLE", + "REVENGE", + "BRICK BREAK", + "YAWN", + "KNOCK OFF", + "ENDEAVOR", + "ERUPTION", + "SKILL SWAP", + "IMPRISON", + "REFRESH", + "GRUDGE", + "SNATCH", + "SECRET POWER", + "DIVE", + "ARM THRUST", + "CAMOUFLAGE", + "TAIL GLOW", + "LUSTER PURGE", + "MIST BALL", + "FEATHERDANCE", + "TEETER DANCE", + "BLAZE KICK", + "MUD SPORT", + "ICE BALL", + "NEEDLE ARM", + "SLACK OFF", + "HYPER VOICE", + "POISON FANG", + "CRUSH CLAW", + "BLAST BURN", + "HYDRO CANNON", + "METEOR MASH", + "ASTONISH", + "WEATHER BALL", + "AROMATHERAPY", + "FAKE TEARS", + "AIR CUTTER", + "OVERHEAT", + "ODOR SLEUTH", + "ROCK TOMB", + "SILVER WIND", + "METAL SOUND", + "GRASSWHISTLE", + "TICKLE", + "COSMIC POWER", + "WATER SPOUT", + "SIGNAL BEAM", + "SHADOW PUNCH", + "EXTRASENSORY", + "SKY UPPERCUT", + "SAND TOMB", + "SHEER COLD", + "MUDDY WATER", + "BULLET SEED", + "AERIAL ACE", + "ICICLE SPEAR", + "IRON DEFENSE", + "BLOCK", + "HOWL", + "DRAGON CLAW", + "SOLID PLANT", + "BULK UP", + "BOUNCE", + "MUD SHOT", + "POISON TAIL", + "COVET", + "VOLT TACKLE", + "MAGICAL LEAF", + "WATER SPORT", + "CALM MIND", + "LEAF BLADE", + "DRAGON DANCE", + "ROCK BLAST", + "SHOCK WAVE", + "WATER PULSE", + "DOOM DESIRE", + "PSYCHO BOOST" +}; + +const char *frenchNames[355] = { + "(Rien)", + "ECRAS'FACE", + "POING-KARATE", + "TORGNOLES", + "POING COMETE", + "ULTIMAPOING", + "JACKPOT", + "POING DE FEU", + "POINGLACE", + "POING-ECLAIR", + "GRIFFE", + "FORCE POIGNE", + "GUILLOTINE", + "COUPE-VENT", + "DANSE-LAMES", + "COUPE", + "TORNADE", + "CRU-AILE", + "CYCLONE", + "VOL", + "ETREINTE", + "SOUPLESSE", + "FOUET LIANES", + "ECRASEMENT", + "DOUBLE PIED", + "ULTIMAWASHI", + "PIED SAUTE", + "MAWASHI GERI", + "JET DE SABLE", + "COUP D'BOULE", + "KOUD'KORNE", + "FURIE", + "EMPAL'KORNE", + "CHARGE", + "PLAQUAGE", + "LIGOTAGE", + "BELIER", + "MANIA", + "DAMOCLES", + "MIMI-QUEUE", + "DARD-VENIN", + "DOUBLE-DARD", + "DARD-NUEE", + "GROZ'YEUX", + "MORSURE", + "RUGISSEMENT", + "HURLEMENT", + "BERCEUSE", + "ULTRASON", + "SONICBOOM", + "ENTRAVE", + "ACIDE", + "FLAMMECHE", + "LANCE-FLAMME", + "BRUME", + "PISTOLET A O", + "HYDROCANON", + "SURF", + "LASER GLACE", + "BLIZZARD", + "RAFALE PSY", + "BULLES D'O", + "ONDE BOREALE", + "ULTRALASER", + "PICPIC", + "BEC VRILLE", + "SACRIFICE", + "BALAYAGE", + "RIPOSTE", + "FRAPPE ATLAS", + "FORCE", + "VOL-VIE", + "MEGA-SANGSUE", + "VAMPIGRAINE", + "CROISSANCE", + "TRANCH'HERBE", + "LANCE-SOLEIL", + "POUDRE TOXIK", + "PARA-SPORE", + "POUDRE DODO", + "DANSE-FLEUR", + "SECRETION", + "DRACO-RAGE", + "DANSEFLAMME", + "ECLAIR", + "TONNERRE", + "CAGE-ECLAIR", + "FATAL-FOUDRE", + "JET-PIERRES", + "SEISME", + "ABIME", + "TUNNEL", + "TOXIK", + "CHOC MENTAL", + "PSYKO", + "HYPNOSE", + "YOGA", + "HATE", + "VIVE-ATTAQUE", + "FRENESIE", + "TELEPORT", + "TENEBRES", + "COPIE", + "GRINCEMENT", + "REFLET", + "SOIN", + "ARMURE", + "LILLIPUT", + "BROUILLARD", + "ONDE FOLIE", + "REPLI", + "BOUL'ARMURE", + "BOUCLIER", + "MUR LUMIERE", + "BUEE NOIRE", + "PROTECTION", + "PUISSANCE", + "PATIENCE", + "METRONOME", + "MIMIQUE", + "DESTRUCTION", + "BOMB'OEUF", + "LECHOUILLE", + "PUREDPOIS", + "DETRITUS", + "MASSD'OS", + "DEFLAGRATION", + "CASCADE", + "CLAQUOIR", + "METEORES", + "COUD'KRANE", + "PICANON", + "CONSTRICTION", + "AMNESIE", + "TELEKINESIE", + "E-COQUE", + "PIED VOLTIGE", + "INTIMIDATION", + "DEVOREVE", + "GAZ TOXIK", + "PILONNAGE", + "VAMPIRISME", + "GROBISOU", + "PIQUE", + "MORPHING", + "ECUME", + "UPPERCUT", + "SPORE", + "FLASH", + "VAGUE PSY", + "TREMPETTE", + "ACIDARMURE", + "PINCE-MASSE", + "EXPLOSION", + "COMBO-GRIFFE", + "OSMERANG", + "REPOS", + "EBOULEMENT", + "CROC DE MORT", + "AFFUTAGE", + "ADAPTATION", + "TRIPLATTAQUE", + "CROC FATAL", + "TRANCHE", + "CLONAGE", + "LUTTE", + "GRIBOUILLE", + "TRIPLE PIED", + "LARCIN", + "TOILE", + "LIRE-ESPRIT", + "CAUCHEMAR", + "ROUE DE FEU", + "RONFLEMENT", + "MALEDICTION", + "FLEAU", + "CONVERSION 2", + "AEROBLAST", + "SPORE COTON", + "CONTRE", + "DEPIT", + "POUDREUSE", + "ABRI", + "MACH PUNCH", + "GRIMACE", + "FEINTE", + "DOUX BAISER", + "COGNOBIDON", + "BOMB-BEURK", + "COUD'BOUE", + "OCTAZOOKA", + "PICOTS", + "ELECANON", + "CLAIRVOYANCE", + "PRLVT DESTIN", + "REQUIEM", + "VENT GLACE", + "DETECTION", + "CHARGE-OS", + "VERROUILLAGE", + "COLERE", + "TEMPETESABLE", + "GIGA-SANGSUE", + "TENACITE", + "CHARME", + "ROULADE", + "FAUX-CHAGE", + "VANTARDISE", + "LAIT A BOIRE", + "ETINCELLE", + "TAILLADE", + "AILE D'ACIER", + "REGARD NOIR", + "ATTRACTION", + "BLABLA DODO", + "GLAS DE SOIN", + "RETOUR", + "CADEAU", + "FRUSTRATION", + "RUNE PROTECT", + "BALANCE", + "FEU SACRE", + "AMPLEUR", + "DYNAMOPOING", + "MEGACORNE", + "DRACOSOUFFLE", + "RELAIS", + "ENCORE", + "POURSUITE", + "TOUR RAPIDE", + "DOUX PARFUM", + "QUEUE DE FER", + "GRIFFE ACIER", + "CORPS PERDU", + "AURORE", + "SYNTHESE", + "RAYON LUNE", + "PUIS. CACHEE", + "COUP-CROIX", + "OURAGAN", + "DANSE PLUIE", + "ZENITH", + "MACHOUILLE", + "VOILE MIROIR", + "BOOST", + "VIT.EXTREME", + "POUV.ANTIQUE", + "BALL'OMBRE", + "PRESCIENCE", + "ECLATE-ROC", + "SIPHON", + "BASTON", + "BLUFF", + "BROUHAHA", + "STOCKAGE", + "RELACHE", + "AVALE", + "CANICULE", + "GRELE", + "TOURMENTE", + "FLATTERIE", + "FEU FOLLET", + "SOUVENIR", + "FACADE", + "MITRA-POING", + "STIMULANT", + "PAR ICI", + "FORCE-NATURE", + "CHARGEUR", + "PROVOC", + "COUP D'MAIN", + "TOURMAGIK", + "IMITATION", + "VOEU", + "ASSISTANCE", + "RACINES", + "SURPUISSANCE", + "REFLET MAGIK", + "RECYCLAGE", + "VENDETTA", + "CASSE-BRIQUE", + "BAILLEMENT", + "SABOTAGE", + "EFFORT", + "ERUPTION", + "ECHANGE", + "POSSESSIF", + "REGENERATION", + "RANCUNE", + "SAISIE", + "FORCE CACHEE", + "PLONGEE", + "COGNE", + "CAMOUFLAGE", + "LUMIQUEUE", + "LUMI-ECLAT", + "BALL'BRUME", + "DANSE-PLUME", + "DANSE-FOLLE", + "PIED BRULEUR", + "LANCE-BOUE", + "BALL'GLACE", + "POING DARD", + "PARESSE", + "MEGAPHONE", + "CROCHETVENIN", + "ECLATEGRIFFE", + "RAFALE FEU", + "HYDROBLAST", + "POING METEOR", + "ETONNEMENT", + "BALL'METEO", + "AROMATHERAPI", + "CROCO LARME", + "TRANCH'AIR", + "SURCHAUFFE", + "FLAIR", + "TOMBEROCHE", + "VENT ARGENTE", + "STRIDO-SON", + "SIFFL'HERBE", + "CHATOUILLE", + "FORCE COSMIK", + "GICLEDO", + "RAYON SIGNAL", + "POING OMBRE", + "EXTRASENSEUR", + "STRATOPERCUT", + "TOURBI-SABLE", + "GLACIATION", + "OCROUPI", + "BALLE GRAINE", + "AEROPIQUE", + "STALAGTITE", + "MUR DE FER", + "BARRAGE", + "GRONDEMENT", + "DRACOGRIFFE", + "VEGE-ATTAK", + "GONFLETTE", + "REBOND", + "TIR DE BOUE", + "QUEUE-POISON", + "IMPLORE", + "ELECTACLE", + "FEUILLEMAGIK", + "TOURNIQUET", + "PLENITUDE", + "LAME-FEUILLE", + "DANSE DRACO", + "BOULE ROC", + "ONDE DE CHOC", + "VIBRAQUA", + "CARNAREKET", + "PSYCHO BOOST" +}; + +const char *germanNames[355] = { + "(Nichts)", + "PFUND", + "KARATESCHLAG", + "DUPLEXHIEB", + "KOMETENHIEB", + "MEGAHIEB", + "ZAHLTAG", + "FEUERSCHLAG", + "EISHIEB", + "DONNERSCHLAG", + "KRATZER", + "KLAMMER", + "GUILLOTINE", + "KLINGENSTURM", + "SCHWERTTANZ", + "ZERSCHNEIDER", + "WINDSTOSS", + "FL\xC3\x9CGELSCHLAG", + "WIRBELWIND", + "FLIEGEN", + "KLAMMERGRIFF", + "SLAM", + "RANKENHIEB", + "STAMPFER", + "DOPPELKICK", + "MEGAKICK", + "SPRUNGKICK", + "FEGEKICK", + "SANDWIRBEL", + "KOPFNUSS", + "HORNATTACKE", + "FURIENSCHLAG", + "HORNBOHRER", + "TACKLE", + "BODYSLAM", + "WICKEL", + "BODYCHECK", + "FUCHTLER", + "RISIKOTACKLE", + "RUTENSCHLAG", + "GIFTSTACHEL", + "DUONADEL", + "NADELRAKETE", + "SILBERBLICK", + "BISS", + "HEULER", + "BR\xC3\x9CLLER", + "GESANG", + "SUPERSCHALL", + "ULTRASCHALL", + "AUSSETZER", + "S\xC3\x84URE", + "GLUT", + "FLAMMENWURF", + "WEISSNEBEL", + "AQUAKNARRE", + "HYDROPUMPE", + "SURFER", + "EISSTRAHL", + "BLIZZARD", + "PSYSTRAHL", + "BLUBBSTRAHL", + "AURORASTRAHL", + "HYPERSTRAHL", + "SCHNABEL", + "BOHRSCHNABEL", + "\xC3\x9C""BERROLLER", + "FUSSKICK", + "KONTER", + "GEOWURF", + "ST\xC3\x84RKE", + "ABSORBER", + "MEGASAUGER", + "EGELSAMEN", + "WACHSTUM", + "RASIERBLATT", + "SOLARSTRAHL", + "GIFTPUDER", + "STACHELSPORE", + "SCHLAFPUDER", + "BL\xC3\x84TTERTANZ", + "FADENSCHUSS", + "DRACHENWUT", + "FEUERWIRBEL", + "DONNERSCHOCK", + "DONNERBLITZ", + "DONNERWELLE", + "DONNER", + "STEINWURF", + "ERDBEBEN", + "GEOFISSUR", + "SCHAUFLER", + "TOXIN", + "KONFUSION", + "PSYCHOKINESE", + "HYPNOSE", + "MEDITATION", + "AGILIT\xC3\x84T", + "RUCKZUCKHIEB", + "RASEREI", + "TELEPORT", + "NACHTNEBEL", + "MIMIKRY", + "KREIDESCHREI", + "DOPPELTEAM", + "GENESUNG", + "H\xC3\x84RTNER", + "KOMPRIMATOR", + "RAUCHWOLKE", + "KONFUSTRAHL", + "PANZERSCHUTZ", + "EINIGLER", + "BARRIERE", + "LICHTSCHILD", + "DUNKELNEBEL", + "REFLEKTOR", + "ENERGIEFOKUS", + "GEDULD", + "METRONOM", + "SPIEGELTRICK", + "FINALE", + "EIERBOMBE", + "SCHLECKER", + "SMOG", + "SCHLAMMBAD", + "KNOCHENKEULE", + "FEUERSTURM", + "KASKADE", + "SCHNAPPER", + "STERNSCHAUER", + "SCH\xC3\x84""DELWUMME", + "DORNKANONE", + "UMKLAMMERUNG", + "AMNESIE", + "PSYKRAFT", + "WEICHEI", + "TURMKICK", + "GIFTBLICK", + "TRAUMFRESSER", + "GIFTWOLKE", + "STAKKATO", + "BLUTSAUGER", + "TODESKUSS", + "HIMMELSFEGER", + "WANDLER", + "BLUBBER", + "IRRSCHLAG", + "PILZSPORE", + "BLITZ", + "PSYWELLE", + "PLATSCHER", + "S\xC3\x84UREPANZER", + "KRABBHAMMER", + "EXPLOSION", + "KRATZFURIE", + "KNOCHMERANG", + "ERHOLUNG", + "STEINHAGEL", + "HYPERZAHN", + "SCH\xC3\x84RFER", + "UMWANDLUNG", + "TRIPLETTE", + "SUPERZAHN", + "SCHLITZER", + "DELEGATOR", + "VERZWEIFLER", + "NACHAHMER", + "DREIFACHKICK", + "RAUB", + "SPINNENNETZ", + "WILLENSLESER", + "NACHTMAHR", + "FLAMMENRAD", + "SCHNARCHER", + "FLUCH", + "DRESCHFLEGEL", + "UMWANDLUNG2", + "LUFTSTOSS", + "BAUMWOLLSAAT", + "GEGENSCHLAG", + "GROLL", + "PULVERSCHNEE", + "SCHUTZSCHILD", + "TEMPOHIEB", + "GRIMASSE", + "FINTE", + "BITTERKUSS", + "BAUCHTROMMEL", + "MATSCHBOMBE", + "LEHMSCHELLE", + "OCTAZOOKA", + "STACHLER", + "BLITZKANONE", + "GESICHTE", + "ABGANGSBUND", + "ABGESANG", + "EISSTURM", + "SCANNER", + "KNOCHENHATZ", + "ZIELSCHUSS", + "WUTANFALL", + "SANDSTURM", + "GIGASAUGER", + "AUSDAUER", + "CHARME", + "WALZER", + "TRUGSCHLAG", + "ANGEBEREI", + "MILCHGETR\xC3\x84NK", + "FUNKENSPRUNG", + "ZORNKLINGE", + "STAHLFL\xC3\x9CGEL", + "HORRORBLICK", + "ANZIEHUNG", + "SCHLAFREDE", + "VITALGLOCKE", + "R\xC3\x9C""CKKEHR", + "GESCHENK", + "FRUSTRATION", + "BODYGUARD", + "LEIDTEILER", + "L\xC3\x84UTERFEUER", + "INTENSIT\xC3\x84T", + "WUCHTSCHLAG", + "VIELENDER", + "FEUERODEM", + "STAFFETTE", + "ZUGABE", + "VERFOLGUNG", + "TURBODREHER", + "LOCKDUFT", + "EISENSCHWEIF", + "METALLKLAUE", + "\xC3\x9C""BERWURF", + "MORGENGRAUEN", + "SYNTHESE", + "MONDSCHEIN", + "KRAFTRESERVE", + "KREUZHIEB", + "WINDHOSE", + "REGENTANZ", + "SONNENTAG", + "KNIRSCHER", + "SPIEGELCAPE", + "PSYCHO-PLUS", + "TURBOTEMPO", + "ANTIK-KRAFT", + "SPUKBALL", + "SEHER", + "ZERTR\xC3\x9CMMERER", + "WHIRLPOOL", + "PR\xC3\x9CGLER", + "MOGELHIEB", + "AUFRUHR", + "HORTER", + "ENTFESSLER", + "VERZEHRER", + "HITZEWELLE", + "HAGELSTURM", + "FOLTERKNECHT", + "SCHMEICHLER", + "IRRLICHT", + "MEMENTO-MORI", + "FASSADE", + "POWER-PUNCH", + "RIECHSALZ", + "SPOTLIGHT", + "NATUR-KRAFT", + "LADEVORGANG", + "VERH\xC3\x96HNER", + "RECHTE HAND", + "TRICKBETRUG", + "ROLLENTAUSCH", + "WUNSCHTRAUM", + "ZUSCHUSS", + "VERWURZLER", + "KRAFTKOLOSS", + "MAGIEMANTEL", + "AUFBEREITUNG", + "VERGELTUNG", + "DURCHBRUCH", + "G\xC3\x84HNER", + "ABSCHLAG", + "NOTSITUATION", + "ERUPTION", + "WERTEWECHSEL", + "BEGRENZER", + "HEILUNG", + "NACHSPIEL", + "\xC3\x9C""BERNAHME", + "GEHEIMPOWER", + "TAUCHER", + "ARMSTOSS", + "TARNUNG", + "SCHWEIFGLANZ", + "SCHEINWERFER", + "NEBELBALL", + "DAUNENREIGEN", + "TAUMELTANZ", + "FEUERFEGER", + "LEHMSUHLER", + "FROSTBEULE", + "NIETENRANKE", + "TAGEDIEB", + "SCHALLWELLE", + "GIFTZAHN", + "ZERMALMKLAUE", + "LOHEKANONADE", + "AQUAHAUBITZE", + "STERNENHIEB", + "ERSTAUNER", + "METEOROLOGE", + "AROMAKUR", + "TRUGTR\xC3\x84NE", + "WINDSCHNITT", + "HITZEKOLLER", + "SCHN\xC3\x9C""FFLER", + "FELSGRAB", + "SILBERHAUCH", + "METALLSOUND", + "GRASFL\xC3\x96TE", + "SPASSKANONE", + "KOSMIK-KRAFT", + "FONTR\xC3\x84NEN", + "AMPELLEUCHTE", + "FINSTERFAUST", + "SONDERSENSOR", + "HIMMELHIEB", + "SANDGRAB", + "EISESK\xC3\x84LTE", + "LEHMBR\xC3\x9CHE", + "KUGELSAAT", + "AERO-ASS", + "EISSPEER", + "EISENABWEHR", + "R\xC3\x9C""CKENTZUG", + "JAULER", + "DRACHENKLAUE", + "FAUNA-STATUE", + "PROTZER", + "SPRUNGFEDER", + "LEHMSCHUSS", + "GIFTSCHWEIF", + "BEZIRZER", + "VOLTTACKLE", + "ZAUBERBLATT", + "NASSMACHER", + "GEDANKENGUT", + "LAUBKLINGE", + "DRACHENTANZ", + "FELSWURF", + "SCHOCKWELLE", + "AQUAWELLE", + "KISMETWUNSCH", + "PSYSCHUB", +}; + +const char *italianNames[355] = { + "(Nessuno)", + "BOTTA", + "COLPOKARATE", + "DOPPIASBERLA", + "COMETAPUGNO", + "MEGAPUGNO", + "GIORNOPAGA", + "FUOCOPUGNO", + "GELOPUGNO", + "TUONOPUGNO", + "GRAFFIO", + "PRESA", + "GHIGLIOTTINA", + "VENTAGLIENTE", + "DANZASPADA", + "TAGLIO", + "RAFFICA", + "ATT. D'ALA", + "TURBINE", + "VOLO", + "LEGATUTTO", + "SCHIANTO", + "FRUSTATA", + "PESTONE", + "DOPPIOCALCIO", + "MEGACALCIO", + "CALCIOSALTO", + "CALCIORULLO", + "TURBOSABBIA", + "BOTTINTESTA", + "INCORNATA", + "FURIA", + "PERFORCORNO", + "AZIONE", + "CORPOSCONTRO", + "AVVOLGIBOTTA", + "RIDUTTORE", + "COLPO", + "SDOPPIATORE", + "COLPOCODA", + "VELENOSPINA", + "DOPPIO AGO", + "MISSILSPILLO", + "FULMISGUARDO", + "MORSO", + "RUGGITO", + "BOATO", + "CANTO", + "SUPERSUONO", + "SONICBOOM", + "INIBITORE", + "ACIDO", + "BRACIERE", + "LANCIAFIAMME", + "NEBBIA", + "PISTOLACQUA", + "IDROPOMPA", + "SURF", + "GELORAGGIO", + "BORA", + "PSICORAGGIO", + "BOLLARAGGIO", + "RAGGIAURORA", + "IPER RAGGIO", + "BECCATA", + "PERFORBECCO", + "SOTTOMISS.", + "COLPO BASSO", + "CONTATORE", + "MOV.SISMICO", + "FORZA", + "ASSORBIMENTO", + "MEGASSORBIM.", + "PARASSISEME", + "CRESCITA", + "FOGLIELAMA", + "SOLARRAGGIO", + "VELENPOLVERE", + "PARALIZZANTE", + "SONNIFERO", + "PETALODANZA", + "MILLEBAVE", + "IRA DI DRAGO", + "TURBOFUOCO", + "TUONOSHOCK", + "FULMINE", + "TUONONDA", + "TUONO", + "SASSATA", + "TERREMOTO", + "ABISSO", + "FOSSA", + "TOSSINA", + "CONFUSIONE", + "PSICHICO", + "IPNOSI", + "MEDITAZIONE", + "AGILIT\xC3\x80", + "ATT. RAPIDO", + "IRA", + "TELETRASPOR.", + "OMBRA NOTT.", + "MIMICA", + "STRIDIO", + "DOPPIOTEAM", + "RIPRESA", + "RAFFORZATORE", + "MINIMIZZATO", + "MURO DI FUMO", + "STORDIRAGGIO", + "RITIRATA", + "RICCIOLSCUDO", + "BARRIERA", + "SCHERMOLUCE", + "NUBE", + "RIFLESSO", + "FOCALENERGIA", + "PAZIENZA", + "METRONOMO", + "SPECULMOSSA", + "AUTODISTRUZ.", + "UOVOBOMBA", + "LECCATA", + "SMOG", + "FANGO", + "OSSOCLAVA", + "FUOCOBOMBA", + "CASCATA", + "TENAGLIA", + "COMETE", + "CAPOCCIATA", + "SPARALANCE", + "LIMITAZIONE", + "AMNESIA", + "CIN\xC3\x88SI", + "COVAUOVA", + "CALCINVOLO", + "BAGLIORE", + "MANGIASOGNI", + "VELENOGAS", + "ATT. PIOGGIA", + "SANGUISUGA", + "DEMONBACIO", + "AEROATTACCO", + "TRASFORMAZ.", + "BOLLA", + "STORDIPUGNO", + "SPORA", + "FLASH", + "PSICONDA", + "SPLASH", + "SCUDO ACIDO", + "MARTELLATA", + "ESPLOSIONE", + "SFURIATE", + "OSSOMERANG", + "RIPOSO", + "FRANA", + "IPERZANNA", + "AFFILATORE", + "CONVERSIONE", + "TRIPLETTA", + "SUPERZANNA", + "LACERAZIONE", + "SOSTITUTO", + "SCONTRO", + "SCHIZZO", + "TRIPLOCALCIO", + "FURTO", + "RAGNATELA", + "LEGGIMENTE", + "INCUBO", + "RUOTAFUOCO", + "RUSSARE", + "MALEDIZIONE", + "FLAGELLO", + "CONVERSIONE2", + "AEROCOLPO", + "COTTONSPORA", + "CONTROPIEDE", + "DISPETTO", + "POLNEVE", + "PROTEZIONE", + "PUGNORAPIDO", + "VISOTRUCE", + "FINTA", + "DOLCEBACIO", + "PANCIAMBURO", + "FANGOBOMBA", + "FANGOSBERLA", + "OCTAZOOKA", + "PUNTE", + "FALCECANNONE", + "PREVEGGENZA", + "DESTINOBBL.", + "ULTIMOCANTO", + "VENTOGELATO", + "INDIVIDUA", + "OSSORAFFICA", + "LOCALIZZA", + "OLTRAGGIO", + "TERREMPESTA", + "GIGASSORBIM.", + "RESISTENZA", + "FASCINO", + "ROTOLAMENTO", + "FALSOFINALE", + "BULLO", + "BUONLATTE", + "SCINTILLA", + "TAGLIOFURIA", + "ALACCIAIO", + "MALOSGUARDO", + "ATTRAZIONE", + "SONNOLALIA", + "RINTOCCASANA", + "RITORNO", + "REGALINO", + "FRUSTRAZIONE", + "SALVAGUARDIA", + "MALCOMUNE", + "MAGIFUOCO", + "MAGNITUDO", + "DINAMIPUGNO", + "MEGACORNO", + "DRAGOSPIRO", + "STAFFETTA", + "RIPETI", + "INSEGUIMENTO", + "RAPIGIRO", + "PROFUMINO", + "CODACCIAIO", + "FERRARTIGLI", + "VITALTIRO", + "MATTINDORO", + "SINTESI", + "LUCELUNARE", + "INTROFORZA", + "INCROCOLPO", + "TORNADO", + "PIOGGIADANZA", + "GIORNODISOLE", + "SGRANOCCHIO", + "SPECCHIOVELO", + "PSICAMIS\xC3\x99", + "EXTRARAPIDO", + "FORZANTICA", + "PALLA OMBRA", + "DIVINAZIONE", + "SPACCAROCCIA", + "MULINELLO", + "PICCHIADURO", + "BRUCIAPELO", + "BARAONDA", + "ACCUMULO", + "SFOGHENERGIA", + "INTROENERGIA", + "ONDACALDA", + "GRANDINE", + "ATTACCALITE", + "ADULAZIONE", + "FUOCOFATUO", + "MEMENTO", + "FACCIATA", + "CENTRIPUGNO", + "MANIEREFORTI", + "SONOQUI", + "NATURFORZA", + "SOTTOCARICA", + "PROVOCAZIONE", + "ALTRUISMO", + "RAGGIRO", + "GIOCODIRUOLO", + "DESIDERIO", + "ASSISTENTE", + "RADICAMENTO", + "TROPPOFORTE", + "MAGIVELO", + "RICICLO", + "VENDETTA", + "BRECCIA", + "SBADIGLIO", + "PRIVAZIONE", + "RIMONTA", + "ERUZIONE", + "BARATTO", + "ESCLUSIVA", + "RINFRESCATA", + "RANCORE", + "SCIPPO", + "FORZASEGRETA", + "SUB", + "SBERLETESE", + "CAMUFFAMENTO", + "CODADILUCE", + "ABBAGLIANTE", + "FOSCHISFERA", + "DANZADIPIUME", + "STRAMPADANZA", + "CALCIARDENTE", + "FANGATA", + "PALLA GELO", + "PUGNOSPINE", + "PIGRO", + "GRANVOCE", + "VELENODENTI", + "TRITARTIGLI", + "INCENDIO", + "IDROCANNONE", + "METEORPUGNO", + "SGOMENTO", + "PALLA CLIMA", + "AROMATERAPIA", + "FALSELACRIME", + "AERASOIO", + "VAMPATA", + "SEGUGIO", + "ROCCIOTOMBA", + "VENTARGENTEO", + "FERROSTRIDO", + "MELODERBA", + "SOLLETICO", + "COSMOFORZA", + "ZAMPILLO", + "SEGNORAGGIO", + "PUGNODOMBRA", + "EXTRASENSO", + "STRAMONTANTE", + "SABBIOTOMBA", + "PUROGELO", + "FANGHIGLIA", + "SEMITRAGLIA", + "AEROASSALTO", + "GELOLANCIA", + "FERROSCUDO", + "BLOCCO", + "GRIDODILOTTA", + "DRAGARTIGLI", + "RADICALBERO", + "GRANFISICO", + "RIMBALZO", + "COLPODIFANGO", + "VELENOCODA", + "SUPPLICA", + "LOCOMOVOLT", + "FOGLIAMAGICA", + "DOCCIASCUDO", + "CALMAMENTE", + "FENDIFOGLIA", + "DRAGODANZA", + "CADUTAMASSI", + "ONDASHOCK", + "IDROPULSAR", + "OBBLIDERIO", + "PSICOSLANCIO", +}; + +const char *spanishNames[355] = { + "(Ninguno)", + "DESTRUCTOR", + "GOLPE KARATE", + "DOBLEBOFET\xC3\x93N", + "PU\xC3\x91O COMETA", + "MEGAPU\xC3\x91O", + "D\xC3\x8D""A DE PAGO", + "PU\xC3\x91O FUEGO", + "PU\xC3\x91O HIELO", + "PU\xC3\x91O TRUENO", + "ARA\xC3\x91""AZO", + "AGARRE", + "GUILLOTINA", + "V. CORTANTE", + "DANZA ESPADA", + "CORTE", + "TORNADO", + "ATAQUE ALA", + "REMOLINO", + "VUELO", + "ATADURA", + "PORTAZO", + "L\xC3\x81TIGO CEPA", + "PISOT\xC3\x93N", + "DOBLE PATADA", + "MEGAPATADA", + "PATADA SALTO", + "PATADA GIRO", + "ATAQUE ARENA", + "GOLPE CABEZA", + "CORNADA", + "ATAQUE FURIA", + "PERFORADOR", + "PLACAJE", + "GOLPE CUERPO", + "REPETICI\xC3\x93N", + "DERRIBO", + "GOLPE", + "DOBLE FILO", + "L\xC3\x81TIGO", + "PICOTAZO VEN", + "DOBLEATAQUE", + "PIN MISIL", + "MALICIOSO", + "MORDISCO", + "GRU\xC3\x91IDO", + "RUGIDO", + "CANTO", + "SUPERS\xC3\x93NICO", + "BOMBA S\xC3\x93NICA", + "ANULACI\xC3\x93N", + "\xC3\x81""CIDO", + "ASCUAS", + "LANZALLAMAS", + "NEBLINA", + "PISTOLA AGUA", + "HIDROBOMBA", + "SURF", + "RAYO HIELO", + "VENTISCA", + "PSICORRAYO", + "RAYO BURBUJA", + "RAYO AURORA", + "HIPERRAYO", + "PICOTAZO", + "PICO TALADRO", + "SUMISI\xC3\x93N", + "PATADA BAJA", + "CONTADOR", + "MOV.S\xC3\x8DSMICO", + "FUERZA", + "ABSORBER", + "MEGAAGOTAR", + "DRENADORAS", + "DESARROLLO", + "HOJA AFILADA", + "RAYO SOLAR", + "POLVO VENENO", + "PARALIZADOR", + "SOMN\xC3\x8D""FERO", + "DANZA P\xC3\x89TALO", + "DISP. DEMORA", + "FURIA DRAG\xC3\x93N", + "GIRO FUEGO", + "IMPACTRUENO", + "RAYO", + "ONDA TRUENO", + "TRUENO", + "LANZARROCAS", + "TERREMOTO", + "FISURA", + "EXCAVAR", + "T\xC3\x93XICO", + "CONFUSI\xC3\x93N", + "PS\xC3\x8DQUICO", + "HIPNOSIS", + "MEDITACI\xC3\x93N", + "AGILIDAD", + "AT. R\xC3\x81PIDO", + "FURIA", + "TELETRANSP", + "TINIEBLAS", + "MIM\xC3\x89TICO", + "CHIRRIDO", + "DOBLE EQUIPO", + "RECUPERACI\xC3\x93N", + "FORTALEZA", + "REDUCCI\xC3\x93N", + "PANTALLAHUMO", + "RAYO CONFUSO", + "REFUGIO", + "RIZO DEFENSA", + "BARRERA", + "PANTALLA LUZ", + "NIEBLA", + "REFLEJO", + "FOCO ENERG\xC3\x8D""A", + "VENGANZA", + "METR\xC3\x93NOMO", + "MOV. ESPEJO", + "AUTODESTRUC", + "BOMBA HUEVO", + "LENG\xC3\x9C""ETAZO", + "POLUCI\xC3\x93N", + "RESIDUOS", + "HUESO PALO", + "LLAMARADA", + "CASCADA", + "TENAZA", + "RAPIDEZ", + "CABEZAZO", + "CLAVO CA\xC3\x91\xC3\x93N", + "RESTRICCI\xC3\x93N", + "AMNESIA", + "KIN\xC3\x89TICO", + "AMORTIGUADOR", + "PAT. S. ALTA", + "DESLUMBRAR", + "COME SUE\xC3\x91OS", + "GAS VENENOSO", + "PRESA", + "CHUPAVIDAS", + "BESO AMOROSO", + "ATAQUE A\xC3\x89REO", + "TRANSFORM", + "BURBUJA", + "PU\xC3\x91O MAREO", + "ESPORA", + "DESTELLO", + "PSICOONDA", + "SALPICADURA", + "ARMAD. \xC3\x81""CIDA", + "MARTILLAZO", + "EXPLOSI\xC3\x93N", + "GOLPES FURIA", + "HUESOMERANG", + "DESCANSO", + "AVALANCHA", + "HIP.COLMILLO", + "AFILAR", + "CONVERSI\xC3\x93N", + "TRIATAQUE", + "SUPERDIENTE", + "CUCHILLADA", + "SUSTITUTO", + "COMBATE", + "ESQUEMA", + "TRIPLEPATADA", + "LADR\xC3\x93N", + "TELARA\xC3\x91""A", + "TEL\xC3\x89PATA", + "PESADILLA", + "RUEDA FUEGO", + "RONQUIDO", + "MALDICI\xC3\x93N", + "AZOTE", + "CONVERSI\xC3\x93N2", + "AEROCHORRO", + "ESPORAGOD\xC3\x93N", + "INVERSI\xC3\x93N", + "RENCOR", + "NIEVE POLVO", + "PROTECCI\xC3\x93N", + "ULTRAPU\xC3\x91O", + "CARA SUSTO", + "FINTA", + "BESO DULCE", + "TAMBOR", + "BOMBA LODO", + "BOFET\xC3\x93N LODO", + "PULPOCA\xC3\x91\xC3\x93N", + "P\xC3\x9A""AS", + "ELECTROCA\xC3\x91\xC3\x93N", + "PROFEC\xC3\x8D""A", + "MISMODESTINO", + "CANTO MORTAL", + "VIENTO HIELO", + "DETECCI\xC3\x93N", + "ATAQUE \xC3\x93SEO", + "FIJAR BLANCO", + "ENFADO", + "TORM. ARENA", + "GIGADRENADO", + "AGUANTE", + "ENCANTO", + "DESENROLLAR", + "FALSOTORTAZO", + "CONTONEO", + "BATIDO", + "CHISPA", + "CORTEFURIA", + "ALA DE ACERO", + "MAL DE OJO", + "ATRACCI\xC3\x93N", + "SON\xC3\x81MBULO", + "CAMPANA CURA", + "RETROCESO", + "PRESENTE", + "FRUSTRACI\xC3\x93N", + "VELO SAGRADO", + "DIVIDE DOLOR", + "FUEGOSAGRADO", + "MAGNITUD", + "PU\xC3\x91ODIN\xC3\x81MICO", + "MEGACUERNO", + "DRAGOALIENTO", + "RELEVO", + "OTRA VEZ", + "PERSECUCI\xC3\x93N", + "GIRO R\xC3\x81PIDO", + "DULCE AROMA", + "COLA F\xC3\x89RREA", + "GARRA METAL", + "TIRO VITAL", + "SOL MATINAL", + "S\xC3\x8DNTESIS", + "LUZ LUNAR", + "PODER OCULTO", + "TAJO CRUZADO", + "CICL\xC3\x93N", + "DANZA LLUVIA", + "D\xC3\x8D""A SOLEADO", + "TRITURAR", + "MANTO ESPEJO", + "M\xC3\x81S PSIQUE", + "VEL. EXTREMA", + "PODER PASADO", + "BOLA SOMBRA", + "PREMONICI\xC3\x93N", + "GOLPE ROCA", + "TORBELLINO", + "PALIZA", + "SORPRESA", + "ALBOROTO", + "RESERVA", + "ESCUPIR", + "TRAGAR", + "ONDA \xC3\x8DGNEA", + "GRANIZO", + "TORMENTO", + "CAMELO", + "FUEGO FATUO", + "LEGADO", + "IMAGEN", + "PU\xC3\x91O CERTERO", + "EST\xC3\x8DMULO", + "SE\xC3\x91UELO", + "ADAPTACI\xC3\x93N", + "CARGA", + "MOFA", + "REFUERZO", + "TRUCO", + "IMITACI\xC3\x93N", + "DESEO", + "AYUDA", + "ARRAIGO", + "FUERZA BRUTA", + "CAPA M\xC3\x81GICA", + "RECICLAJE", + "DESQUITE", + "DEMOLICI\xC3\x93N", + "BOSTEZO", + "DESARME", + "ESFUERZO", + "ESTALLIDO", + "INTERCAMBIO", + "CERCA", + "ALIVIO", + "RABIA", + "ROBO", + "DA\xC3\x91O SECRETO", + "BUCEO", + "EMPUJ\xC3\x93N", + "CAMUFLAJE", + "R\xC3\x81""FAGA", + "RESPLANDOR", + "BOLA NEBLINA", + "DANZA PLUMA", + "DANZA CAOS", + "PATADA \xC3\x8DGNEA", + "CHAPOTEOLODO", + "BOLA HIELO", + "BRAZO PINCHO", + "RELAJO", + "VOZARR\xC3\x93N", + "COLMILLO VEN", + "GARRA BRUTAL", + "ANILLO \xC3\x8DGNEO", + "HIDROCA\xC3\x91\xC3\x93N", + "PU\xC3\x91O METEORO", + "IMPRESIONAR", + "METEOROBOLA", + "AROMATERAPIA", + "LLANTO FALSO", + "AIRE AFILADO", + "SOFOCO", + "RASTREO", + "TUMBA ROCAS", + "VIENTO PLATA", + "ECO MET\xC3\x81LICO", + "SILBATO", + "COSQUILLAS", + "MASA C\xC3\x93SMICA", + "SALPICAR", + "DOBLE RAYO", + "PU\xC3\x91O SOMBRA", + "PARANORMAL", + "GANCHO ALTO", + "BUCLE ARENA", + "FR\xC3\x8DO POLAR", + "AGUA LODOSA", + "RECURRENTE", + "GOLPE A\xC3\x89REO", + "CAR\xC3\x81MBANO", + "DEF. F\xC3\x89RREA", + "BLOQUEO", + "AULLIDO", + "GARRA DRAG\xC3\x93N", + "PLANTA FEROZ", + "CORPULENCIA", + "BOTE", + "DISP. LODO", + "COLA VENENO", + "ANTOJO", + "PLACAJE EL\xC3\x89""C", + "HOJA M\xC3\x81GICA", + "HIDROCHORRO", + "PAZ MENTAL", + "HOJA AGUDA", + "DANZA DRAG\xC3\x93N", + "PEDRADA", + "ONDA VOLTIO", + "HIDROPULSO", + "DESEO OCULTO", + "PSICOATAQUE", +}; + +const char *japaneseNames[355] = { + "(\xe4\xbd\x95\xe3\x82\x82)", + "\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x8f", + "\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xa6\xe3\x83\x81\xe3\x83\xa7\xe3\x83\x83\xe3\x83\x97", + "\xe3\x81\x8a\xe3\x81\x86\xe3\x81\xb5\xe3\x81\x8f\xe3\x83\x93\xe3\x83\xb3\xe3\x82\xbf", + "\xe3\x82\x8c\xe3\x82\x93\xe3\x81\x9e\xe3\x81\x8f\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x88\xe3\x83\xb3\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x83\x8d\xe3\x82\xb3\xe3\x81\xab\xe3\x81\x93\xe3\x81\xb0\xe3\x82\x93", + "\xe3\x81\xbb\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xae\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x82\x8c\xe3\x81\x84\xe3\x81\xa8\xe3\x81\x86\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\x8b\xe3\x81\xbf\xe3\x81\xaa\xe3\x82\x8a\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\xb2\xe3\x81\xa3\xe3\x81\x8b\xe3\x81\x8f", + "\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x80", + "\xe3\x83\x8f\xe3\x82\xb5\xe3\x83\x9f\xe3\x82\xae\xe3\x83\xad\xe3\x83\x81\xe3\x83\xb3", + "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa1", + "\xe3\x81\xa4\xe3\x82\x8b\xe3\x81\x8e\xe3\x81\xae\xe3\x81\xbe\xe3\x81\x84", + "\xe3\x81\x84\xe3\x81\x82\xe3\x81\x84\xe3\x81\x8e\xe3\x82\x8a", + "\xe3\x81\x8b\xe3\x81\x9c\xe3\x81\x8a\xe3\x81\x93\xe3\x81\x97", + "\xe3\x81\xa4\xe3\x81\xb0\xe3\x81\x95\xe3\x81\xa7\xe3\x81\x86\xe3\x81\xa4", + "\xe3\x81\xb5\xe3\x81\x8d\xe3\x81\xa8\xe3\x81\xb0\xe3\x81\x97", + "\xe3\x81\x9d\xe3\x82\x89\xe3\x82\x92\xe3\x81\xa8\xe3\x81\xb6", + "\xe3\x81\x97\xe3\x82\x81\xe3\x81\xa4\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x81\x9f\xe3\x81\x9f\xe3\x81\x8d\xe3\x81\xa4\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x81\xa4\xe3\x82\x8b\xe3\x81\xae\xe3\x83\xa0\xe3\x83\x81", + "\xe3\x81\xb5\xe3\x81\xbf\xe3\x81\xa4\xe3\x81\x91", + "\xe3\x81\xab\xe3\x81\xa9\xe3\x81\x92\xe3\x82\x8a", + "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x88\xe3\x83\xb3\xe3\x82\xad\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x81\xa8\xe3\x81\xb3\xe3\x81\x92\xe3\x82\x8a", + "\xe3\x81\xbe\xe3\x82\x8f\xe3\x81\x97\xe3\x81\x92\xe3\x82\x8a", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x8b\xe3\x81\x91", + "\xe3\x81\x9a\xe3\x81\xa4\xe3\x81\x8d", + "\xe3\x81\xa4\xe3\x81\xae\xe3\x81\xa7\xe3\x81\xa4\xe3\x81\x8f", + "\xe3\x81\xbf\xe3\x81\xa0\xe3\x82\x8c\xe3\x81\xa5\xe3\x81\x8d", + "\xe3\x81\xa4\xe3\x81\xae\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xab", + "\xe3\x81\x9f\xe3\x81\x84\xe3\x81\x82\xe3\x81\x9f\xe3\x82\x8a", + "\xe3\x81\xae\xe3\x81\x97\xe3\x81\x8b\xe3\x81\x8b\xe3\x82\x8a", + "\xe3\x81\xbe\xe3\x81\x8d\xe3\x81\xa4\xe3\x81\x8f", + "\xe3\x81\xa8\xe3\x81\xa3\xe3\x81\x97\xe3\x82\x93", + "\xe3\x81\x82\xe3\x81\xb0\xe3\x82\x8c\xe3\x82\x8b", + "\xe3\x81\x99\xe3\x81\xa6\xe3\x81\xbf\xe3\x82\xbf\xe3\x83\x83\xe3\x82\xaf\xe3\x83\xab", + "\xe3\x81\x97\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x92\xe3\x81\xb5\xe3\x82\x8b", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xb0\xe3\x82\x8a", + "\xe3\x83\x80\xe3\x83\x96\xe3\x83\xab\xe3\x83\x8b\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xab", + "\xe3\x83\x9f\xe3\x82\xb5\xe3\x82\xa4\xe3\x83\xab\xe3\x81\xb0\xe3\x82\x8a", + "\xe3\x81\xab\xe3\x82\x89\xe3\x81\xbf\xe3\x81\xa4\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x81\x8b\xe3\x81\xbf\xe3\x81\xa4\xe3\x81\x8f", + "\xe3\x81\xaa\xe3\x81\x8d\xe3\x81\x94\xe3\x81\x88", + "\xe3\x81\xbb\xe3\x81\x88\xe3\x82\x8b", + "\xe3\x81\x86\xe3\x81\x9f\xe3\x81\x86", + "\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x86\xe3\x81\x8a\xe3\x82\x93\xe3\x81\xb1", + "\xe3\x82\xbd\xe3\x83\x8b\xe3\x83\x83\xe3\x82\xaf\xe3\x83\x96\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x81\x8b\xe3\x81\xaa\xe3\x81\x97\xe3\x81\xb0\xe3\x82\x8a", + "\xe3\x82\x88\xe3\x81\x86\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x88\xe3\x81\x8d", + "\xe3\x81\xb2\xe3\x81\xae\xe3\x81\x93", + "\xe3\x81\x8b\xe3\x81\x88\xe3\x82\x93\xe3\x81\xbb\xe3\x81\x86\xe3\x81\x97\xe3\x82\x83", + "\xe3\x81\x97\xe3\x82\x8d\xe3\x81\x84\xe3\x81\x8d\xe3\x82\x8a", + "\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\xa7\xe3\x81\xa3\xe3\x81\xbd\xe3\x81\x86", + "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x89\xe3\x83\xad\xe3\x83\x9d\xe3\x83\xb3\xe3\x83\x97", + "\xe3\x81\xaa\xe3\x81\xbf\xe3\x81\xae\xe3\x82\x8a", + "\xe3\x82\x8c\xe3\x81\x84\xe3\x81\xa8\xe3\x81\x86\xe3\x83\x93\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x81\xb5\xe3\x81\xb6\xe3\x81\x8d", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xb1\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9b\xe3\x82\x93", + "\xe3\x83\x90\xe3\x83\x96\xe3\x83\xab\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9b\xe3\x82\x93", + "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\xad\xe3\x83\xa9\xe3\x83\x93\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x81\xaf\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9b\xe3\x82\x93", + "\xe3\x81\xa4\xe3\x81\xa4\xe3\x81\x8f", + "\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xab\xe3\x81\x8f\xe3\x81\xa1\xe3\x81\xb0\xe3\x81\x97", + "\xe3\x81\x98\xe3\x81\x94\xe3\x81\x8f\xe3\x81\x90\xe3\x82\x8b\xe3\x81\xbe", + "\xe3\x81\x91\xe3\x81\x9f\xe3\x81\x90\xe3\x82\x8a", + "\xe3\x82\xab\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x81\xa1\xe3\x81\x8d\xe3\x82\x85\xe3\x81\x86\xe3\x81\xaa\xe3\x81\x92", + "\xe3\x81\x8b\xe3\x81\x84\xe3\x82\x8a\xe3\x81\x8d", + "\xe3\x81\x99\xe3\x81\x84\xe3\x81\xa8\xe3\x82\x8b", + "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x89\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x82\x84\xe3\x81\xa9\xe3\x82\x8a\xe3\x81\x8e\xe3\x81\xae\xe3\x82\xbf\xe3\x83\x8d", + "\xe3\x81\x9b\xe3\x81\x84\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x86", + "\xe3\x81\xaf\xe3\x81\xa3\xe3\x81\xb1\xe3\x82\xab\xe3\x83\x83\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x82\xbd\xe3\x83\xbc\xe3\x83\xa9\xe3\x83\xbc\xe3\x83\x93\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xae\xe3\x81\x93\xe3\x81\xaa", + "\xe3\x81\x97\xe3\x81\xb3\xe3\x82\x8c\xe3\x81\x94\xe3\x81\xaa", + "\xe3\x81\xad\xe3\x82\x80\xe3\x82\x8a\xe3\x81\x94\xe3\x81\xaa", + "\xe3\x81\xaf\xe3\x81\xaa\xe3\x81\xb3\xe3\x82\x89\xe3\x81\xae\xe3\x81\xbe\xe3\x81\x84", + "\xe3\x81\x84\xe3\x81\xa8\xe3\x82\x92\xe3\x81\xaf\xe3\x81\x8f", + "\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86\xe3\x81\xae\xe3\x81\x84\xe3\x81\x8b\xe3\x82\x8a", + "\xe3\x81\xbb\xe3\x81\xae\xe3\x81\x8a\xe3\x81\xae\xe3\x81\x86\xe3\x81\x9a", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x8d\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\x83\xe3\x82\xaf", + "\xef\xbc\x91\xef\xbc\x90\xe3\x81\xbe\xe3\x82\x93\xe3\x83\x9c\xe3\x83\xab\xe3\x83\x88", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x98\xe3\x81\xaf", + "\xe3\x81\x8b\xe3\x81\xbf\xe3\x81\xaa\xe3\x82\x8a", + "\xe3\x81\x84\xe3\x82\x8f\xe3\x81\x8a\xe3\x81\xa8\xe3\x81\x97", + "\xe3\x81\x98\xe3\x81\x97\xe3\x82\x93", + "\xe3\x81\x98\xe3\x82\x8f\xe3\x82\x8c", + "\xe3\x81\x82\xe3\x81\xaa\xe3\x82\x92\xe3\x81\xbb\xe3\x82\x8b", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xa9\xe3\x81\x8f", + "\xe3\x81\xad\xe3\x82\x93\xe3\x82\x8a\xe3\x81\x8d", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xb3\xe3\x82\xad\xe3\x83\x8d\xe3\x82\xb7\xe3\x82\xb9", + "\xe3\x81\x95\xe3\x81\x84\xe3\x81\xbf\xe3\x82\x93\xe3\x81\x98\xe3\x82\x85\xe3\x81\xa4", + "\xe3\x83\xa8\xe3\x82\xac\xe3\x81\xae\xe3\x83\x9d\xe3\x83\xbc\xe3\x82\xba", + "\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9d\xe3\x81\x8f\xe3\x81\x84\xe3\x81\xa9\xe3\x81\x86", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9b\xe3\x81\xa3\xe3\x81\x8b", + "\xe3\x81\x84\xe3\x81\x8b\xe3\x82\x8a", + "\xe3\x83\x86\xe3\x83\xac\xe3\x83\x9d\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x83\x8a\xe3\x82\xa4\xe3\x83\x88\xe3\x83\x98\xe3\x83\x83\xe3\x83\x89", + "\xe3\x82\x82\xe3\x81\xae\xe3\x81\xbe\xe3\x81\xad", + "\xe3\x81\x84\xe3\x82\x84\xe3\x81\xaa\xe3\x81\x8a\xe3\x81\xa8", + "\xe3\x81\x8b\xe3\x81\x92\xe3\x81\xb6\xe3\x82\x93\xe3\x81\x97\xe3\x82\x93", + "\xe3\x81\x98\xe3\x81\x93\xe3\x81\x95\xe3\x81\x84\xe3\x81\x9b\xe3\x81\x84", + "\xe3\x81\x8b\xe3\x81\x9f\xe3\x81\x8f\xe3\x81\xaa\xe3\x82\x8b", + "\xe3\x81\xa1\xe3\x81\x84\xe3\x81\x95\xe3\x81\x8f\xe3\x81\xaa\xe3\x82\x8b", + "\xe3\x81\x88\xe3\x82\x93\xe3\x81\xbe\xe3\x81\x8f", + "\xe3\x81\x82\xe3\x82\x84\xe3\x81\x97\xe3\x81\x84\xe3\x81\xb2\xe3\x81\x8b\xe3\x82\x8a", + "\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xab\xe3\x81\x93\xe3\x82\x82\xe3\x82\x8b", + "\xe3\x81\xbe\xe3\x82\x8b\xe3\x81\x8f\xe3\x81\xaa\xe3\x82\x8b", + "\xe3\x83\x90\xe3\x83\xaa\xe3\x82\xa2\xe3\x83\xbc", + "\xe3\x81\xb2\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\xae\xe3\x81\x8b\xe3\x81\xb9", + "\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\x84\xe3\x81\x8d\xe3\x82\x8a", + "\xe3\x83\xaa\xe3\x83\x95\xe3\x83\xac\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x81\x8d\xe3\x81\x82\xe3\x81\x84\xe3\x81\xa0\xe3\x82\x81", + "\xe3\x81\x8c\xe3\x81\xbe\xe3\x82\x93", + "\xe3\x82\x86\xe3\x81\xb3\xe3\x82\x92\xe3\x81\xb5\xe3\x82\x8b", + "\xe3\x82\xaa\xe3\x82\xa6\xe3\x83\xa0\xe3\x81\x8c\xe3\x81\x88\xe3\x81\x97", + "\xe3\x81\x98\xe3\x81\xb0\xe3\x81\x8f", + "\xe3\x82\xbf\xe3\x83\x9e\xe3\x82\xb4\xe3\x81\xb0\xe3\x81\x8f\xe3\x81\xa0\xe3\x82\x93", + "\xe3\x81\x97\xe3\x81\x9f\xe3\x81\xa7\xe3\x81\xaa\xe3\x82\x81\xe3\x82\x8b", + "\xe3\x82\xb9\xe3\x83\xa2\xe3\x83\x83\xe3\x82\xb0", + "\xe3\x83\x98\xe3\x83\x89\xe3\x83\xad\xe3\x81\x93\xe3\x81\x86\xe3\x81\x92\xe3\x81\x8d", + "\xe3\x83\x9b\xe3\x83\x8d\xe3\x81\x93\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86", + "\xe3\x81\xa0\xe3\x81\x84\xe3\x82\x82\xe3\x82\x93\xe3\x81\x98", + "\xe3\x81\x9f\xe3\x81\x8d\xe3\x81\xae\xe3\x81\xbc\xe3\x82\x8a", + "\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xa7\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x80", + "\xe3\x82\xb9\xe3\x83\x94\xe3\x83\xbc\xe3\x83\x89\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x83\xad\xe3\x82\xb1\xe3\x83\x83\xe3\x83\x88\xe3\x81\x9a\xe3\x81\xa4\xe3\x81\x8d", + "\xe3\x81\xa8\xe3\x81\x92\xe3\x82\xad\xe3\x83\xa3\xe3\x83\x8e\xe3\x83\xb3", + "\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xbf\xe3\x81\xa4\xe3\x81\x8f", + "\xe3\x83\x89\xe3\x82\x8f\xe3\x81\x99\xe3\x82\x8c", + "\xe3\x82\xb9\xe3\x83\x97\xe3\x83\xbc\xe3\x83\xb3\xe3\x81\xbe\xe3\x81\x92", + "\xe3\x82\xbf\xe3\x83\x9e\xe3\x82\xb4\xe3\x81\x86\xe3\x81\xbf", + "\xe3\x81\xa8\xe3\x81\xb3\xe3\x81\xb2\xe3\x81\x96\xe3\x81\x92\xe3\x82\x8a", + "\xe3\x81\xb8\xe3\x81\xb3\xe3\x81\xab\xe3\x82\x89\xe3\x81\xbf", + "\xe3\x82\x86\xe3\x82\x81\xe3\x81\x8f\xe3\x81\x84", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x82\xac\xe3\x82\xb9", + "\xe3\x81\x9f\xe3\x81\xbe\xe3\x81\xaa\xe3\x81\x92", + "\xe3\x81\x8d\xe3\x82\x85\xe3\x81\x86\xe3\x81\x91\xe3\x81\xa4", + "\xe3\x81\x82\xe3\x81\x8f\xe3\x81\xbe\xe3\x81\xae\xe3\x82\xad\xe3\x83\x83\xe3\x82\xb9", + "\xe3\x82\xb4\xe3\x83\x83\xe3\x83\x89\xe3\x83\x90\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x81\xb8\xe3\x82\x93\xe3\x81\x97\xe3\x82\x93", + "\xe3\x81\x82\xe3\x82\x8f", + "\xe3\x83\x94\xe3\x83\xa8\xe3\x83\x94\xe3\x83\xa8\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x82\xad\xe3\x83\x8e\xe3\x82\xb3\xe3\x81\xae\xe3\x81\xbb\xe3\x81\x86\xe3\x81\x97", + "\xe3\x83\x95\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa5", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xb3\xe3\x82\xa6\xe3\x82\xa7\xe3\x83\xbc\xe3\x83\x96", + "\xe3\x81\xaf\xe3\x81\xad\xe3\x82\x8b", + "\xe3\x81\xa8\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x82\xaf\xe3\x83\xa9\xe3\x83\x96\xe3\x83\x8f\xe3\x83\xb3\xe3\x83\x9e\xe3\x83\xbc", + "\xe3\x81\xa0\xe3\x81\x84\xe3\x81\xb0\xe3\x81\x8f\xe3\x81\xaf\xe3\x81\xa4", + "\xe3\x81\xbf\xe3\x81\xa0\xe3\x82\x8c\xe3\x81\xb2\xe3\x81\xa3\xe3\x81\x8b\xe3\x81\x8d", + "\xe3\x83\x9b\xe3\x83\x8d\xe3\x83\x96\xe3\x83\xbc\xe3\x83\xa1\xe3\x83\xa9\xe3\x83\xb3", + "\xe3\x81\xad\xe3\x82\x80\xe3\x82\x8b", + "\xe3\x81\x84\xe3\x82\x8f\xe3\x81\xaa\xe3\x81\xa0\xe3\x82\x8c", + "\xe3\x81\xb2\xe3\x81\xa3\xe3\x81\x95\xe3\x81\xa4\xe3\x81\xbe\xe3\x81\x88\xe3\x81\xb0", + "\xe3\x81\x8b\xe3\x81\x8f\xe3\x81\xb0\xe3\x82\x8b", + "\xe3\x83\x86\xe3\x82\xaf\xe3\x82\xb9\xe3\x83\x81\xe3\x83\xa3\xe3\x83\xbc", + "\xe3\x83\x88\xe3\x83\xa9\xe3\x82\xa4\xe3\x82\xa2\xe3\x82\xbf\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x81\x84\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\xae\xe3\x81\xbe\xe3\x81\x88\xe3\x81\xb0", + "\xe3\x81\x8d\xe3\x82\x8a\xe3\x81\x95\xe3\x81\x8f", + "\xe3\x81\xbf\xe3\x81\x8c\xe3\x82\x8f\xe3\x82\x8a", + "\xe3\x82\x8f\xe3\x82\x8b\xe3\x81\x82\xe3\x81\x8c\xe3\x81\x8d", + "\xe3\x82\xb9\xe3\x82\xb1\xe3\x83\x83\xe3\x83\x81", + "\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x97\xe3\x83\xab\xe3\x82\xad\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x81\xa9\xe3\x82\x8d\xe3\x81\xbc\xe3\x81\x86", + "\xe3\x82\xaf\xe3\x83\xa2\xe3\x81\xae\xe3\x81\x99", + "\xe3\x81\x93\xe3\x81\x93\xe3\x82\x8d\xe3\x81\xae\xe3\x82\x81", + "\xe3\x81\x82\xe3\x81\x8f\xe3\x82\x80", + "\xe3\x81\x8b\xe3\x81\x88\xe3\x82\x93\xe3\x81\x90\xe3\x82\x8b\xe3\x81\xbe", + "\xe3\x81\x84\xe3\x81\xb3\xe3\x81\x8d", + "\xe3\x81\xae\xe3\x82\x8d\xe3\x81\x84", + "\xe3\x81\x98\xe3\x81\x9f\xe3\x81\xb0\xe3\x81\x9f", + "\xe3\x83\x86\xe3\x82\xaf\xe3\x82\xb9\xe3\x83\x81\xe3\x83\xa3\xe3\x83\xbc\xef\xbc\x92", + "\xe3\x82\xa8\xe3\x82\xa2\xe3\x83\xad\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\x88", + "\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\xbb\xe3\x81\x86\xe3\x81\x97", + "\xe3\x81\x8d\xe3\x81\x97\xe3\x81\x8b\xe3\x81\x84\xe3\x81\x9b\xe3\x81\x84", + "\xe3\x81\x86\xe3\x82\x89\xe3\x81\xbf", + "\xe3\x81\x93\xe3\x81\xaa\xe3\x82\x86\xe3\x81\x8d", + "\xe3\x81\xbe\xe3\x82\x82\xe3\x82\x8b", + "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x8f\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\x93\xe3\x82\x8f\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x8a", + "\xe3\x81\xa0\xe3\x81\xbe\xe3\x81\x97\xe3\x81\x86\xe3\x81\xa1", + "\xe3\x81\xa6\xe3\x82\x93\xe3\x81\x97\xe3\x81\xae\xe3\x82\xad\xe3\x83\x83\xe3\x82\xb9", + "\xe3\x81\xaf\xe3\x82\x89\xe3\x81\xa0\xe3\x81\x84\xe3\x81\x93", + "\xe3\x83\x98\xe3\x83\x89\xe3\x83\xad\xe3\x81\xb0\xe3\x81\x8f\xe3\x81\xa0\xe3\x82\x93", + "\xe3\x81\xa9\xe3\x82\x8d\xe3\x81\x8b\xe3\x81\x91", + "\xe3\x82\xaa\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xb3\xe3\x81\xbb\xe3\x81\x86", + "\xe3\x81\xbe\xe3\x81\x8d\xe3\x81\xb3\xe3\x81\x97", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x98\xe3\x81\xbb\xe3\x81\x86", + "\xe3\x81\xbf\xe3\x82\x84\xe3\x81\xb6\xe3\x82\x8b", + "\xe3\x81\xbf\xe3\x81\xa1\xe3\x81\xa5\xe3\x82\x8c", + "\xe3\x81\xbb\xe3\x82\x8d\xe3\x81\xb3\xe3\x81\xae\xe3\x81\x86\xe3\x81\x9f", + "\xe3\x81\x93\xe3\x81\x94\xe3\x81\x88\xe3\x82\x8b\xe3\x81\x8b\xe3\x81\x9c", + "\xe3\x81\xbf\xe3\x81\x8d\xe3\x82\x8a", + "\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xb3\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa5", + "\xe3\x83\xad\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xaa\xe3\x83\xb3", + "\xe3\x81\x92\xe3\x81\x8d\xe3\x82\x8a\xe3\x82\x93", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x82\xe3\x82\x89\xe3\x81\x97", + "\xe3\x82\xae\xe3\x82\xac\xe3\x83\x89\xe3\x83\xac\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x81\x93\xe3\x82\x89\xe3\x81\x88\xe3\x82\x8b", + "\xe3\x81\x82\xe3\x81\xbe\xe3\x81\x88\xe3\x82\x8b", + "\xe3\x81\x93\xe3\x82\x8d\xe3\x81\x8c\xe3\x82\x8b", + "\xe3\x81\xbf\xe3\x81\xad\xe3\x81\x86\xe3\x81\xa1", + "\xe3\x81\x84\xe3\x81\xb0\xe3\x82\x8b", + "\xe3\x83\x9f\xe3\x83\xab\xe3\x82\xaf\xe3\x81\xae\xe3\x81\xbf", + "\xe3\x82\xb9\xe3\x83\x91\xe3\x83\xbc\xe3\x82\xaf", + "\xe3\x82\x8c\xe3\x82\x93\xe3\x81\x9e\xe3\x81\x8f\xe3\x81\x8e\xe3\x82\x8a", + "\xe3\x81\xaf\xe3\x81\x8c\xe3\x81\xad\xe3\x81\xae\xe3\x81\xa4\xe3\x81\xb0\xe3\x81\x95", + "\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\x84\xe3\x81\xbe\xe3\x81\xaa\xe3\x81\x96\xe3\x81\x97", + "\xe3\x83\xa1\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xad", + "\xe3\x81\xad\xe3\x81\x94\xe3\x81\xa8", + "\xe3\x81\x84\xe3\x82\x84\xe3\x81\x97\xe3\x81\xae\xe3\x81\x99\xe3\x81\x9a", + "\xe3\x81\x8a\xe3\x82\x93\xe3\x81\x8c\xe3\x81\x88\xe3\x81\x97", + "\xe3\x83\x97\xe3\x83\xac\xe3\x82\xbc\xe3\x83\xb3\xe3\x83\x88", + "\xe3\x82\x84\xe3\x81\xa4\xe3\x81\x82\xe3\x81\x9f\xe3\x82\x8a", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\xb4\xe3\x81\xae\xe3\x81\xbe\xe3\x82\x82\xe3\x82\x8a", + "\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xbf\xe3\x82\x8f\xe3\x81\x91", + "\xe3\x81\x9b\xe3\x81\x84\xe3\x81\xaa\xe3\x82\x8b\xe3\x81\xbb\xe3\x81\xae\xe3\x81\x8a", + "\xe3\x83\x9e\xe3\x82\xb0\xe3\x83\x8b\xe3\x83\x81\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x81\xb0\xe3\x81\x8f\xe3\x82\x8c\xe3\x81\xa4\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86\xe3\x81\xae\xe3\x81\x84\xe3\x81\xb6\xe3\x81\x8d", + "\xe3\x83\x90\xe3\x83\x88\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\x83\xe3\x83\x81", + "\xe3\x82\xa2\xe3\x83\xb3\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x81\x8a\xe3\x81\x84\xe3\x81\x86\xe3\x81\xa1", + "\xe3\x81\x93\xe3\x81\x86\xe3\x81\x9d\xe3\x81\x8f\xe3\x82\xb9\xe3\x83\x94\xe3\x83\xb3", + "\xe3\x81\x82\xe3\x81\xbe\xe3\x81\x84\xe3\x81\x8b\xe3\x81\x8a\xe3\x82\x8a", + "\xe3\x82\xa2\xe3\x82\xa4\xe3\x82\xa2\xe3\x83\xb3\xe3\x83\x86\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\xab\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc", + "\xe3\x81\x82\xe3\x81\xa6\xe3\x81\xbf\xe3\x81\xaa\xe3\x81\x92", + "\xe3\x81\x82\xe3\x81\x95\xe3\x81\xae\xe3\x81\xb2\xe3\x81\x96\xe3\x81\x97", + "\xe3\x81\x93\xe3\x81\x86\xe3\x81\x94\xe3\x81\x86\xe3\x81\x9b\xe3\x81\x84", + "\xe3\x81\xa4\xe3\x81\x8d\xe3\x81\xae\xe3\x81\xb2\xe3\x81\x8b\xe3\x82\x8a", + "\xe3\x82\x81\xe3\x81\x96\xe3\x82\x81\xe3\x82\x8b\xe3\x83\x91\xe3\x83\xaf\xe3\x83\xbc", + "\xe3\x82\xaf\xe3\x83\xad\xe3\x82\xb9\xe3\x83\x81\xe3\x83\xa7\xe3\x83\x83\xe3\x83\x97", + "\xe3\x81\x9f\xe3\x81\xa4\xe3\x81\xbe\xe3\x81\x8d", + "\xe3\x81\x82\xe3\x81\xbe\xe3\x81\x94\xe3\x81\x84", + "\xe3\x81\xab\xe3\x81\xbb\xe3\x82\x93\xe3\x81\xb0\xe3\x82\x8c", + "\xe3\x81\x8b\xe3\x81\xbf\xe3\x81\x8f\xe3\x81\xa0\xe3\x81\x8f", + "\xe3\x83\x9f\xe3\x83\xa9\xe3\x83\xbc\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x81\x98\xe3\x81\x93\xe3\x81\x82\xe3\x82\x93\xe3\x81\x98", + "\xe3\x81\x97\xe3\x82\x93\xe3\x81\x9d\xe3\x81\x8f", + "\xe3\x81\x92\xe3\x82\x93\xe3\x81\x97\xe3\x81\xae\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89", + "\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\x89\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x81\xbf\xe3\x82\x89\xe3\x81\x84\xe3\x82\x88\xe3\x81\xa1", + "\xe3\x81\x84\xe3\x82\x8f\xe3\x81\x8f\xe3\x81\xa0\xe3\x81\x8d", + "\xe3\x81\x86\xe3\x81\x9a\xe3\x81\x97\xe3\x81\x8a", + "\xe3\x81\xb5\xe3\x81\x8f\xe3\x82\x8d\xe3\x81\xa0\xe3\x81\x9f\xe3\x81\x8d", + "\xe3\x81\xad\xe3\x81\x93\xe3\x81\xa0\xe3\x81\xbe\xe3\x81\x97", + "\xe3\x81\x95\xe3\x82\x8f\xe3\x81\x90", + "\xe3\x81\x9f\xe3\x81\x8f\xe3\x82\x8f\xe3\x81\x88\xe3\x82\x8b", + "\xe3\x81\xaf\xe3\x81\x8d\xe3\x81\xa0\xe3\x81\x99", + "\xe3\x81\xae\xe3\x81\xbf\xe3\x81\x93\xe3\x82\x80", + "\xe3\x81\xad\xe3\x81\xa3\xe3\x81\xb7\xe3\x81\x86", + "\xe3\x81\x82\xe3\x82\x89\xe3\x82\x8c", + "\xe3\x81\x84\xe3\x81\xa1\xe3\x82\x83\xe3\x82\x82\xe3\x82\x93", + "\xe3\x81\x8a\xe3\x81\xa0\xe3\x81\xa6\xe3\x82\x8b", + "\xe3\x81\x8a\xe3\x81\xab\xe3\x81\xb3", + "\xe3\x81\x8a\xe3\x81\x8d\xe3\x81\xbf\xe3\x82\x84\xe3\x81\x92", + "\xe3\x81\x8b\xe3\x82\x89\xe3\x81\x92\xe3\x82\x93\xe3\x81\x8d", + "\xe3\x81\x8d\xe3\x81\x82\xe3\x81\x84\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\x8d\xe3\x81\xa4\xe3\x81\x91", + "\xe3\x81\x93\xe3\x81\xae\xe3\x82\x86\xe3\x81\xb3\xe3\x81\xa8\xe3\x81\xbe\xe3\x82\x8c", + "\xe3\x81\x97\xe3\x81\x9c\xe3\x82\x93\xe3\x81\xae\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89", + "\xe3\x81\x98\xe3\x82\x85\xe3\x81\x86\xe3\x81\xa7\xe3\x82\x93", + "\xe3\x81\xa1\xe3\x82\x87\xe3\x81\x86\xe3\x81\xaf\xe3\x81\xa4", + "\xe3\x81\xa6\xe3\x81\xa0\xe3\x81\x99\xe3\x81\x91", + "\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x81\xaa\xe3\x82\x8a\xe3\x81\x8d\xe3\x82\x8a", + "\xe3\x81\xad\xe3\x81\x8c\xe3\x81\x84\xe3\x81\x94\xe3\x81\xa8", + "\xe3\x81\xad\xe3\x81\x93\xe3\x81\xae\xe3\x81\xa6", + "\xe3\x81\xad\xe3\x82\x92\xe3\x81\xaf\xe3\x82\x8b", + "\xe3\x81\xb0\xe3\x81\x8b\xe3\x81\xa2\xe3\x81\x8b\xe3\x82\x89", + "\xe3\x83\x9e\xe3\x82\xb8\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x83\xaa\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xab", + "\xe3\x83\xaa\xe3\x83\x99\xe3\x83\xb3\xe3\x82\xb8", + "\xe3\x81\x8b\xe3\x82\x8f\xe3\x82\x89\xe3\x82\x8f\xe3\x82\x8a", + "\xe3\x81\x82\xe3\x81\x8f\xe3\x81\xb3", + "\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x8d\xe3\x81\x8a\xe3\x81\xa8\xe3\x81\x99", + "\xe3\x81\x8c\xe3\x82\x80\xe3\x81\x97\xe3\x82\x83\xe3\x82\x89", + "\xe3\x81\xb5\xe3\x82\x93\xe3\x81\x8b", + "\xe3\x82\xb9\xe3\x82\xad\xe3\x83\xab\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x97", + "\xe3\x81\xb5\xe3\x81\x86\xe3\x81\x84\xe3\x82\x93", + "\xe3\x83\xaa\xe3\x83\x95\xe3\x83\xac\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa5", + "\xe3\x81\x8a\xe3\x82\x93\xe3\x81\xad\xe3\x82\x93", + "\xe3\x82\x88\xe3\x81\x93\xe3\x81\xa9\xe3\x82\x8a", + "\xe3\x81\xb2\xe3\x81\xbf\xe3\x81\xa4\xe3\x81\xae\xe3\x81\xa1\xe3\x81\x8b\xe3\x82\x89", + "\xe3\x83\x80\xe3\x82\xa4\xe3\x83\x93\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x81\xa4\xe3\x81\xa3\xe3\x81\xb1\xe3\x82\x8a", + "\xe3\x81\xbb\xe3\x81\x94\xe3\x81\x97\xe3\x82\x87\xe3\x81\x8f", + "\xe3\x81\xbb\xe3\x81\x9f\xe3\x82\x8b\xe3\x81\xb3", + "\xe3\x83\xa9\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x91\xe3\x83\xbc\xe3\x82\xb8", + "\xe3\x83\x9f\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x95\xe3\x82\xa7\xe3\x82\xb6\xe3\x83\xbc\xe3\x83\x80\xe3\x83\xb3\xe3\x82\xb9", + "\xe3\x83\x95\xe3\x83\xa9\xe3\x83\x95\xe3\x83\xa9\xe3\x83\x80\xe3\x83\xb3\xe3\x82\xb9", + "\xe3\x83\x96\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xba\xe3\x82\xad\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x81\xa9\xe3\x82\x8d\xe3\x81\x82\xe3\x81\x9d\xe3\x81\xb3", + "\xe3\x82\xa2\xe3\x82\xa4\xe3\x82\xb9\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8b\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xab\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x9c\xe3\x82\xa4\xe3\x82\xb9", + "\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xa9\xe3\x81\x8f\xe3\x81\xae\xe3\x82\xad\xe3\x83\x90", + "\xe3\x83\x96\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xaf\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc", + "\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x90\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x89\xe3\x83\xad\xe3\x82\xab\xe3\x83\x8e\xe3\x83\xb3", + "\xe3\x82\xb3\xe3\x83\xa1\xe3\x83\x83\xe3\x83\x88\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\x8a\xe3\x81\xa9\xe3\x82\x8d\xe3\x81\x8b\xe3\x81\x99", + "\xe3\x82\xa6\xe3\x82\xa7\xe3\x82\xb6\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xa2\xe3\x83\xad\xe3\x83\x9e\xe3\x82\xbb\xe3\x83\xa9\xe3\x83\x94\xe3\x83\xbc", + "\xe3\x81\x86\xe3\x81\x9d\xe3\x81\xaa\xe3\x81\x8d", + "\xe3\x82\xa8\xe3\x82\xa2\xe3\x82\xab\xe3\x83\x83\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\x90\xe3\x83\xbc\xe3\x83\x92\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x81\x8b\xe3\x81\x8e\xe3\x82\x8f\xe3\x81\x91\xe3\x82\x8b", + "\xe3\x81\x8c\xe3\x82\x93\xe3\x81\x9b\xe3\x81\x8d\xe3\x81\xb5\xe3\x81\x86\xe3\x81\x98", + "\xe3\x81\x8e\xe3\x82\x93\xe3\x81\x84\xe3\x82\x8d\xe3\x81\xae\xe3\x81\x8b\xe3\x81\x9c", + "\xe3\x81\x8d\xe3\x82\x93\xe3\x81\x9e\xe3\x81\x8f\xe3\x81\x8a\xe3\x82\x93", + "\xe3\x81\x8f\xe3\x81\x95\xe3\x81\xb6\xe3\x81\x88", + "\xe3\x81\x8f\xe3\x81\x99\xe3\x81\x90\xe3\x82\x8b", + "\xe3\x82\xb3\xe3\x82\xb9\xe3\x83\xa2\xe3\x83\x91\xe3\x83\xaf\xe3\x83\xbc", + "\xe3\x81\x97\xe3\x81\x8a\xe3\x81\xb5\xe3\x81\x8d", + "\xe3\x82\xb7\xe3\x82\xb0\xe3\x83\x8a\xe3\x83\xab\xe3\x83\x93\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\x89\xe3\x83\xbc\xe3\x83\x91\xe3\x83\xb3\xe3\x83\x81", + "\xe3\x81\x98\xe3\x82\x93\xe3\x81\xa4\xe3\x81\x86\xe3\x82\x8a\xe3\x81\x8d", + "\xe3\x82\xb9\xe3\x82\xab\xe3\x82\xa4\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x91\xe3\x83\xbc", + "\xe3\x81\x99\xe3\x81\xaa\xe3\x81\x98\xe3\x81\x94\xe3\x81\x8f", + "\xe3\x81\x9c\xe3\x81\xa3\xe3\x81\x9f\xe3\x81\x84\xe3\x82\x8c\xe3\x81\x84\xe3\x81\xa9", + "\xe3\x81\xa0\xe3\x81\x8f\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86", + "\xe3\x82\xbf\xe3\x83\x8d\xe3\x83\x9e\xe3\x82\xb7\xe3\x83\xb3\xe3\x82\xac\xe3\x83\xb3", + "\xe3\x81\xa4\xe3\x81\xb0\xe3\x82\x81\xe3\x81\x8c\xe3\x81\x88\xe3\x81\x97", + "\xe3\x81\xa4\xe3\x82\x89\xe3\x82\x89\xe3\x81\xb0\xe3\x82\x8a", + "\xe3\x81\xa6\xe3\x81\xa3\xe3\x81\xba\xe3\x81\x8d", + "\xe3\x81\xa8\xe3\x81\x8a\xe3\x81\x9b\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86", + "\xe3\x81\xa8\xe3\x81\x8a\xe3\x81\xbc\xe3\x81\x88", + "\xe3\x83\x89\xe3\x83\xa9\xe3\x82\xb4\xe3\x83\xb3\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc", + "\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x89\xe3\x83\x97\xe3\x83\xa9\xe3\x83\xb3\xe3\x83\x88", + "\xe3\x83\x93\xe3\x83\xab\xe3\x83\x89\xe3\x82\xa2\xe3\x83\x83\xe3\x83\x97", + "\xe3\x81\xa8\xe3\x81\xb3\xe3\x81\xaf\xe3\x81\xad\xe3\x82\x8b", + "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x89\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\x83\xe3\x83\x88", + "\xe3\x83\x9d\xe3\x82\xa4\xe3\x82\xba\xe3\x83\xb3\xe3\x83\x86\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x81\xbb\xe3\x81\x97\xe3\x81\x8c\xe3\x82\x8b", + "\xe3\x83\x9c\xe3\x83\xab\xe3\x83\x86\xe3\x83\x83\xe3\x82\xab\xe3\x83\xbc", + "\xe3\x83\x9e\xe3\x82\xb8\xe3\x82\xab\xe3\x83\xab\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x95", + "\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\x82\xe3\x81\x9d\xe3\x81\xb3", + "\xe3\x82\x81\xe3\x81\x84\xe3\x81\x9d\xe3\x81\x86", + "\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x95\xe3\x83\x96\xe3\x83\xac\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x82\x8a\xe3\x82\x85\xe3\x81\x86\xe3\x81\xae\xe3\x81\xbe\xe3\x81\x84", + "\xe3\x83\xad\xe3\x83\x83\xe3\x82\xaf\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\x88", + "\xe3\x81\xa7\xe3\x82\x93\xe3\x81\x92\xe3\x81\x8d\xe3\x81\xaf", + "\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\xae\xe3\x81\xaf\xe3\x81\xa9\xe3\x81\x86", + "\xe3\x81\xaf\xe3\x82\x81\xe3\x81\xa4\xe3\x81\xae\xe3\x81\xad\xe3\x81\x8c\xe3\x81\x84", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xb3\xe3\x83\x96\xe3\x83\xbc\xe3\x82\xb9\xe3\x83\x88", +}; + + +} +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Core/Detail/SpeciesNames.cpp b/LibPkmGC/src/LibPkmGC/Core/Detail/SpeciesNames.cpp new file mode 100644 index 0000000..2b4b788 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Detail/SpeciesNames.cpp @@ -0,0 +1,2362 @@ +#include + + +namespace LibPkmGC { +namespace Localization { +namespace Detail { + +namespace Species { + +const char **names[7] = { NULL, japaneseNames, englishNames, germanNames, frenchNames, italianNames, spanishNames }; + +const char *englishNames[388] = { + "(None)", + "BULBASAUR", + "IVYSAUR", + "VENUSAUR", + "CHARMANDER", + "CHARMELEON", + "CHARIZARD", + "SQUIRTLE", + "WARTORTLE", + "BLASTOISE", + "CATERPIE", + "METAPOD", + "BUTTERFREE", + "WEEDLE", + "KAKUNA", + "BEEDRILL", + "PIDGEY", + "PIDGEOTTO", + "PIDGEOT", + "RATTATA", + "RATICATE", + "SPEAROW", + "FEAROW", + "EKANS", + "ARBOK", + "PIKACHU", + "RAICHU", + "SANDSHREW", + "SANDSLASH", + "NIDORAN\xe2\x99\x80", + "NIDORINA", + "NIDOQUEEN", + "NIDORAN\xe2\x99\x82", + "NIDORINO", + "NIDOKING", + "CLEFAIRY", + "CLEFABLE", + "VULPIX", + "NINETALES", + "JIGGLYPUFF", + "WIGGLYTUFF", + "ZUBAT", + "GOLBAT", + "ODDISH", + "GLOOM", + "VILEPLUME", + "PARAS", + "PARASECT", + "VENONAT", + "VENOMOTH", + "DIGLETT", + "DUGTRIO", + "MEOWTH", + "PERSIAN", + "PSYDUCK", + "GOLDUCK", + "MANKEY", + "PRIMEAPE", + "GROWLITHE", + "ARCANINE", + "POLIWAG", + "POLIWHIRL", + "POLIWRATH", + "ABRA", + "KADABRA", + "ALAKAZAM", + "MACHOP", + "MACHOKE", + "MACHAMP", + "BELLSPROUT", + "WEEPINBELL", + "VICTREEBEL", + "TENTACOOL", + "TENTACRUEL", + "GEODUDE", + "GRAVELER", + "GOLEM", + "PONYTA", + "RAPIDASH", + "SLOWPOKE", + "SLOWBRO", + "MAGNEMITE", + "MAGNETON", + "FARFETCH'D", + "DODUO", + "DODRIO", + "SEEL", + "DEWGONG", + "GRIMER", + "MUK", + "SHELLDER", + "CLOYSTER", + "GASTLY", + "HAUNTER", + "GENGAR", + "ONIX", + "DROWZEE", + "HYPNO", + "KRABBY", + "KINGLER", + "VOLTORB", + "ELECTRODE", + "EXEGGCUTE", + "EXEGGUTOR", + "CUBONE", + "MAROWAK", + "HITMONLEE", + "HITMONCHAN", + "LICKITUNG", + "KOFFING", + "WEEZING", + "RHYHORN", + "RHYDON", + "CHANSEY", + "TANGELA", + "KANGASKHAN", + "HORSEA", + "SEADRA", + "GOLDEEN", + "SEAKING", + "STARYU", + "STARMIE", + "MR. MIME", + "SCYTHER", + "JYNX", + "ELECTABUZZ", + "MAGMAR", + "PINSIR", + "TAUROS", + "MAGIKARP", + "GYARADOS", + "LAPRAS", + "DITTO", + "EEVEE", + "VAPOREON", + "JOLTEON", + "FLAREON", + "PORYGON", + "OMANYTE", + "OMASTAR", + "KABUTO", + "KABUTOPS", + "AERODACTYL", + "SNORLAX", + "ARTICUNO", + "ZAPDOS", + "MOLTRES", + "DRATINI", + "DRAGONAIR", + "DRAGONITE", + "MEWTWO", + "MEW", + "CHIKORITA", + "BAYLEEF", + "MEGANIUM", + "CYNDAQUIL", + "QUILAVA", + "TYPHLOSION", + "TOTODILE", + "CROCONAW", + "FERALIGATR", + "SENTRET", + "FURRET", + "HOOTHOOT", + "NOCTOWL", + "LEDYBA", + "LEDIAN", + "SPINARAK", + "ARIADOS", + "CROBAT", + "CHINCHOU", + "LANTURN", + "PICHU", + "CLEFFA", + "IGGLYBUFF", + "TOGEPI", + "TOGETIC", + "NATU", + "XATU", + "MAREEP", + "FLAAFFY", + "AMPHAROS", + "BELLOSSOM", + "MARILL", + "AZUMARILL", + "SUDOWOODO", + "POLITOED", + "HOPPIP", + "SKIPLOOM", + "JUMPLUFF", + "AIPOM", + "SUNKERN", + "SUNFLORA", + "YANMA", + "WOOPER", + "QUAGSIRE", + "ESPEON", + "UMBREON", + "MURKROW", + "SLOWKING", + "MISDREAVUS", + "UNOWN", + "WOBBUFFET", + "GIRAFARIG", + "PINECO", + "FORRETRESS", + "DUNSPARCE", + "GLIGAR", + "STEELIX", + "SNUBBULL", + "GRANBULL", + "QWILFISH", + "SCIZOR", + "SHUCKLE", + "HERACROSS", + "SNEASEL", + "TEDDIURSA", + "URSARING", + "SLUGMA", + "MAGCARGO", + "SWINUB", + "PILOSWINE", + "CORSOLA", + "REMORAID", + "OCTILLERY", + "DELIBIRD", + "MANTINE", + "SKARMORY", + "HOUNDOUR", + "HOUNDOOM", + "KINGDRA", + "PHANPY", + "DONPHAN", + "PORYGON2", + "STANTLER", + "SMEARGLE", + "TYROGUE", + "HITMONTOP", + "SMOOCHUM", + "ELEKID", + "MAGBY", + "MILTANK", + "BLISSEY", + "RAIKOU", + "ENTEI", + "SUICUNE", + "LARVITAR", + "PUPITAR", + "TYRANITAR", + "LUGIA", + "HO-OH", + "CELEBI", + "TREECKO", + "GROVYLE", + "SCEPTILE", + "TORCHIC", + "COMBUSKEN", + "BLAZIKEN", + "MUDKIP", + "MARSHTOMP", + "SWAMPERT", + "POOCHYENA", + "MIGHTYENA", + "ZIGZAGOON", + "LINOONE", + "WURMPLE", + "SILCOON", + "BEAUTIFLY", + "CASCOON", + "DUSTOX", + "LOTAD", + "LOMBRE", + "LUDICOLO", + "SEEDOT", + "NUZLEAF", + "SHIFTRY", + "TAILLOW", + "SWELLOW", + "WINGULL", + "PELIPPER", + "RALTS", + "KIRLIA", + "GARDEVOIR", + "SURSKIT", + "MASQUERAIN", + "SHROOMISH", + "BRELOOM", + "SLAKOTH", + "VIGOROTH", + "SLAKING", + "NINCADA", + "NINJASK", + "SHEDINJA", + "WHISMUR", + "LOUDRED", + "EXPLOUD", + "MAKUHITA", + "HARIYAMA", + "AZURILL", + "NOSEPASS", + "SKITTY", + "DELCATTY", + "SABLEYE", + "MAWILE", + "ARON", + "LAIRON", + "AGGRON", + "MEDITITE", + "MEDICHAM", + "ELECTRIKE", + "MANECTRIC", + "PLUSLE", + "MINUN", + "VOLBEAT", + "ILLUMISE", + "ROSELIA", + "GULPIN", + "SWALOT", + "CARVANHA", + "SHARPEDO", + "WAILMER", + "WAILORD", + "NUMEL", + "CAMERUPT", + "TORKOAL", + "SPOINK", + "GRUMPIG", + "SPINDA", + "TRAPINCH", + "VIBRAVA", + "FLYGON", + "CACNEA", + "CACTURNE", + "SWABLU", + "ALTARIA", + "ZANGOOSE", + "SEVIPER", + "LUNATONE", + "SOLROCK", + "BARBOACH", + "WHISCASH", + "CORPHISH", + "CRAWDAUNT", + "BALTOY", + "CLAYDOL", + "LILEEP", + "CRADILY", + "ANORITH", + "ARMALDO", + "FEEBAS", + "MILOTIC", + "CASTFORM", + "KECLEON", + "SHUPPET", + "BANETTE", + "DUSKULL", + "DUSCLOPS", + "TROPIUS", + "CHIMECHO", + "ABSOL", + "WYNAUT", + "SNORUNT", + "GLALIE", + "SPHEAL", + "SEALEO", + "WALREIN", + "CLAMPERL", + "HUNTAIL", + "GOREBYSS", + "RELICANTH", + "LUVDISC", + "BAGON", + "SHELGON", + "SALAMENCE", + "BELDUM", + "METANG", + "METAGROSS", + "REGIROCK", + "REGICE", + "REGISTEEL", + "LATIAS", + "LATIOS", + "KYOGRE", + "GROUDON", + "RAYQUAZA", + "JIRACHI", + "DEOXYS", + "BONSLY", // XD only +}; + +const char *frenchNames[388] = { + "(Rien)", + "BULBIZARRE", + "HERBIZARRE", + "FLORIZARRE", + "SALAMECHE", + "REPTINCEL", + "DRACAUFEU", + "CARAPUCE", + "CARABAFFE", + "TORTANK", + "CHENIPAN", + "CHRYSACIER", + "PAPILUSION", + "ASPICOT", + "COCONFORT", + "DARDARGNAN", + "ROUCOOL", + "ROUCOUPS", + "ROUCARNAGE", + "RATTATA", + "RATTATAC", + "PIAFABEC", + "RAPASDEPIC", + "ABO", + "ARBOK", + "PIKACHU", + "RAICHU", + "SABELETTE", + "SABLAIREAU", + "NIDORAN\xe2\x99\x80", + "NIDORINA", + "NIDOQUEEN", + "NIDORAN\xe2\x99\x82", + "NIDORINO", + "NIDOKING", + "MELOFEE", + "MELODELFE", + "GOUPIX", + "FEUNARD", + "RONDOUDOU", + "GRODOUDOU", + "NOSFERAPTI", + "NOSFERALTO", + "MYSTHERBE", + "ORTIDE", + "RAFFLESIA", + "PARAS", + "PARASECT", + "MIMITOSS", + "AEROMITE", + "TAUPIQUEUR", + "TRIOPIKEUR", + "MIAOUSS", + "PERSIAN", + "PSYKOKWAK", + "AKWAKWAK", + "FEROSINGE", + "COLOSSINGE", + "CANINOS", + "ARCANIN", + "PTITARD", + "TETARTE", + "TARTARD", + "ABRA", + "KADABRA", + "ALAKAZAM", + "MACHOC", + "MACHOPEUR", + "MACKOGNEUR", + "CHETIFLOR", + "BOUSTIFLOR", + "EMPIFLOR", + "TENTACOOL", + "TENTACRUEL", + "RACAILLOU", + "GRAVALANCH", + "GROLEM", + "PONYTA", + "GALOPA", + "RAMOLOSS", + "FLAGADOSS", + "MAGNETI", + "MAGNETON", + "CANARTICHO", + "DODUO", + "DODRIO", + "OTARIA", + "LAMANTINE", + "TADMORV", + "GROTADMORV", + "KOKIYAS", + "CRUSTABRI", + "FANTOMINUS", + "SPECTRUM", + "ECTOPLASMA", + "ONIX", + "SOPORIFIK", + "HYPNOMADE", + "KRABBY", + "KRABBOSS", + "VOLTORBE", + "ELECTRODE", + "NOEUNOEUF", + "NOADKOKO", + "OSSELAIT", + "OSSATUEUR", + "KICKLEE", + "TYGNON", + "EXCELANGUE", + "SMOGO", + "SMOGOGO", + "RHINOCORNE", + "RHINOFEROS", + "LEVEINARD", + "SAQUEDENEU", + "KANGOUREX", + "HYPOTREMPE", + "HYPOCEAN", + "POISSIRENE", + "POISSOROY", + "STARI", + "STAROSS", + "M. MIME", + "INSECATEUR", + "LIPPOUTOU", + "ELEKTEK", + "MAGMAR", + "SCARABRUTE", + "TAUROS", + "MAGICARPE", + "LEVIATOR", + "LOKHLASS", + "METAMORPH", + "EVOLI", + "AQUALI", + "VOLTALI", + "PYROLI", + "PORYGON", + "AMONITA", + "AMONISTAR", + "KABUTO", + "KABUTOPS", + "PTERA", + "RONFLEX", + "ARTIKODIN", + "ELECTHOR", + "SULFURA", + "MINIDRACO", + "DRACO", + "DRACOLOSSE", + "MEWTWO", + "MEW", + "GERMIGNON", + "MACRONIUM", + "MEGANIUM", + "HERICENDRE", + "FEURISSON", + "TYPHLOSION", + "KAIMINUS", + "CROCRODIL", + "ALIGATUEUR", + "FOUINETTE", + "FOUINAR", + "HOOTHOOT", + "NOARFANG", + "COXY", + "COXYCLAQUE", + "MIMIGAL", + "MIGALOS", + "NOSTENFER", + "LOUPIO", + "LANTURN", + "PICHU", + "MELO", + "TOUDOUDOU", + "TOGEPI", + "TOGETIC", + "NATU", + "XATU", + "WATTOUAT", + "LAINERGIE", + "PHARAMP", + "JOLIFLOR", + "MARILL", + "AZUMARILL", + "SIMULARBRE", + "TARPAUD", + "GRANIVOL", + "FLORAVOL", + "COTOVOL", + "CAPUMAIN", + "TOURNEGRIN", + "HELIATRONC", + "YANMA", + "AXOLOTO", + "MARAISTE", + "MENTALI", + "NOCTALI", + "CORNEBRE", + "ROIGADA", + "FEUFOREVE", + "ZARBI", + "QULBUTOKE", + "GIRAFARIG", + "POMDEPIK", + "FORETRESS", + "INSOLOURDO", + "SCORPLANE", + "STEELIX", + "SNUBBULL", + "GRANBULL", + "QWILFISH", + "CIZAYOX", + "CARATROC", + "SCARHINO", + "FARFURET", + "TEDDIURSA", + "URSARING", + "LIMAGMA", + "VOLCAROPOD", + "MARCACRIN", + "COCHIGNON", + "CORAYON", + "REMORAID", + "OCTILLERY", + "CADOIZO", + "DEMANTA", + "AIRMURE", + "MALOSSE", + "DEMOLOSSE", + "HYPOROI", + "PHANPY", + "DONPHAN", + "PORYGON2", + "CERFROUSSE", + "QUEULORIOR", + "DEBUGANT", + "KAPOERA", + "LIPPOUTI", + "ELEKID", + "MAGBY", + "ECREMEUH", + "LEUPHORIE", + "RAIKOU", + "ENTEI", + "SUICUNE", + "EMBRYLEX", + "YMPHECT", + "TYRANOCIF", + "LUGIA", + "HO-OH", + "CELEBI", + "ARCKO", + "MASSKO", + "JUNGKO", + "POUSSIFEU", + "GALIFEU", + "BRASEGALI", + "GOBOU", + "FLOBIO", + "LAGGRON", + "MEDHYENA", + "GRAHYENA", + "ZIGZATON", + "LINEON", + "CHENIPOTTE", + "ARMULYS", + "CHARMILLON", + "BLINDALYS", + "PAPINOX", + "NENUPIOT", + "LOMBRE", + "LUDICOLO", + "GRAINIPIOT", + "PIFEUIL", + "TENGALICE", + "NIRONDELLE", + "HELEDELLE", + "GOELISE", + "BEKIPAN", + "TARSAL", + "KIRLIA", + "GARDEVOIR", + "ARAKDO", + "MASKADRA", + "BALIGNON", + "CHAPIGNON", + "PARECOOL", + "VIGOROTH", + "MONAFLEMIT", + "NINGALE", + "NINJASK", + "MUNJA", + "CHUCHMUR", + "RAMBOUM", + "BROUHABAM", + "MAKUHITA", + "HARIYAMA", + "AZURILL", + "TARINOR", + "SKITTY", + "DELCATTY", + "TENEFIX", + "MYSDIBULE", + "GALEKID", + "GALEGON", + "GALEKING", + "MEDITIKKA", + "CHARMINA", + "DYNAVOLT", + "ELECSPRINT", + "POSIPI", + "NEGAPI", + "MUCIOLE", + "LUMIVOLE", + "ROSELIA", + "GLOUPTI", + "AVALTOUT", + "CARVANHA", + "SHARPEDO", + "WAILMER", + "WAILORD", + "CHAMALLOT", + "CAMERUPT", + "CHARTOR", + "SPOINK", + "GRORET", + "SPINDA", + "KRAKNOIX", + "VIBRANINF", + "LIBEGON", + "CACNEA", + "CACTURNE", + "TYLTON", + "ALTARIA", + "MANGRIFF", + "SEVIPER", + "SELEROC", + "SOLAROC", + "BARLOCHE", + "BARBICHA", + "ECRAPINCE", + "COLHOMARD", + "BALBUTO", + "KAORINE", + "LILIA", + "VACILYS", + "ANORITH", + "ARMALDO", + "BARPAU", + "MILOBELLUS", + "MORPHEO", + "KECLEON", + "POLICHOMBR", + "BRANETTE", + "SKELENOX", + "TERACLOPE", + "TROPIUS", + "EOKO", + "ABSOL", + "OKEOKE", + "STALGAMIN", + "ONIGLALI", + "OBALIE", + "PHOGLEUR", + "KAIMORSE", + "COQUIPERL", + "SERPANG", + "ROSABYSS", + "RELICANTH", + "LOVDISC", + "DRABY", + "DRACKHAUS", + "DRATTAK", + "TERHAL", + "METANG", + "METALOSSE", + "REGIROCK", + "REGICE", + "REGISTEEL", + "LATIAS", + "LATIOS", + "KYOGRE", + "GROUDON", + "RAYQUAZA", + "JIRACHI", + "DEOXYS", + "MANZAI" +}; + +const char *germanNames[388] = { + "(Nichts)", + "BISASAM", + "BISAKNOSP", + "BISAFLOR", + "GLUMANDA", + "GLUTEXO", + "GLURAK", + "SCHIGGY", + "SCHILLOK", + "TURTOK", + "RAUPY", + "SAFCON", + "SMETTBO", + "HORNLIU", + "KOKUNA", + "BIBOR", + "TAUBSI", + "TAUBOGA", + "TAUBOSS", + "RATTFRATZ", + "RATTIKARL", + "HABITAK", + "IBITAK", + "RETTAN", + "ARBOK", + "PIKACHU", + "RAICHU", + "SANDAN", + "SANDAMER", + "NIDORAN\xe2\x99\x80", + "NIDORINA", + "NIDOQUEEN", + "NIDORAN\xe2\x99\x82", + "NIDORINO", + "NIDOKING", + "PIEPI", + "PIXI", + "VULPIX", + "VULNONA", + "PUMMELUFF", + "KNUDDELUFF", + "ZUBAT", + "GOLBAT", + "MYRAPLA", + "DUFLOR", + "GIFLOR", + "PARAS", + "PARASEK", + "BLUZUK", + "OMOT", + "DIGDA", + "DIGDRI", + "MAUZI", + "SNOBILIKAT", + "ENTON", + "ENTORON", + "MENKI", + "RASAFF", + "FUKANO", + "ARKANI", + "QUAPSEL", + "QUAPUTZI", + "QUAPPO", + "ABRA", + "KADABRA", + "SIMSALA", + "MACHOLLO", + "MASCHOCK", + "MACHOMEI", + "KNOFENSA", + "ULTRIGARIA", + "SARZENIA", + "TENTACHA", + "TENTOXA", + "KLEINSTEIN", + "GEOROK", + "GEOWAZ", + "PONITA", + "GALLOPA", + "FLEGMON", + "LAHMUS", + "MAGNETILO", + "MAGNETON", + "PORENTA", + "DODU", + "DODRI", + "JUROB", + "JUGONG", + "SLEIMA", + "SLEIMOK", + "MUSCHAS", + "AUSTOS", + "NEBULAK", + "ALPOLLO", + "GENGAR", + "ONIX", + "TRAUMATO", + "HYPNO", + "KRABBY", + "KINGLER", + "VOLTOBAL", + "LEKTROBAL", + "OWEI", + "KOKOWEI", + "TRAGOSSO", + "KNOGGA", + "KICKLEE", + "NOCKCHAN", + "SCHLURP", + "SMOGON", + "SMOGMOG", + "RIHORN", + "RIZEROS", + "CHANEIRA", + "TANGELA", + "KANGAMA", + "SEEPER", + "SEEMON", + "GOLDINI", + "GOLKING", + "STERNDU", + "STARMIE", + "PANTIMOS", + "SICHLOR", + "ROSSANA", + "ELEKTEK", + "MAGMAR", + "PINSIR", + "TAUROS", + "KARPADOR", + "GARADOS", + "LAPRAS", + "DITTO", + "EVOLI", + "AQUANA", + "BLITZA", + "FLAMARA", + "PORYGON", + "AMONITAS", + "AMOROSO", + "KABUTO", + "KABUTOPS", + "AERODACTYL", + "RELAXO", + "ARKTOS", + "ZAPDOS", + "LAVADOS", + "DRATINI", + "DRAGONIR", + "DRAGORAN", + "MEWTU", + "MEW", + "ENDIVIE", + "LORBLATT", + "MEGANIE", + "FEURIGEL", + "IGELAVAR", + "TORNUPTO", + "KARNIMANI", + "TYRACROC", + "IMPERGATOR", + "WIESOR", + "WIESENIOR", + "HOOTHOOT", + "NOCTUH", + "LEDYBA", + "LEDIAN", + "WEBARAK", + "ARIADOS", + "IKSBAT", + "LAMPI", + "LANTURN", + "PICHU", + "PII", + "FLUFFELUFF", + "TOGEPI", + "TOGETIC", + "NATU", + "XATU", + "VOLTILAMM", + "WAATY", + "AMPHAROS", + "BLUBELLA", + "MARILL", + "AZUMARILL", + "MOGELBAUM", + "QUAXO", + "HOPPSPROSS", + "HUBELUPF", + "PAPUNGHA", + "GRIFFEL", + "SONNKERN", + "SONNFLORA", + "YANMA", + "FELINO", + "MORLORD", + "PSIANA", + "NACHTARA", + "KRAMURX", + "LASCHOKING", + "TRAUNFUGIL", + "ICOGNITO", + "WOINGENAU", + "GIRAFARIG", + "TANNZA", + "FORSTELLKA", + "DUMMISEL", + "SKORGLA", + "STAHLOS", + "SNUBBULL", + "GRANBULL", + "BALDORFISH", + "SCHEROX", + "POTTROTT", + "SKARABORN", + "SNIEBEL", + "TEDDIURSA", + "URSARING", + "SCHNECKMAG", + "MAGCARGO", + "QUIEKEL", + "KEIFEL", + "CORASONN", + "REMORAID", + "OCTILLERY", + "BOTOGEL", + "MANTAX", + "PANZAERON", + "HUNDUSTER", + "HUNDEMON", + "SEEDRAKING", + "PHANPY", + "DONPHAN", + "PORYGON2", + "DAMHIRPLEX", + "FARBEAGLE", + "RABAUZ", + "KAPOERA", + "KUSSILLA", + "ELEKID", + "MAGBY", + "MILTANK", + "HEITEIRA", + "RAIKOU", + "ENTEI", + "SUICUNE", + "LARVITAR", + "PUPITAR", + "DESPOTAR", + "LUGIA", + "HO-OH", + "CELEBI", + "GECKARBOR", + "REPTAIN", + "GEWALDRO", + "FLEMMLI", + "JUNGGLUT", + "LOHGOCK", + "HYDROPI", + "MOORABBEL", + "SUMPEX", + "FIFFYEN", + "MAGNAYEN", + "ZIGZACHS", + "GERADAKS", + "WAUMPEL", + "SCHALOKO", + "PAPINELLA", + "PANEKON", + "PUDOX", + "LOTURZEL", + "LOMBRERO", + "KAPPALORES", + "SAMURZEL", + "BLANAS", + "TENGULIST", + "SCHWALBINI", + "SCHWALBOSS", + "WINGULL", + "PELIPPER", + "TRASLA", + "KIRLIA", + "GUARDEVOIR", + "GEHWEIHER", + "MASKEREGEN", + "KNILZ", + "KAPILZ", + "BUMMELZ", + "MUNTIER", + "LETARKING", + "NINCADA", + "NINJASK", + "NINJATOM", + "FLURMEL", + "KRAKEELO", + "KRAWUMMS", + "MAKUHITA", + "HARIYAMA", + "AZURILL", + "NASGNET", + "ENECO", + "ENEKORO", + "ZOBIRIS", + "FLUNKIFER", + "STOLLUNIOR", + "STOLLRAK", + "STOLLOSS", + "MEDITIE", + "MEDITALIS", + "FRIZELBLIZ", + "VOLTENSO", + "PLUSLE", + "MINUN", + "VOLBEAT", + "ILLUMISE", + "ROSELIA", + "SCHLUPPUCK", + "SCHLUKWECH", + "KANIVANHA", + "TOHAIDO", + "WAILMER", + "WAILORD", + "CAMAUB", + "CAMERUPT", + "QURTEL", + "SPOINK", + "GROINK", + "PANDIR", + "KNACKLION", + "VIBRAVA", + "LIBELLDRA", + "TUSKA", + "NOKTUSKA", + "WABLU", + "ALTARIA", + "SENGO", + "VIPITIS", + "LUNASTEIN", + "SONNFEL", + "SCHMERBE", + "WELSAR", + "KREBSCORPS", + "KREBUTACK", + "PUPPANCE", + "LEPUMENTAS", + "LILIEP", + "WIELIE", + "ANORITH", + "ARMALDO", + "BARSCHWA", + "MILOTIC", + "FORMEO", + "KECLEON", + "SHUPPET", + "BANETTE", + "ZWIRRLICHT", + "ZWIRRKLOP", + "TROPIUS", + "PALIMPALIM", + "ABSOL", + "ISSO", + "SCHNEPPKE", + "FIRNONTOR", + "SEEMOPS", + "SEEJONG", + "WALRAISA", + "PERLU", + "AALABYSS", + "SAGANABYSS", + "RELICANTH", + "LIEBISKUS", + "KINDWURM", + "DRASCHEL", + "BRUTALANDA", + "TANHEL", + "METANG", + "METAGROSS", + "REGIROCK", + "REGICE", + "REGISTEEL", + "LATIAS", + "LATIOS", + "KYOGRE", + "GROUDON", + "RAYQUAZA", + "JIRACHI", + "DEOXYS", + "MOBAI" +}; + +const char *italianNames[388] = { + "(Nessuno)", + "BULBASAUR", + "IVYSAUR", + "VENUSAUR", + "CHARMANDER", + "CHARMELEON", + "CHARIZARD", + "SQUIRTLE", + "WARTORTLE", + "BLASTOISE", + "CATERPIE", + "METAPOD", + "BUTTERFREE", + "WEEDLE", + "KAKUNA", + "BEEDRILL", + "PIDGEY", + "PIDGEOTTO", + "PIDGEOT", + "RATTATA", + "RATICATE", + "SPEAROW", + "FEAROW", + "EKANS", + "ARBOK", + "PIKACHU", + "RAICHU", + "SANDSHREW", + "SANDSLASH", + "NIDORAN\xe2\x99\x80", + "NIDORINA", + "NIDOQUEEN", + "NIDORAN\xe2\x99\x82", + "NIDORINO", + "NIDOKING", + "CLEFAIRY", + "CLEFABLE", + "VULPIX", + "NINETALES", + "JIGGLYPUFF", + "WIGGLYTUFF", + "ZUBAT", + "GOLBAT", + "ODDISH", + "GLOOM", + "VILEPLUME", + "PARAS", + "PARASECT", + "VENONAT", + "VENOMOTH", + "DIGLETT", + "DUGTRIO", + "MEOWTH", + "PERSIAN", + "PSYDUCK", + "GOLDUCK", + "MANKEY", + "PRIMEAPE", + "GROWLITHE", + "ARCANINE", + "POLIWAG", + "POLIWHIRL", + "POLIWRATH", + "ABRA", + "KADABRA", + "ALAKAZAM", + "MACHOP", + "MACHOKE", + "MACHAMP", + "BELLSPROUT", + "WEEPINBELL", + "VICTREEBEL", + "TENTACOOL", + "TENTACRUEL", + "GEODUDE", + "GRAVELER", + "GOLEM", + "PONYTA", + "RAPIDASH", + "SLOWPOKE", + "SLOWBRO", + "MAGNEMITE", + "MAGNETON", + "FARFETCH'D", + "DODUO", + "DODRIO", + "SEEL", + "DEWGONG", + "GRIMER", + "MUK", + "SHELLDER", + "CLOYSTER", + "GASTLY", + "HAUNTER", + "GENGAR", + "ONIX", + "DROWZEE", + "HYPNO", + "KRABBY", + "KINGLER", + "VOLTORB", + "ELECTRODE", + "EXEGGCUTE", + "EXEGGUTOR", + "CUBONE", + "MAROWAK", + "HITMONLEE", + "HITMONCHAN", + "LICKITUNG", + "KOFFING", + "WEEZING", + "RHYHORN", + "RHYDON", + "CHANSEY", + "TANGELA", + "KANGASKHAN", + "HORSEA", + "SEADRA", + "GOLDEEN", + "SEAKING", + "STARYU", + "STARMIE", + "MR. MIME", + "SCYTHER", + "JYNX", + "ELECTABUZZ", + "MAGMAR", + "PINSIR", + "TAUROS", + "MAGIKARP", + "GYARADOS", + "LAPRAS", + "DITTO", + "EEVEE", + "VAPOREON", + "JOLTEON", + "FLAREON", + "PORYGON", + "OMANYTE", + "OMASTAR", + "KABUTO", + "KABUTOPS", + "AERODACTYL", + "SNORLAX", + "ARTICUNO", + "ZAPDOS", + "MOLTRES", + "DRATINI", + "DRAGONAIR", + "DRAGONITE", + "MEWTWO", + "MEW", + "CHIKORITA", + "BAYLEEF", + "MEGANIUM", + "CYNDAQUIL", + "QUILAVA", + "TYPHLOSION", + "TOTODILE", + "CROCONAW", + "FERALIGATR", + "SENTRET", + "FURRET", + "HOOTHOOT", + "NOCTOWL", + "LEDYBA", + "LEDIAN", + "SPINARAK", + "ARIADOS", + "CROBAT", + "CHINCHOU", + "LANTURN", + "PICHU", + "CLEFFA", + "IGGLYBUFF", + "TOGEPI", + "TOGETIC", + "NATU", + "XATU", + "MAREEP", + "FLAAFFY", + "AMPHAROS", + "BELLOSSOM", + "MARILL", + "AZUMARILL", + "SUDOWOODO", + "POLITOED", + "HOPPIP", + "SKIPLOOM", + "JUMPLUFF", + "AIPOM", + "SUNKERN", + "SUNFLORA", + "YANMA", + "WOOPER", + "QUAGSIRE", + "ESPEON", + "UMBREON", + "MURKROW", + "SLOWKING", + "MISDREAVUS", + "UNOWN", + "WOBBUFFET", + "GIRAFARIG", + "PINECO", + "FORRETRESS", + "DUNSPARCE", + "GLIGAR", + "STEELIX", + "SNUBBULL", + "GRANBULL", + "QWILFISH", + "SCIZOR", + "SHUCKLE", + "HERACROSS", + "SNEASEL", + "TEDDIURSA", + "URSARING", + "SLUGMA", + "MAGCARGO", + "SWINUB", + "PILOSWINE", + "CORSOLA", + "REMORAID", + "OCTILLERY", + "DELIBIRD", + "MANTINE", + "SKARMORY", + "HOUNDOUR", + "HOUNDOOM", + "KINGDRA", + "PHANPY", + "DONPHAN", + "PORYGON2", + "STANTLER", + "SMEARGLE", + "TYROGUE", + "HITMONTOP", + "SMOOCHUM", + "ELEKID", + "MAGBY", + "MILTANK", + "BLISSEY", + "RAIKOU", + "ENTEI", + "SUICUNE", + "LARVITAR", + "PUPITAR", + "TYRANITAR", + "LUGIA", + "HO-OH", + "CELEBI", + "TREECKO", + "GROVYLE", + "SCEPTILE", + "TORCHIC", + "COMBUSKEN", + "BLAZIKEN", + "MUDKIP", + "MARSHTOMP", + "SWAMPERT", + "POOCHYENA", + "MIGHTYENA", + "ZIGZAGOON", + "LINOONE", + "WURMPLE", + "SILCOON", + "BEAUTIFLY", + "CASCOON", + "DUSTOX", + "LOTAD", + "LOMBRE", + "LUDICOLO", + "SEEDOT", + "NUZLEAF", + "SHIFTRY", + "TAILLOW", + "SWELLOW", + "WINGULL", + "PELIPPER", + "RALTS", + "KIRLIA", + "GARDEVOIR", + "SURSKIT", + "MASQUERAIN", + "SHROOMISH", + "BRELOOM", + "SLAKOTH", + "VIGOROTH", + "SLAKING", + "NINCADA", + "NINJASK", + "SHEDINJA", + "WHISMUR", + "LOUDRED", + "EXPLOUD", + "MAKUHITA", + "HARIYAMA", + "AZURILL", + "NOSEPASS", + "SKITTY", + "DELCATTY", + "SABLEYE", + "MAWILE", + "ARON", + "LAIRON", + "AGGRON", + "MEDITITE", + "MEDICHAM", + "ELECTRIKE", + "MANECTRIC", + "PLUSLE", + "MINUN", + "VOLBEAT", + "ILLUMISE", + "ROSELIA", + "GULPIN", + "SWALOT", + "CARVANHA", + "SHARPEDO", + "WAILMER", + "WAILORD", + "NUMEL", + "CAMERUPT", + "TORKOAL", + "SPOINK", + "GRUMPIG", + "SPINDA", + "TRAPINCH", + "VIBRAVA", + "FLYGON", + "CACNEA", + "CACTURNE", + "SWABLU", + "ALTARIA", + "ZANGOOSE", + "SEVIPER", + "LUNATONE", + "SOLROCK", + "BARBOACH", + "WHISCASH", + "CORPHISH", + "CRAWDAUNT", + "BALTOY", + "CLAYDOL", + "LILEEP", + "CRADILY", + "ANORITH", + "ARMALDO", + "FEEBAS", + "MILOTIC", + "CASTFORM", + "KECLEON", + "SHUPPET", + "BANETTE", + "DUSKULL", + "DUSCLOPS", + "TROPIUS", + "CHIMECHO", + "ABSOL", + "WYNAUT", + "SNORUNT", + "GLALIE", + "SPHEAL", + "SEALEO", + "WALREIN", + "CLAMPERL", + "HUNTAIL", + "GOREBYSS", + "RELICANTH", + "LUVDISC", + "BAGON", + "SHELGON", + "SALAMENCE", + "BELDUM", + "METANG", + "METAGROSS", + "REGIROCK", + "REGICE", + "REGISTEEL", + "LATIAS", + "LATIOS", + "KYOGRE", + "GROUDON", + "RAYQUAZA", + "JIRACHI", + "DEOXYS", + "BONSLY", // XD only +}; + +const char *spanishNames[388] = { + "(Ninguno)", + "BULBASAUR", + "IVYSAUR", + "VENUSAUR", + "CHARMANDER", + "CHARMELEON", + "CHARIZARD", + "SQUIRTLE", + "WARTORTLE", + "BLASTOISE", + "CATERPIE", + "METAPOD", + "BUTTERFREE", + "WEEDLE", + "KAKUNA", + "BEEDRILL", + "PIDGEY", + "PIDGEOTTO", + "PIDGEOT", + "RATTATA", + "RATICATE", + "SPEAROW", + "FEAROW", + "EKANS", + "ARBOK", + "PIKACHU", + "RAICHU", + "SANDSHREW", + "SANDSLASH", + "NIDORAN\xe2\x99\x80", + "NIDORINA", + "NIDOQUEEN", + "NIDORAN\xe2\x99\x82", + "NIDORINO", + "NIDOKING", + "CLEFAIRY", + "CLEFABLE", + "VULPIX", + "NINETALES", + "JIGGLYPUFF", + "WIGGLYTUFF", + "ZUBAT", + "GOLBAT", + "ODDISH", + "GLOOM", + "VILEPLUME", + "PARAS", + "PARASECT", + "VENONAT", + "VENOMOTH", + "DIGLETT", + "DUGTRIO", + "MEOWTH", + "PERSIAN", + "PSYDUCK", + "GOLDUCK", + "MANKEY", + "PRIMEAPE", + "GROWLITHE", + "ARCANINE", + "POLIWAG", + "POLIWHIRL", + "POLIWRATH", + "ABRA", + "KADABRA", + "ALAKAZAM", + "MACHOP", + "MACHOKE", + "MACHAMP", + "BELLSPROUT", + "WEEPINBELL", + "VICTREEBEL", + "TENTACOOL", + "TENTACRUEL", + "GEODUDE", + "GRAVELER", + "GOLEM", + "PONYTA", + "RAPIDASH", + "SLOWPOKE", + "SLOWBRO", + "MAGNEMITE", + "MAGNETON", + "FARFETCH'D", + "DODUO", + "DODRIO", + "SEEL", + "DEWGONG", + "GRIMER", + "MUK", + "SHELLDER", + "CLOYSTER", + "GASTLY", + "HAUNTER", + "GENGAR", + "ONIX", + "DROWZEE", + "HYPNO", + "KRABBY", + "KINGLER", + "VOLTORB", + "ELECTRODE", + "EXEGGCUTE", + "EXEGGUTOR", + "CUBONE", + "MAROWAK", + "HITMONLEE", + "HITMONCHAN", + "LICKITUNG", + "KOFFING", + "WEEZING", + "RHYHORN", + "RHYDON", + "CHANSEY", + "TANGELA", + "KANGASKHAN", + "HORSEA", + "SEADRA", + "GOLDEEN", + "SEAKING", + "STARYU", + "STARMIE", + "MR. MIME", + "SCYTHER", + "JYNX", + "ELECTABUZZ", + "MAGMAR", + "PINSIR", + "TAUROS", + "MAGIKARP", + "GYARADOS", + "LAPRAS", + "DITTO", + "EEVEE", + "VAPOREON", + "JOLTEON", + "FLAREON", + "PORYGON", + "OMANYTE", + "OMASTAR", + "KABUTO", + "KABUTOPS", + "AERODACTYL", + "SNORLAX", + "ARTICUNO", + "ZAPDOS", + "MOLTRES", + "DRATINI", + "DRAGONAIR", + "DRAGONITE", + "MEWTWO", + "MEW", + "CHIKORITA", + "BAYLEEF", + "MEGANIUM", + "CYNDAQUIL", + "QUILAVA", + "TYPHLOSION", + "TOTODILE", + "CROCONAW", + "FERALIGATR", + "SENTRET", + "FURRET", + "HOOTHOOT", + "NOCTOWL", + "LEDYBA", + "LEDIAN", + "SPINARAK", + "ARIADOS", + "CROBAT", + "CHINCHOU", + "LANTURN", + "PICHU", + "CLEFFA", + "IGGLYBUFF", + "TOGEPI", + "TOGETIC", + "NATU", + "XATU", + "MAREEP", + "FLAAFFY", + "AMPHAROS", + "BELLOSSOM", + "MARILL", + "AZUMARILL", + "SUDOWOODO", + "POLITOED", + "HOPPIP", + "SKIPLOOM", + "JUMPLUFF", + "AIPOM", + "SUNKERN", + "SUNFLORA", + "YANMA", + "WOOPER", + "QUAGSIRE", + "ESPEON", + "UMBREON", + "MURKROW", + "SLOWKING", + "MISDREAVUS", + "UNOWN", + "WOBBUFFET", + "GIRAFARIG", + "PINECO", + "FORRETRESS", + "DUNSPARCE", + "GLIGAR", + "STEELIX", + "SNUBBULL", + "GRANBULL", + "QWILFISH", + "SCIZOR", + "SHUCKLE", + "HERACROSS", + "SNEASEL", + "TEDDIURSA", + "URSARING", + "SLUGMA", + "MAGCARGO", + "SWINUB", + "PILOSWINE", + "CORSOLA", + "REMORAID", + "OCTILLERY", + "DELIBIRD", + "MANTINE", + "SKARMORY", + "HOUNDOUR", + "HOUNDOOM", + "KINGDRA", + "PHANPY", + "DONPHAN", + "PORYGON2", + "STANTLER", + "SMEARGLE", + "TYROGUE", + "HITMONTOP", + "SMOOCHUM", + "ELEKID", + "MAGBY", + "MILTANK", + "BLISSEY", + "RAIKOU", + "ENTEI", + "SUICUNE", + "LARVITAR", + "PUPITAR", + "TYRANITAR", + "LUGIA", + "HO-OH", + "CELEBI", + "TREECKO", + "GROVYLE", + "SCEPTILE", + "TORCHIC", + "COMBUSKEN", + "BLAZIKEN", + "MUDKIP", + "MARSHTOMP", + "SWAMPERT", + "POOCHYENA", + "MIGHTYENA", + "ZIGZAGOON", + "LINOONE", + "WURMPLE", + "SILCOON", + "BEAUTIFLY", + "CASCOON", + "DUSTOX", + "LOTAD", + "LOMBRE", + "LUDICOLO", + "SEEDOT", + "NUZLEAF", + "SHIFTRY", + "TAILLOW", + "SWELLOW", + "WINGULL", + "PELIPPER", + "RALTS", + "KIRLIA", + "GARDEVOIR", + "SURSKIT", + "MASQUERAIN", + "SHROOMISH", + "BRELOOM", + "SLAKOTH", + "VIGOROTH", + "SLAKING", + "NINCADA", + "NINJASK", + "SHEDINJA", + "WHISMUR", + "LOUDRED", + "EXPLOUD", + "MAKUHITA", + "HARIYAMA", + "AZURILL", + "NOSEPASS", + "SKITTY", + "DELCATTY", + "SABLEYE", + "MAWILE", + "ARON", + "LAIRON", + "AGGRON", + "MEDITITE", + "MEDICHAM", + "ELECTRIKE", + "MANECTRIC", + "PLUSLE", + "MINUN", + "VOLBEAT", + "ILLUMISE", + "ROSELIA", + "GULPIN", + "SWALOT", + "CARVANHA", + "SHARPEDO", + "WAILMER", + "WAILORD", + "NUMEL", + "CAMERUPT", + "TORKOAL", + "SPOINK", + "GRUMPIG", + "SPINDA", + "TRAPINCH", + "VIBRAVA", + "FLYGON", + "CACNEA", + "CACTURNE", + "SWABLU", + "ALTARIA", + "ZANGOOSE", + "SEVIPER", + "LUNATONE", + "SOLROCK", + "BARBOACH", + "WHISCASH", + "CORPHISH", + "CRAWDAUNT", + "BALTOY", + "CLAYDOL", + "LILEEP", + "CRADILY", + "ANORITH", + "ARMALDO", + "FEEBAS", + "MILOTIC", + "CASTFORM", + "KECLEON", + "SHUPPET", + "BANETTE", + "DUSKULL", + "DUSCLOPS", + "TROPIUS", + "CHIMECHO", + "ABSOL", + "WYNAUT", + "SNORUNT", + "GLALIE", + "SPHEAL", + "SEALEO", + "WALREIN", + "CLAMPERL", + "HUNTAIL", + "GOREBYSS", + "RELICANTH", + "LUVDISC", + "BAGON", + "SHELGON", + "SALAMENCE", + "BELDUM", + "METANG", + "METAGROSS", + "REGIROCK", + "REGICE", + "REGISTEEL", + "LATIAS", + "LATIOS", + "KYOGRE", + "GROUDON", + "RAYQUAZA", + "JIRACHI", + "DEOXYS", + "BONSLY", // XD only +}; + +const char *japaneseNames[388] = { + "(\xe4\xbd\x95\xe3\x82\x82)", + "\xe3\x83\x95\xe3\x82\xb7\xe3\x82\xae\xe3\x83\x80\xe3\x83\x8d", + "\xe3\x83\x95\xe3\x82\xb7\xe3\x82\xae\xe3\x82\xbd\xe3\x82\xa6", + "\xe3\x83\x95\xe3\x82\xb7\xe3\x82\xae\xe3\x83\x90\xe3\x83\x8a", + "\xe3\x83\x92\xe3\x83\x88\xe3\x82\xab\xe3\x82\xb2", + "\xe3\x83\xaa\xe3\x82\xb6\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x83\xaa\xe3\x82\xb6\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xb3", + "\xe3\x82\xbc\xe3\x83\x8b\xe3\x82\xac\xe3\x83\xa1", + "\xe3\x82\xab\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xab\xe3\x83\xa1\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9", + "\xe3\x82\xad\xe3\x83\xa3\xe3\x82\xbf\xe3\x83\x94\xe3\x83\xbc", + "\xe3\x83\x88\xe3\x83\xa9\xe3\x83\xb3\xe3\x82\xbb\xe3\x83\xab", + "\xe3\x83\x90\xe3\x82\xbf\xe3\x83\x95\xe3\x83\xaa\xe3\x83\xbc", + "\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xab", + "\xe3\x82\xb3\xe3\x82\xaf\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xb9\xe3\x83\x94\xe3\x82\xa2\xe3\x83\xbc", + "\xe3\x83\x9d\xe3\x83\x83\xe3\x83\x9d", + "\xe3\x83\x94\xe3\x82\xb8\xe3\x83\xa7\xe3\x83\xb3", + "\xe3\x83\x94\xe3\x82\xb8\xe3\x83\xa7\xe3\x83\x83\xe3\x83\x88", + "\xe3\x82\xb3\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xbf", + "\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xbf", + "\xe3\x82\xaa\xe3\x83\x8b\xe3\x82\xb9\xe3\x82\xba\xe3\x83\xa1", + "\xe3\x82\xaa\xe3\x83\x8b\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xab", + "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\x9c", + "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\x9c\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x83\x94\xe3\x82\xab\xe3\x83\x81\xe3\x83\xa5\xe3\x82\xa6", + "\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\x81\xe3\x83\xa5\xe3\x82\xa6", + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x89", + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x89\xe3\x83\x91\xe3\x83\xb3", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x83\xa9\xe3\x83\xb3\xe2\x99\x80", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x8a", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x82\xaf\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x83\xa9\xe3\x83\xb3\xe2\x99\x82", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x8e", + "\xe3\x83\x8b\xe3\x83\x89\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x83\x94\xe3\x83\x83\xe3\x83\x94", + "\xe3\x83\x94\xe3\x82\xaf\xe3\x82\xb7\xe3\x83\xbc", + "\xe3\x83\xad\xe3\x82\xb3\xe3\x83\xb3", + "\xe3\x82\xad\xe3\x83\xa5\xe3\x82\xa6\xe3\x82\xb3\xe3\x83\xb3", + "\xe3\x83\x97\xe3\x83\xaa\xe3\x83\xb3", + "\xe3\x83\x97\xe3\x82\xaf\xe3\x83\xaa\xe3\x83\xb3", + "\xe3\x82\xba\xe3\x83\x90\xe3\x83\x83\xe3\x83\x88", + "\xe3\x82\xb4\xe3\x83\xab\xe3\x83\x90\xe3\x83\x83\xe3\x83\x88", + "\xe3\x83\x8a\xe3\x82\xbe\xe3\x83\x8e\xe3\x82\xaf\xe3\x82\xb5", + "\xe3\x82\xaf\xe3\x82\xb5\xe3\x82\xa4\xe3\x83\x8f\xe3\x83\x8a", + "\xe3\x83\xa9\xe3\x83\x95\xe3\x83\xac\xe3\x82\xb7\xe3\x82\xa2", + "\xe3\x83\x91\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\x91\xe3\x83\xa9\xe3\x82\xbb\xe3\x82\xaf\xe3\x83\x88", + "\xe3\x82\xb3\xe3\x83\xb3\xe3\x83\x91\xe3\x83\xb3", + "\xe3\x83\xa2\xe3\x83\xab\xe3\x83\x95\xe3\x82\xa9\xe3\x83\xb3", + "\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xb0\xe3\x83\x80", + "\xe3\x83\x80\xe3\x82\xb0\xe3\x83\x88\xe3\x83\xaa\xe3\x82\xaa", + "\xe3\x83\x8b\xe3\x83\xa3\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\x9a\xe3\x83\xab\xe3\x82\xb7\xe3\x82\xa2\xe3\x83\xb3", + "\xe3\x82\xb3\xe3\x83\x80\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x82\xb4\xe3\x83\xab\xe3\x83\x80\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x83\x9e\xe3\x83\xb3\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x82\xaa\xe3\x82\xb3\xe3\x83\xaa\xe3\x82\xb6\xe3\x83\xab", + "\xe3\x82\xac\xe3\x83\xbc\xe3\x83\x87\xe3\x82\xa3", + "\xe3\x82\xa6\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x87\xe3\x82\xa3", + "\xe3\x83\x8b\xe3\x83\xa7\xe3\x83\xad\xe3\x83\xa2", + "\xe3\x83\x8b\xe3\x83\xa7\xe3\x83\xad\xe3\x82\xbe", + "\xe3\x83\x8b\xe3\x83\xa7\xe3\x83\xad\xe3\x83\x9c\xe3\x83\xb3", + "\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb7\xe3\x82\xa3", + "\xe3\x83\xa6\xe3\x83\xb3\xe3\x82\xb2\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\x95\xe3\x83\xbc\xe3\x83\x87\xe3\x82\xa3\xe3\x83\xb3", + "\xe3\x83\xaf\xe3\x83\xb3\xe3\x83\xaa\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x82\xb4\xe3\x83\xbc\xe3\x83\xaa\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xaa\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x83\x9e\xe3\x83\x80\xe3\x83\x84\xe3\x83\x9c\xe3\x83\x9f", + "\xe3\x82\xa6\xe3\x83\x84\xe3\x83\x89\xe3\x83\xb3", + "\xe3\x82\xa6\xe3\x83\x84\xe3\x83\x9c\xe3\x83\x83\xe3\x83\x88", + "\xe3\x83\xa1\xe3\x83\x8e\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xb2", + "\xe3\x83\x89\xe3\x82\xaf\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xb2", + "\xe3\x82\xa4\xe3\x82\xb7\xe3\x83\x84\xe3\x83\x96\xe3\x83\x86", + "\xe3\x82\xb4\xe3\x83\xad\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xb4\xe3\x83\xad\xe3\x83\xbc\xe3\x83\x8b\xe3\x83\xa3", + "\xe3\x83\x9d\xe3\x83\x8b\xe3\x83\xbc\xe3\x82\xbf", + "\xe3\x82\xae\xe3\x83\xa3\xe3\x83\xad\xe3\x83\x83\xe3\x83\x97", + "\xe3\x83\xa4\xe3\x83\x89\xe3\x83\xb3", + "\xe3\x83\xa4\xe3\x83\x89\xe3\x83\xa9\xe3\x83\xb3", + "\xe3\x82\xb3\xe3\x82\xa4\xe3\x83\xab", + "\xe3\x83\xac\xe3\x82\xa2\xe3\x82\xb3\xe3\x82\xa4\xe3\x83\xab", + "\xe3\x82\xab\xe3\x83\xa2\xe3\x83\x8d\xe3\x82\xae", + "\xe3\x83\x89\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xbc", + "\xe3\x83\x89\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xaa\xe3\x82\xaa", + "\xe3\x83\x91\xe3\x82\xa6\xe3\x83\xaf\xe3\x82\xa6", + "\xe3\x82\xb8\xe3\x83\xa5\xe3\x82\xb4\xe3\x83\xb3", + "\xe3\x83\x99\xe3\x83\x88\xe3\x83\x99\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x83\x99\xe3\x83\x88\xe3\x83\x99\xe3\x83\x88\xe3\x83\xb3", + "\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xab\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x83\x91\xe3\x83\xab\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xb3", + "\xe3\x82\xb4\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x82\xb4\xe3\x83\xbc\xe3\x82\xb9\xe3\x83\x88", + "\xe3\x82\xb2\xe3\x83\xb3\xe3\x82\xac\xe3\x83\xbc", + "\xe3\x82\xa4\xe3\x83\xaf\xe3\x83\xbc\xe3\x82\xaf", + "\xe3\x82\xb9\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x97", + "\xe3\x82\xb9\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x91\xe3\x83\xbc", + "\xe3\x82\xaf\xe3\x83\xa9\xe3\x83\x96", + "\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\x93\xe3\x83\xaa\xe3\x83\xaa\xe3\x83\x80\xe3\x83\x9e", + "\xe3\x83\x9e\xe3\x83\xab\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x82\xbf\xe3\x83\x9e\xe3\x82\xbf\xe3\x83\x9e", + "\xe3\x83\x8a\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x83\xa9\xe3\x82\xab\xe3\x83\xa9", + "\xe3\x82\xac\xe3\x83\xa9\xe3\x82\xac\xe3\x83\xa9", + "\xe3\x82\xb5\xe3\x83\xaf\xe3\x83\xa0\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x82\xa8\xe3\x83\x93\xe3\x83\xaf\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\x99\xe3\x83\xad\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xac", + "\xe3\x83\x89\xe3\x82\xac\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\x9e\xe3\x82\xbf\xe3\x83\x89\xe3\x82\xac\xe3\x82\xb9", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x83\x89\xe3\x83\xb3", + "\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x83\xa2\xe3\x83\xb3\xe3\x82\xb8\xe3\x83\xa3\xe3\x83\xa9", + "\xe3\x82\xac\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa9", + "\xe3\x82\xbf\xe3\x83\x83\xe3\x83\x84\xe3\x83\xbc", + "\xe3\x82\xb7\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xa9", + "\xe3\x83\x88\xe3\x82\xb5\xe3\x82\xad\xe3\x83\xb3\xe3\x83\x88", + "\xe3\x82\xa2\xe3\x82\xba\xe3\x83\x9e\xe3\x82\xaa\xe3\x82\xa6", + "\xe3\x83\x92\xe3\x83\x88\xe3\x83\x87\xe3\x83\x9e\xe3\x83\xb3", + "\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x9f\xe3\x83\xbc", + "\xe3\x83\x90\xe3\x83\xaa\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x82\xb9\xe3\x83\x88\xe3\x83\xa9\xe3\x82\xa4\xe3\x82\xaf", + "\xe3\x83\xab\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\xa9", + "\xe3\x82\xa8\xe3\x83\xac\xe3\x83\x96\xe3\x83\xbc", + "\xe3\x83\x96\xe3\x83\xbc\xe3\x83\x90\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xad\xe3\x82\xb9", + "\xe3\x82\xb1\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xad\xe3\x82\xb9", + "\xe3\x82\xb3\xe3\x82\xa4\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x82\xae\xe3\x83\xa3\xe3\x83\xa9\xe3\x83\x89\xe3\x82\xb9", + "\xe3\x83\xa9\xe3\x83\x97\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\xa2\xe3\x83\xb3", + "\xe3\x82\xa4\xe3\x83\xbc\xe3\x83\x96\xe3\x82\xa4", + "\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\xaf\xe3\x83\xbc\xe3\x82\xba", + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x80\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\x96\xe3\x83\xbc\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x83\x9d\xe3\x83\xaa\xe3\x82\xb4\xe3\x83\xb3", + "\xe3\x82\xaa\xe3\x83\xa0\xe3\x83\x8a\xe3\x82\xa4\xe3\x83\x88", + "\xe3\x82\xaa\xe3\x83\xa0\xe3\x82\xb9\xe3\x82\xbf\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x83\x96\xe3\x83\x88", + "\xe3\x82\xab\xe3\x83\x96\xe3\x83\x88\xe3\x83\x97\xe3\x82\xb9", + "\xe3\x83\x97\xe3\x83\x86\xe3\x83\xa9", + "\xe3\x82\xab\xe3\x83\x93\xe3\x82\xb4\xe3\x83\xb3", + "\xe3\x83\x95\xe3\x83\xaa\xe3\x83\xbc\xe3\x82\xb6\xe3\x83\xbc", + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xa4\xe3\x83\xbc", + "\xe3\x83\x9f\xe3\x83\x8b\xe3\x83\xaa\xe3\x83\xa5\xe3\x82\xa6", + "\xe3\x83\x8f\xe3\x82\xaf\xe3\x83\xaa\xe3\x83\xa5\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xaa\xe3\x83\xa5\xe3\x83\xbc", + "\xe3\x83\x9f\xe3\x83\xa5\xe3\x82\xa6\xe3\x83\x84\xe3\x83\xbc", + "\xe3\x83\x9f\xe3\x83\xa5\xe3\x82\xa6", + "\xe3\x83\x81\xe3\x82\xb3\xe3\x83\xaa\xe3\x83\xbc\xe3\x82\xbf", + "\xe3\x83\x99\xe3\x82\xa4\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x95", + "\xe3\x83\xa1\xe3\x82\xac\xe3\x83\x8b\xe3\x82\xa6\xe3\x83\xa0", + "\xe3\x83\x92\xe3\x83\x8e\xe3\x82\xa2\xe3\x83\xa9\xe3\x82\xb7", + "\xe3\x83\x9e\xe3\x82\xb0\xe3\x83\x9e\xe3\x83\xa9\xe3\x82\xb7", + "\xe3\x83\x90\xe3\x82\xaf\xe3\x83\x95\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x83\xaf\xe3\x83\x8b\xe3\x83\x8e\xe3\x82\xb3", + "\xe3\x82\xa2\xe3\x83\xaa\xe3\x82\xb2\xe3\x82\xa4\xe3\x83\x84", + "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\x80\xe3\x82\xa4\xe3\x83\xab", + "\xe3\x82\xaa\xe3\x82\xbf\xe3\x83\x81", + "\xe3\x82\xaa\xe3\x82\xaa\xe3\x82\xbf\xe3\x83\x81", + "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\x9b\xe3\x83\xbc", + "\xe3\x83\xa8\xe3\x83\xab\xe3\x83\x8e\xe3\x82\xba\xe3\x82\xaf", + "\xe3\x83\xac\xe3\x83\x87\xe3\x82\xa3\xe3\x83\x90", + "\xe3\x83\xac\xe3\x83\x87\xe3\x82\xa3\xe3\x82\xa2\xe3\x83\xb3", + "\xe3\x82\xa4\xe3\x83\x88\xe3\x83\x9e\xe3\x83\xab", + "\xe3\x82\xa2\xe3\x83\xaa\xe3\x82\xa2\xe3\x83\x89\xe3\x82\xb9", + "\xe3\x82\xaf\xe3\x83\xad\xe3\x83\x90\xe3\x83\x83\xe3\x83\x88", + "\xe3\x83\x81\xe3\x83\xa7\xe3\x83\xb3\xe3\x83\x81\xe3\x83\xbc", + "\xe3\x83\xa9\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x83\x94\xe3\x83\x81\xe3\x83\xa5\xe3\x83\xbc", + "\xe3\x83\x94\xe3\x82\xa3", + "\xe3\x83\x97\xe3\x83\x97\xe3\x83\xaa\xe3\x83\xb3", + "\xe3\x83\x88\xe3\x82\xb2\xe3\x83\x94\xe3\x83\xbc", + "\xe3\x83\x88\xe3\x82\xb2\xe3\x83\x81\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x83\x8d\xe3\x82\xa4\xe3\x83\x86\xe3\x82\xa3", + "\xe3\x83\x8d\xe3\x82\xa4\xe3\x83\x86\xe3\x82\xa3\xe3\x82\xaa", + "\xe3\x83\xa1\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\x97", + "\xe3\x83\xa2\xe3\x82\xb3\xe3\x82\xb3", + "\xe3\x83\x87\xe3\x83\xb3\xe3\x83\xaa\xe3\x83\xa5\xe3\x82\xa6", + "\xe3\x82\xad\xe3\x83\xac\xe3\x82\xa4\xe3\x83\x8f\xe3\x83\x8a", + "\xe3\x83\x9e\xe3\x83\xaa\xe3\x83\xab", + "\xe3\x83\x9e\xe3\x83\xaa\xe3\x83\xab\xe3\x83\xaa", + "\xe3\x82\xa6\xe3\x82\xbd\xe3\x83\x83\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x83\x8b\xe3\x83\xa7\xe3\x83\xad\xe3\x83\x88\xe3\x83\x8e", + "\xe3\x83\x8f\xe3\x83\x8d\xe3\x83\x83\xe3\x82\xb3", + "\xe3\x83\x9d\xe3\x83\x9d\xe3\x83\x83\xe3\x82\xb3", + "\xe3\x83\xaf\xe3\x82\xbf\xe3\x83\x83\xe3\x82\xb3", + "\xe3\x82\xa8\xe3\x82\xa4\xe3\x83\x91\xe3\x83\xa0", + "\xe3\x83\x92\xe3\x83\x9e\xe3\x83\x8a\xe3\x83\x83\xe3\x83\x84", + "\xe3\x82\xad\xe3\x83\x9e\xe3\x83\xaf\xe3\x83\xaa", + "\xe3\x83\xa4\xe3\x83\xb3\xe3\x83\xa4\xe3\x83\xb3\xe3\x83\x9e", + "\xe3\x82\xa6\xe3\x83\x91\xe3\x83\xbc", + "\xe3\x83\x8c\xe3\x82\xaa\xe3\x83\xbc", + "\xe3\x82\xa8\xe3\x83\xbc\xe3\x83\x95\xe3\x82\xa3", + "\xe3\x83\x96\xe3\x83\xa9\xe3\x83\x83\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x83\xa4\xe3\x83\x9f\xe3\x82\xab\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\xa4\xe3\x83\x89\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x83\xa0\xe3\x82\xa6\xe3\x83\x9e", + "\xe3\x82\xa2\xe3\x83\xb3\xe3\x83\x8e\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xbd\xe3\x83\xbc\xe3\x83\x8a\xe3\x83\xb3\xe3\x82\xb9", + "\xe3\x82\xad\xe3\x83\xaa\xe3\x83\xb3\xe3\x83\xaa\xe3\x82\xad", + "\xe3\x82\xaf\xe3\x83\x8c\xe3\x82\xae\xe3\x83\x80\xe3\x83\x9e", + "\xe3\x83\x95\xe3\x82\xa9\xe3\x83\xac\xe3\x83\x88\xe3\x82\xb9", + "\xe3\x83\x8e\xe3\x82\xb3\xe3\x83\x83\xe3\x83\x81", + "\xe3\x82\xb0\xe3\x83\xa9\xe3\x82\xa4\xe3\x82\xac\xe3\x83\xbc", + "\xe3\x83\x8f\xe3\x82\xac\xe3\x83\x8d\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc", + "\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xb3\xe3\x83\x96\xe3\x83\xab", + "\xe3\x83\x8f\xe3\x83\xaa\xe3\x83\xbc\xe3\x82\xbb\xe3\x83\xb3", + "\xe3\x83\x8f\xe3\x83\x83\xe3\x82\xb5\xe3\x83\xa0", + "\xe3\x83\x84\xe3\x83\x9c\xe3\x83\x84\xe3\x83\x9c", + "\xe3\x83\x98\xe3\x83\xa9\xe3\x82\xaf\xe3\x83\xad\xe3\x82\xb9", + "\xe3\x83\x8b\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xa9", + "\xe3\x83\x92\xe3\x83\xa1\xe3\x82\xb0\xe3\x83\x9e", + "\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\x9e", + "\xe3\x83\x9e\xe3\x82\xb0\xe3\x83\x9e\xe3\x83\x83\xe3\x82\xb0", + "\xe3\x83\x9e\xe3\x82\xb0\xe3\x82\xab\xe3\x83\xab\xe3\x82\xb4", + "\xe3\x82\xa6\xe3\x83\xaa\xe3\x83\xa0\xe3\x83\xbc", + "\xe3\x82\xa4\xe3\x83\x8e\xe3\x83\xa0\xe3\x83\xbc", + "\xe3\x82\xb5\xe3\x83\x8b\xe3\x83\xbc\xe3\x82\xb4", + "\xe3\x83\x86\xe3\x83\x83\xe3\x83\x9d\xe3\x82\xa6\xe3\x82\xaa", + "\xe3\x82\xaa\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xb3", + "\xe3\x83\x87\xe3\x83\xaa\xe3\x83\x90\xe3\x83\xbc\xe3\x83\x89", + "\xe3\x83\x9e\xe3\x83\xb3\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x82\xa8\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\xa0\xe3\x83\x89", + "\xe3\x83\x87\xe3\x83\xab\xe3\x83\x93\xe3\x83\xab", + "\xe3\x83\x98\xe3\x83\xab\xe3\x82\xac\xe3\x83\xbc", + "\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\x89\xe3\x83\xa9", + "\xe3\x82\xb4\xe3\x83\x9e\xe3\x82\xbe\xe3\x82\xa6", + "\xe3\x83\x89\xe3\x83\xb3\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xb3", + "\xe3\x83\x9d\xe3\x83\xaa\xe3\x82\xb4\xe3\x83\xb3\xef\xbc\x92", + "\xe3\x82\xaa\xe3\x83\x89\xe3\x82\xb7\xe3\x82\xb7", + "\xe3\x83\x89\xe3\x83\xbc\xe3\x83\x96\xe3\x83\xab", + "\xe3\x83\x90\xe3\x83\xab\xe3\x82\xad\xe3\x83\xbc", + "\xe3\x82\xab\xe3\x83\x9d\xe3\x82\xa8\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\xa0\xe3\x83\x81\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xa8\xe3\x83\xac\xe3\x82\xad\xe3\x83\x83\xe3\x83\x89", + "\xe3\x83\x96\xe3\x83\x93\xe3\x82\xa3", + "\xe3\x83\x9f\xe3\x83\xab\xe3\x82\xbf\xe3\x83\xb3\xe3\x82\xaf", + "\xe3\x83\x8f\xe3\x83\x94\xe3\x83\x8a\xe3\x82\xb9", + "\xe3\x83\xa9\xe3\x82\xa4\xe3\x82\xb3\xe3\x82\xa6", + "\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x86\xe3\x82\xa4", + "\xe3\x82\xb9\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xb3", + "\xe3\x83\xa8\xe3\x83\xbc\xe3\x82\xae\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x82\xb5\xe3\x83\x8a\xe3\x82\xae\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\x90\xe3\x83\xb3\xe3\x82\xae\xe3\x83\xa9\xe3\x82\xb9", + "\xe3\x83\xab\xe3\x82\xae\xe3\x82\xa2", + "\xe3\x83\x9b\xe3\x82\xa6\xe3\x82\xaa\xe3\x82\xa6", + "\xe3\x82\xbb\xe3\x83\xac\xe3\x83\x93\xe3\x82\xa3", + "\xe3\x82\xad\xe3\x83\xa2\xe3\x83\xaa", + "\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\x97\xe3\x83\x88\xe3\x83\xab", + "\xe3\x82\xb8\xe3\x83\xa5\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xb3", + "\xe3\x82\xa2\xe3\x83\x81\xe3\x83\xa3\xe3\x83\xa2", + "\xe3\x83\xaf\xe3\x82\xab\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\xa2", + "\xe3\x83\x90\xe3\x82\xb7\xe3\x83\xa3\xe3\x83\xbc\xe3\x83\xa2", + "\xe3\x83\x9f\xe3\x82\xba\xe3\x82\xb4\xe3\x83\xad\xe3\x82\xa6", + "\xe3\x83\x8c\xe3\x83\x9e\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc", + "\xe3\x83\xa9\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xbc\xe3\x82\xb8", + "\xe3\x83\x9d\xe3\x83\x81\xe3\x82\xa8\xe3\x83\x8a", + "\xe3\x82\xb0\xe3\x83\xa9\xe3\x82\xa8\xe3\x83\x8a", + "\xe3\x82\xb8\xe3\x82\xb0\xe3\x82\xb6\xe3\x82\xb0\xe3\x83\x9e", + "\xe3\x83\x9e\xe3\x83\x83\xe3\x82\xb9\xe3\x82\xb0\xe3\x83\x9e", + "\xe3\x82\xb1\xe3\x83\xa0\xe3\x83\x83\xe3\x82\xbd", + "\xe3\x82\xab\xe3\x83\xa9\xe3\x82\xb5\xe3\x83\xaa\xe3\x82\xb9", + "\xe3\x82\xa2\xe3\x82\xb2\xe3\x83\x8f\xe3\x83\xb3\xe3\x83\x88", + "\xe3\x83\x9e\xe3\x83\xa6\xe3\x83\xab\xe3\x83\x89", + "\xe3\x83\x89\xe3\x82\xaf\xe3\x82\xb1\xe3\x82\xa4\xe3\x83\xab", + "\xe3\x83\x8f\xe3\x82\xb9\xe3\x83\x9c\xe3\x83\xbc", + "\xe3\x83\x8f\xe3\x82\xb9\xe3\x83\x96\xe3\x83\xac\xe3\x83\xad", + "\xe3\x83\xab\xe3\x83\xb3\xe3\x83\x91\xe3\x83\x83\xe3\x83\x91", + "\xe3\x82\xbf\xe3\x83\x8d\xe3\x83\x9c\xe3\x83\xbc", + "\xe3\x82\xb3\xe3\x83\x8e\xe3\x83\x8f\xe3\x83\x8a", + "\xe3\x83\x80\xe3\x83\xbc\xe3\x83\x86\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x82\xb9\xe3\x83\x90\xe3\x83\xa1", + "\xe3\x82\xaa\xe3\x82\xaa\xe3\x82\xb9\xe3\x83\x90\xe3\x83\xa1", + "\xe3\x82\xad\xe3\x83\xa3\xe3\x83\xa2\xe3\x83\xa1", + "\xe3\x83\x9a\xe3\x83\xaa\xe3\x83\x83\xe3\x83\x91\xe3\x83\xbc", + "\xe3\x83\xa9\xe3\x83\xab\xe3\x83\x88\xe3\x82\xb9", + "\xe3\x82\xad\xe3\x83\xab\xe3\x83\xaa\xe3\x82\xa2", + "\xe3\x82\xb5\xe3\x83\xbc\xe3\x83\x8a\xe3\x82\xa4\xe3\x83\x88", + "\xe3\x82\xa2\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\x9e", + "\xe3\x82\xa2\xe3\x83\xa1\xe3\x83\xa2\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x82\xad\xe3\x83\x8e\xe3\x82\xb3\xe3\x82\xb3", + "\xe3\x82\xad\xe3\x83\x8e\xe3\x82\xac\xe3\x83\x83\xe3\x82\xb5", + "\xe3\x83\x8a\xe3\x83\x9e\xe3\x82\xb1\xe3\x83\xad", + "\xe3\x83\xa4\xe3\x83\xab\xe3\x82\xad\xe3\x83\xa2\xe3\x83\x8e", + "\xe3\x82\xb1\xe3\x83\x83\xe3\x82\xad\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x83\x84\xe3\x83\x81\xe3\x83\x8b\xe3\x83\xb3", + "\xe3\x83\x86\xe3\x83\x83\xe3\x82\xab\xe3\x83\x8b\xe3\x83\xb3", + "\xe3\x83\x8c\xe3\x82\xb1\xe3\x83\x8b\xe3\x83\xb3", + "\xe3\x82\xb4\xe3\x83\x8b\xe3\x83\xa7\xe3\x83\x8b\xe3\x83\xa7", + "\xe3\x83\x89\xe3\x82\xb4\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x83\x90\xe3\x82\xaf\xe3\x82\xaa\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x83\x9e\xe3\x82\xaf\xe3\x83\x8e\xe3\x82\xb7\xe3\x82\xbf", + "\xe3\x83\x8f\xe3\x83\xaa\xe3\x83\x86\xe3\x83\xa4\xe3\x83\x9e", + "\xe3\x83\xab\xe3\x83\xaa\xe3\x83\xaa", + "\xe3\x83\x8e\xe3\x82\xba\xe3\x83\x91\xe3\x82\xb9", + "\xe3\x82\xa8\xe3\x83\x8d\xe3\x82\xb3", + "\xe3\x82\xa8\xe3\x83\x8d\xe3\x82\xb3\xe3\x83\xad\xe3\x83\xad", + "\xe3\x83\xa4\xe3\x83\x9f\xe3\x83\xa9\xe3\x83\x9f", + "\xe3\x82\xaf\xe3\x83\x81\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x82\xb3\xe3\x82\xb3\xe3\x83\x89\xe3\x83\xa9", + "\xe3\x82\xb3\xe3\x83\x89\xe3\x83\xa9", + "\xe3\x83\x9c\xe3\x82\xb9\xe3\x82\xb4\xe3\x83\x89\xe3\x83\xa9", + "\xe3\x82\xa2\xe3\x82\xb5\xe3\x83\x8a\xe3\x83\xb3", + "\xe3\x83\x81\xe3\x83\xa3\xe3\x83\xbc\xe3\x83\xac\xe3\x83\xa0", + "\xe3\x83\xa9\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa4", + "\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\x9c\xe3\x83\xab\xe3\x83\x88", + "\xe3\x83\x97\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\xab", + "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\x8a\xe3\x83\xb3", + "\xe3\x83\x90\xe3\x83\xab\xe3\x83\x93\xe3\x83\xbc\xe3\x83\x88", + "\xe3\x82\xa4\xe3\x83\xab\xe3\x83\x9f\xe3\x83\xbc\xe3\x82\xbc", + "\xe3\x83\xad\xe3\x82\xbc\xe3\x83\xaa\xe3\x82\xa2", + "\xe3\x82\xb4\xe3\x82\xaf\xe3\x83\xaa\xe3\x83\xb3", + "\xe3\x83\x9e\xe3\x83\xab\xe3\x83\x8e\xe3\x83\xbc\xe3\x83\xa0", + "\xe3\x82\xad\xe3\x83\x90\xe3\x83\x8b\xe3\x82\xa2", + "\xe3\x82\xb5\xe3\x83\xa1\xe3\x83\x8f\xe3\x83\x80\xe3\x83\xbc", + "\xe3\x83\x9b\xe3\x82\xa8\xe3\x83\xab\xe3\x82\xb3", + "\xe3\x83\x9b\xe3\x82\xa8\xe3\x83\xab\xe3\x82\xaa\xe3\x83\xbc", + "\xe3\x83\x89\xe3\x83\xb3\xe3\x83\xa1\xe3\x83\xab", + "\xe3\x83\x90\xe3\x82\xaf\xe3\x83\xbc\xe3\x83\x80", + "\xe3\x82\xb3\xe3\x83\xbc\xe3\x82\xbf\xe3\x82\xb9", + "\xe3\x83\x90\xe3\x83\x8d\xe3\x83\x96\xe3\x83\xbc", + "\xe3\x83\x96\xe3\x83\xbc\xe3\x83\x94\xe3\x83\x83\xe3\x82\xb0", + "\xe3\x83\x91\xe3\x83\x83\xe3\x83\x81\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x8a\xe3\x83\x83\xe3\x82\xaf\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\x93\xe3\x83\x96\xe3\x83\xa9\xe3\x83\xbc\xe3\x83\x90", + "\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x82\xb4\xe3\x83\xb3", + "\xe3\x82\xb5\xe3\x83\x9c\xe3\x83\x8d\xe3\x82\xa2", + "\xe3\x83\x8e\xe3\x82\xaf\xe3\x82\xbf\xe3\x82\xb9", + "\xe3\x83\x81\xe3\x83\xab\xe3\x83\x83\xe3\x83\x88", + "\xe3\x83\x81\xe3\x83\xab\xe3\x82\xbf\xe3\x83\xaa\xe3\x82\xb9", + "\xe3\x82\xb6\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb9", + "\xe3\x83\x8f\xe3\x83\x96\xe3\x83\x8d\xe3\x83\xbc\xe3\x82\xaf", + "\xe3\x83\xab\xe3\x83\x8a\xe3\x83\x88\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xbd\xe3\x83\xab\xe3\x83\xad\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x83\x89\xe3\x82\xb8\xe3\x83\xa7\xe3\x83\x83\xe3\x83\x81", + "\xe3\x83\x8a\xe3\x83\x9e\xe3\x82\xba\xe3\x83\xb3", + "\xe3\x83\x98\xe3\x82\xa4\xe3\x82\xac\xe3\x83\x8b", + "\xe3\x82\xb7\xe3\x82\xb6\xe3\x83\xaa\xe3\x82\xac\xe3\x83\xbc", + "\xe3\x83\xa4\xe3\x82\xb8\xe3\x83\xad\xe3\x83\xb3", + "\xe3\x83\x8d\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\xaa\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xa9", + "\xe3\x83\xa6\xe3\x83\xac\xe3\x82\xa4\xe3\x83\x89\xe3\x83\xab", + "\xe3\x82\xa2\xe3\x83\x8e\xe3\x83\x97\xe3\x82\xb9", + "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\x9e\xe3\x83\xab\xe3\x83\x89", + "\xe3\x83\x92\xe3\x83\xb3\xe3\x83\x90\xe3\x82\xb9", + "\xe3\x83\x9f\xe3\x83\xad\xe3\x82\xab\xe3\x83\xad\xe3\x82\xb9", + "\xe3\x83\x9d\xe3\x83\xaf\xe3\x83\xab\xe3\x83\xb3", + "\xe3\x82\xab\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xaa\xe3\x83\xb3", + "\xe3\x82\xab\xe3\x82\xb2\xe3\x83\x9c\xe3\x82\xa6\xe3\x82\xba", + "\xe3\x82\xb8\xe3\x83\xa5\xe3\x83\x9a\xe3\x83\x83\xe3\x82\xbf", + "\xe3\x83\xa8\xe3\x83\x9e\xe3\x83\xaf\xe3\x83\xab", + "\xe3\x82\xb5\xe3\x83\x9e\xe3\x83\xa8\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x83\x88\xe3\x83\xad\xe3\x83\x94\xe3\x82\xa6\xe3\x82\xb9", + "\xe3\x83\x81\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xb3", + "\xe3\x82\xa2\xe3\x83\x96\xe3\x82\xbd\xe3\x83\xab", + "\xe3\x82\xbd\xe3\x83\xbc\xe3\x83\x8a\xe3\x83\x8e", + "\xe3\x83\xa6\xe3\x82\xad\xe3\x83\xaf\xe3\x83\xa9\xe3\x82\xb7", + "\xe3\x82\xaa\xe3\x83\x8b\xe3\x82\xb4\xe3\x83\xbc\xe3\x83\xaa", + "\xe3\x82\xbf\xe3\x83\x9e\xe3\x82\xb6\xe3\x83\xa9\xe3\x82\xb7", + "\xe3\x83\x88\xe3\x83\x89\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xbc", + "\xe3\x83\x88\xe3\x83\x89\xe3\x82\xbc\xe3\x83\xab\xe3\x82\xac", + "\xe3\x83\x91\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xab", + "\xe3\x83\x8f\xe3\x83\xb3\xe3\x83\x86\xe3\x83\xbc\xe3\x83\xab", + "\xe3\x82\xb5\xe3\x82\xaf\xe3\x83\xa9\xe3\x83\x93\xe3\x82\xb9", + "\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xa9\xe3\x83\xb3\xe3\x82\xb9", + "\xe3\x83\xa9\xe3\x83\x96\xe3\x82\xab\xe3\x82\xb9", + "\xe3\x82\xbf\xe3\x83\x84\xe3\x83\x99\xe3\x82\xa4", + "\xe3\x82\xb3\xe3\x83\xa2\xe3\x83\xab\xe3\x83\xbc", + "\xe3\x83\x9c\xe3\x83\xbc\xe3\x83\x9e\xe3\x83\xb3\xe3\x83\x80", + "\xe3\x83\x80\xe3\x83\xb3\xe3\x83\x90\xe3\x83\xab", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x83\xb3\xe3\x82\xb0", + "\xe3\x83\xa1\xe3\x82\xbf\xe3\x82\xb0\xe3\x83\xad\xe3\x82\xb9", + "\xe3\x83\xac\xe3\x82\xb8\xe3\x83\xad\xe3\x83\x83\xe3\x82\xaf", + "\xe3\x83\xac\xe3\x82\xb8\xe3\x82\xa2\xe3\x82\xa4\xe3\x82\xb9", + "\xe3\x83\xac\xe3\x82\xb8\xe3\x82\xb9\xe3\x83\x81\xe3\x83\xab", + "\xe3\x83\xa9\xe3\x83\x86\xe3\x82\xa3\xe3\x82\xa2\xe3\x82\xb9", + "\xe3\x83\xa9\xe3\x83\x86\xe3\x82\xa3\xe3\x82\xaa\xe3\x82\xb9", + "\xe3\x82\xab\xe3\x82\xa4\xe3\x82\xaa\xe3\x83\xbc\xe3\x82\xac", + "\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\xbc\xe3\x83\x89\xe3\x83\xb3", + "\xe3\x83\xac\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xa6\xe3\x82\xb6", + "\xe3\x82\xb8\xe3\x83\xa9\xe3\x83\xbc\xe3\x83\x81", + "\xe3\x83\x87\xe3\x82\xaa\xe3\x82\xad\xe3\x82\xb7\xe3\x82\xb9", + "\xe3\x82\xa6\xe3\x82\xbd\xe3\x83\x8f\xe3\x83\x81" +}; + +} + +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Core/ItemInfo.cpp b/LibPkmGC/src/LibPkmGC/Core/ItemInfo.cpp new file mode 100644 index 0000000..0869627 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/ItemInfo.cpp @@ -0,0 +1,46 @@ +#include +#include + +namespace LibPkmGC { + +void Item::load(u8 * data) { + LD_FIELD_E(u16, index, 0, ItemIndex); + LD_FIELD(u16, quantity, 2); +} + +void Item::save(u8 * data) { + SV_FIELD_E(u16, index, 0, ItemIndex); + SV_FIELD(u16, quantity, 2); +} + +ItemCategoryIndex getItemCategory(ItemIndex index, bool isXD) { + u16 i = (u16)index; + if ((index >= MasterBall) && (index <= PremierBall)) return PokeballsCategory; + if ((index >= Potion) && (index <= GreenShard)) return RegularItemsCategory; + if ((index >= HPUp) && (index <= Repel) && (i != 0x48) && (i != 0x52)) return RegularItemsCategory; + if ((index >= SunStone) && (index <= LeafStone)) return RegularItemsCategory; + if ((index >= TinyMushroom) && (index <= HeartScale) && (i != 0x69)) return RegularItemsCategory; + if ((index >= OrangeMail) && (index <= RetroMail)) return RegularItemsCategory; + if ((index >= CheriBerry) && (index <= EnigmaBerry)) return BerriesCategory; + if ((index >= BrightPowder) && (index <= Stick)) return RegularItemsCategory; + if ((index >= RedScarf) && (index <= YellowScarf)) return RegularItemsCategory; + if ((index >= TM01) && (index <= TM50)) return TMsCategory; + if (isXD) { + if ((index >= SafeKey) && (index <= MirorRadar)) return KeyItemsCategory; + if (index == PokeSnack) return RegularItemsCategory; + if (index == CologneCase_XD) return KeyItemsCategory; + if ((index >= JoyScent_XD) && (index <= VividScent_XD)) return ColognesCategory; + if ((index >= SunShard) && (index <= CryAnalyzer)) return KeyItemsCategory; + if ((index >= KraneMemo1) && (index <= DiscCase)) return KeyItemsCategory; + if ((index >= BattleCD01) && (index <= BattleCD60)) return BattleCDsCategory; + } + else { + if ((index >= JailKey) && (index <= YlwIDBadge)) return KeyItemsCategory; + if (index == TimeFlute) return RegularItemsCategory; + if ((index >= JoyScent_C) && (index <= VividScent_C)) return ColognesCategory; + if ((index == PowerupPart) || (index == EinFileF)) return KeyItemsCategory; + } + return NoItemCategory; +} + +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/Core/Localization.cpp b/LibPkmGC/src/LibPkmGC/Core/Localization.cpp new file mode 100644 index 0000000..fe3dc81 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/Localization.cpp @@ -0,0 +1,533 @@ +#include +//^([0-9a-f]*)\t(.*){{null}} +//(.*)(\\n|\\0) + + + +namespace LibPkmGC { + +namespace Localization { + +size_t itemIndexToNameIndex(ItemIndex index, bool isXD) { + size_t i = (size_t)index; + if ((index >= NoItem) && (index <= GreenShard)) return i; + i -= 11; + if ((index >= HPUp) && (index <= PPMax)) return i; + --i; + if ((index >= GuardSpec) && (index <= FluffyTail)) return i; + --i; + if ((index >= SuperRepel) && (index <= Repel)) return i; + i -= 6; + if ((index >= SunStone) && (index <= LeafStone)) return i; + i -= 4; + if ((index == TinyMushroom) || (index == BigMushroom)) return i; + --i; + if ((index >= Pearl) && (index <= HeartScale)) return i; + i -= 9; + if ((index >= OrangeMail) && (index <= EnigmaBerry)) return i; + i -= 3; + if ((index >= BrightPowder) && (index <= Stick)) return i; + i -= 28; + if ((index >= RedScarf) && (index <= YellowScarf)) return i; + i -= 30; + if ((index >= TM01) && (index <= TM50)) return i; + i -= 161; + if (isXD) { + if (index < SafeKey || index > BattleCD60) return 0; + return i; + } + else{ + if (index < SafeKey || index > EinFileF) return 0; + return i; + } + return 0; +} + +ItemIndex nameIndexToItemIndex(size_t index, bool isXD) { + static const ItemIndex commonItems[] = { + NoItem, + MasterBall, + UltraBall, + GreatBall, + PokeBall, + SafariBall, + NetBall, + DiveBall, + NestBall, + RepeatBall, + TimerBall, + LuxuryBall, + PremierBall, + Potion, + Antidote, + BurnHeal, + IceHeal, + Awakening, + ParlyzHeal, + FullRestore, + MaxPotion, + HyperPotion, + SuperPotion, + FullHeal, + Revive, + MaxRevive, + FreshWater, + SodaPop, + Lemonade, + MoomooMilk, + EnergyPowder, + EnergyRoot, + HealPowder, + RevivalHerb, + Ether, + MaxEther, + Elixir, + MaxElixir, + LavaCookie, + BlueFlute, + YellowFlute, + RedFlute, + BlackFlute, + WhiteFlute, + BerryJuice, + SacredAsh, + ShoalSalt, + ShoalShell, + RedShard, + BlueShard, + YellowShard, + GreenShard, + + + HPUp, + Protein, + Iron, + Carbos, + Calcium, + RareCandy, + PPUp, + Zinc, + PPMax, + + + GuardSpec, + DireHit, + XAttack, + XDefend, + XSpeed, + XAccuracy, + XSpecial, + Pokedoll, + FluffyTail, + + SuperRepel, + MaxRepel, + EscapeRope, + Repel, + + SunStone, + MoonStone, + FireStone, + ThunderStone, + WaterStone, + LeafStone, + + TinyMushroom, + BigMushroom, + + Pearl, + BigPearl, + Stardust, + StarPiece, + Nugget, + HeartScale, + + OrangeMail, + HarborMail, + GlitterMail, + MechMail, + WoodMail, + WaveMail, + BeadMail, + ShadowMail, + TropicMail, + DreamMail, + FabMail, + RetroMail, + + CheriBerry, + ChestoBerry, + PechaBerry, + RawstBerry, + AspearBerry, + LeppaBerry, + OranBerry, + PersimBerry, + LumBerry, + SitrusBerry, + FigyBerry, + WikiBerry, + MagoBerry, + AguavBerry, + IapapaBerry, + RazzBerry, + BlukBerry, + NanabBerry, + WepearBerry, + PinapBerry, + PomegBerry, + KelpsyBerry, + QualotBerry, + HondewBerry, + GrepaBerry, + TamatoBerry, + CornnBerry, + MagostBerry, + RabutaBerry, + NomelBerry, + SpelonBerry, + PamtreBerry, + WatmelBerry, + DurinBerry, + BelueBerry, + LiechiBerry, + GanlonBerry, + SalacBerry, + PetayaBerry, + ApicotBerry, + LansatBerry, + StarfBerry, + EnigmaBerry, + + BrightPowder, + WhiteHerb, + MachoBrace, + ExpShare, + QuickClaw, + SootheBell, + MentalHerb, + ChoiceBand, + KingsRock, + SilverPowder, + AmuletCoin, + CleanseTag, + SoulDew, + DeepSeaTooth, + DeepSeaScale, + SmokeBall, + Everstone, + FocusBand, + LuckyEgg, + ScopeLens, + MetalCoat, + Leftovers, + DragonScale, + LightBall, + SoftSand, + HardStone, + MiracleSeed, + BlackGlasses, + BlackBelt, + Magnet, + MysticWater, + SharpBeak, + PoisonBarb, + NeverMeltIce, + SpellTag, + TwistedSpoon, + Charcoal, + DragonFang, + SilkScarf, + UpGrade, + ShellBell, + SeaIncense, + LaxIncense, + LuckyPunch, + MetalPowder, + ThickClub, + Stick, + + + RedScarf, + BlueScarf, + PinkScarf, + GreenScarf, + YellowScarf, + + TM01, + TM02, + TM03, + TM04, + TM05, + TM06, + TM07, + TM08, + TM09, + TM10, + TM11, + TM12, + TM13, + TM14, + TM15, + TM16, + TM17, + TM18, + TM19, + TM20, + TM21, + TM22, + TM23, + TM24, + TM25, + TM26, + TM27, + TM28, + TM29, + TM30, + TM31, + TM32, + TM33, + TM34, + TM35, + TM36, + TM37, + TM38, + TM39, + TM40, + TM41, + TM42, + TM43, + TM44, + TM45, + TM46, + TM47, + TM48, + TM49, + TM50 + }; + static const ItemIndex colosseumItems[] = { + JailKey, + ElevatorKey, + + SmallTablet, + FDisk, + RDisk, + LDisk, + DDisk, + UDisk, + SubwayKey, + MaingateKey, + CardKey, + DownStKey, + DNASample, + DNASample1, + DNASample2, + DNASample3, + DNASample4, + DNASample5, + DNASample6, + DNASample7, + DNASample8, + DNASample9, + DNASample10, + DNASample11, + DNASample12, + DNASample13, + DNASample14, + DNASample15, + DNASample16, + DNASample17, + DataROM_C, + SteelTeeth, + Gear, + RedIDBadge, + GrnIDBadge, + BluIDBadge, + YlwIDBadge, + TimeFlute, + EinFileS, + EinFileH, + EinFileC, + EinFileP, + CologneCase_C, + JoyScent_C, + ExciteScent_C, + VividScent_C, + PowerupPart, + EinFileF, + }; + static const ItemIndex XDItems[] = { + SafeKey, + ElevatorKey, + BonslyCard, + MachinePart, + GonzapsKey, + DataROM_XD, + IDCard, + MusicDisc, + SystemLever, + MayorsNote, + MirorRadar, + PokeSnack, + CologneCase_XD, + JoyScent_XD, + ExciteScent_XD, + VividScent_XD, + SunShard, + MoonShard, + BonslyPhoto, + CryAnalyzer, + + + KraneMemo1, + KraneMemo2, + KraneMemo3, + KraneMemo4, + KraneMemo5, + VoiceCase1, + VoiceCase2, + VoiceCase3, + VoiceCase4, + VoiceCase5, + DiscCase, + BattleCD01, + BattleCD02, + BattleCD03, + BattleCD04, + BattleCD05, + BattleCD06, + BattleCD07, + BattleCD08, + BattleCD09, + BattleCD10, + BattleCD11, + BattleCD12, + BattleCD13, + BattleCD14, + BattleCD15, + BattleCD16, + BattleCD17, + BattleCD18, + BattleCD19, + BattleCD20, + BattleCD21, + BattleCD22, + BattleCD23, + BattleCD24, + BattleCD25, + BattleCD26, + BattleCD27, + BattleCD28, + BattleCD29, + BattleCD30, + BattleCD31, + BattleCD32, + BattleCD33, + BattleCD34, + BattleCD35, + BattleCD36, + BattleCD37, + BattleCD38, + BattleCD39, + BattleCD40, + BattleCD41, + BattleCD42, + BattleCD43, + BattleCD44, + BattleCD45, + BattleCD46, + BattleCD47, + BattleCD48, + BattleCD49, + BattleCD50, + BattleCD51, + BattleCD52, + BattleCD53, + BattleCD54, + BattleCD55, + BattleCD56, + BattleCD57, + BattleCD58, + BattleCD59, + BattleCD60, + }; + + if (index < 245) return commonItems[index]; + index -= 245; + + if (isXD) { + if (index < 91) return XDItems[index]; + } + else { + if (index < 48) return colosseumItems[index]; + } + return NoItem; +} + +size_t pkmSpeciesIndexToNameIndex(PokemonSpeciesIndex index) { + if (index == Bonsly) return 387; + return (size_t) getPokedexIndexOf(index); +} +PokemonSpeciesIndex nameIndexToPkmSpeciesIndex(size_t index) { + if (index == 387) return Bonsly; + return getSpeciesIndexOf((u16)index); +} + +#define LIBPKMGC_CHECK_LANG_INDEX(lang) lang = ((lang == NoLanguage) || (lang > Spanish)) ? English : lang; +#define LIBPKMGC_GET_LOCALIZED_NAME_LIST(lang) const char **lst = (names[(size_t)lang] == NULL) ? names[2] : names[(size_t)lang]; +#define LIBPKMGC_GET_LOCALIZED_NAME(lang, id, maxval) LIBPKMGC_CHECK_LANG_INDEX(lang); LIBPKMGC_GET_LOCALIZED_NAME_LIST(lang);\ +return (id > maxval) ? lst[0] : lst[(size_t)id]; + +const char* getPokemonSpeciesName(LanguageIndex language, PokemonSpeciesIndex index) { + using namespace Detail::Species; + size_t id = pkmSpeciesIndexToNameIndex(index); + LIBPKMGC_GET_LOCALIZED_NAME(language, id, 387); +} + +const char* getPokemonSpeciesNameByPkdxIndex(LanguageIndex language, u16 pkdexIndex) { + using namespace Detail::Species; + size_t id = (pkdexIndex == 438) ? 387 : pkdexIndex; + LIBPKMGC_GET_LOCALIZED_NAME(language, id, 387); + +} + +const char* getPokemonNatureName(LanguageIndex language, PokemonNatureIndex index) { + using namespace Detail::Natures; + LIBPKMGC_GET_LOCALIZED_NAME(language, index, Quirky); +} + +const char* getPokemonMoveName(LanguageIndex language, PokemonMoveIndex index) { + using namespace Detail::Moves; + LIBPKMGC_GET_LOCALIZED_NAME(language, index, PsychoBoost); +} +const char* getPokemonAbilityName(LanguageIndex language, PokemonAbilityIndex index) { + using namespace Detail::Abilities; + LIBPKMGC_GET_LOCALIZED_NAME(language, index, AirLock); +} + +const char* getItemName(LanguageIndex language, ItemIndex index, bool isXD) { + LIBPKMGC_CHECK_LANG_INDEX(language); + size_t id = itemIndexToNameIndex(index, isXD); + + if (id < 245) { + using namespace Detail::GivableItems; + LIBPKMGC_GET_LOCALIZED_NAME_LIST(language); + return lst[id]; + } + + if (isXD) { + using namespace Detail::XDExclusiveItems; + LIBPKMGC_GET_LOCALIZED_NAME_LIST(language); + return lst[namesByIndex[id - 245]]; + } + else { + using namespace Detail::ColosseumExclusiveItems; + LIBPKMGC_GET_LOCALIZED_NAME_LIST(language); + return lst[id - 245]; + } + return 0; +} + + +} +} diff --git a/LibPkmGC/src/LibPkmGC/Core/PokemonInfo.cpp b/LibPkmGC/src/LibPkmGC/Core/PokemonInfo.cpp new file mode 100644 index 0000000..2c0f132 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/Core/PokemonInfo.cpp @@ -0,0 +1,5626 @@ +#include +#include + +namespace LibPkmGC{ + +void VersionInfo::load(u8 * data) { + LD_FIELD_E(u8, game, 0, GameIndex); + LD_FIELD_E(u8, currentRegion, 1, RegionIndex); + LD_FIELD_E(u8, originalRegion, 2, RegionIndex); + LD_FIELD_E(u8, language, 3, LanguageIndex); +} + +void VersionInfo::save(u8 * data) { + SV_FIELD_E(u8, game, 0, GameIndex); + SV_FIELD_E(u8, currentRegion, 1, RegionIndex); + SV_FIELD_E(u8, originalRegion, 2, RegionIndex); + SV_FIELD_E(u8, language, 3, LanguageIndex); +} + +bool VersionInfo::isIncomplete(void) const { + return (game == NoGame) || (currentRegion == NoRegion) || (originalRegion == NoRegion) || (language == NoLanguage); +} + +void PokemonMove::load(u8 * data) { + LD_FIELD_E(u16, moveIndex, 0, PokemonMoveIndex); + LD_FIELD(u8, currentPPs, 2); + LD_FIELD(u8, nbPPUpsUsed, 3); +} + +void PokemonMove::save(u8 * data) { + SV_FIELD_E(u16, moveIndex, 0, PokemonMoveIndex); + SV_FIELD(u8, currentPPs, 2); + SV_FIELD(u8, nbPPUpsUsed, 3); +} + +u8 PokemonMove::calculateMaxPP(void) const { + u32 baseMaxPP = (moveIndex > PsychoBoost) ? 0 : (u32)getBaseMoveMaxPPs(moveIndex); + return (u8)(baseMaxPP*(100 + (u32)nbPPUpsUsed * 20) / 100); +} + +void PokemonMarkings::load(u8 m) { + circle = (m & 1) != 0; + square = (m & 2) != 0; + triangle = (m & 4) != 0; + heart = (m & 8) != 0; +} + +u8 PokemonMarkings::save(void) const { + u8 m = (u8)(((heart) ? 1 : 0) << 3) | (((triangle) ? 1 : 0) << 2); + m |= (u8)(((square) ? 1 : 0) << 1) | ((circle) ? 1 : 0); + return m; +} + +u16 getPokedexIndexOf(PokemonSpeciesIndex speciesIndex) { + static const u16 remaining[] = { + 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344, 299, 324, + 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322, 323, 363, 364, 365, 331, 332, 361, 362, + 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334, 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, + 367, 368, 359, 353, 354, 336, 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}; + + u16 result = (u16)speciesIndex; + if (speciesIndex == Bonsly) return 438; + if (speciesIndex <= Celebi) return result; + if (speciesIndex < Treecko) return 0; + if (speciesIndex <= Shiftry) return (result - 25); + if (speciesIndex <= Chimecho) return remaining[result - 301]; + else return 0; + +} + +PokemonSpeciesIndex getSpeciesIndexOf(u16 pokedexIndex) { + static const PokemonSpeciesIndex speciesIndexFromPkdxIndexTable[388] = { + NoSpecies, + Bulbasaur, + Ivysaur, + Venusaur, + Charmander, + Charmeleon, + Charizard, + Squirtle, + Wartortle, + Blastoise, + Caterpie, + Metapod, + Butterfree, + Weedle, + Kakuna, + Beedrill, + Pidgey, + Pidgeotto, + Pidgeot, + Rattata, + Raticate, + Spearow, + Fearow, + Ekans, + Arbok, + Pikachu, + Raichu, + Sandshrew, + Sandslash, + NidoranF, + Nidorina, + Nidoqueen, + NidoranM, + Nidorino, + Nidoking, + Clefairy, + Clefable, + Vulpix, + Ninetales, + Jigglypuff, + Wigglytuff, + Zubat, + Golbat, + Oddish, + Gloom, + Vileplume, + Paras, + Parasect, + Venonat, + Venomoth, + Diglett, + Dugtrio, + Meowth, + Persian, + Psyduck, + Golduck, + Mankey, + Primeape, + Growlithe, + Arcanine, + Poliwag, + Poliwhirl, + Poliwrath, + Abra, + Kadabra, + Alakazam, + Machop, + Machoke, + Machamp, + Bellsprout, + Weepinbell, + Victreebel, + Tentacool, + Tentacruel, + Geodude, + Graveler, + Golem, + Ponyta, + Rapidash, + Slowpoke, + Slowbro, + Magnemite, + Magneton, + Farfetch_d, + Doduo, + Dodrio, + Seel, + Dewgong, + Grimer, + Muk, + Shellder, + Cloyster, + Gastly, + Haunter, + Gengar, + Onix, + Drowzee, + Hypno, + Krabby, + Kingler, + Voltorb, + Electrode, + Exeggcute, + Exeggutor, + Cubone, + Marowak, + Hitmonlee, + Hitmonchan, + Lickitung, + Koffing, + Weezing, + Rhyhorn, + Rhydon, + Chansey, + Tangela, + Kangaskhan, + Horsea, + Seadra, + Goldeen, + Seaking, + Staryu, + Starmie, + MrMime, + Scyther, + Jynx, + Electabuzz, + Magmar, + Pinsir, + Tauros, + Magikarp, + Gyarados, + Lapras, + Ditto, + Eevee, + Vaporeon, + Jolteon, + Flareon, + Porygon, + Omanyte, + Omastar, + Kabuto, + Kabutops, + Aerodactyl, + Snorlax, + Articuno, + Zapdos, + Moltres, + Dratini, + Dragonair, + Dragonite, + Mewtwo, + Mew, + Chikorita, + Bayleef, + Meganium, + Cyndaquil, + Quilava, + Typhlosion, + Totodile, + Croconaw, + Feraligatr, + Sentret, + Furret, + Hoothoot, + Noctowl, + Ledyba, + Ledian, + Spinarak, + Ariados, + Crobat, + Chinchou, + Lanturn, + Pichu, + Cleffa, + Igglybuff, + Togepi, + Togetic, + Natu, + Xatu, + Mareep, + Flaaffy, + Ampharos, + Bellossom, + Marill, + Azumarill, + Sudowoodo, + Politoed, + Hoppip, + Skiploom, + Jumpluff, + Aipom, + Sunkern, + Sunflora, + Yanma, + Wooper, + Quagsire, + Espeon, + Umbreon, + Murkrow, + Slowking, + Misdreavus, + Unown, + Wobbuffet, + Girafarig, + Pineco, + Forretress, + Dunsparce, + Gligar, + Steelix, + Snubbull, + Granbull, + Qwilfish, + Scizor, + Shuckle, + Heracross, + Sneasel, + Teddiursa, + Ursaring, + Slugma, + Magcargo, + Swinub, + Piloswine, + Corsola, + Remoraid, + Octillery, + Delibird, + Mantine, + Skarmory, + Houndour, + Houndoom, + Kingdra, + Phanpy, + Donphan, + Porygon2, + Stantler, + Smeargle, + Tyrogue, + Hitmontop, + Smoochum, + Elekid, + Magby, + Miltank, + Blissey, + Raikou, + Entei, + Suicune, + Larvitar, + Pupitar, + Tyranitar, + Lugia, + HoOh, + Celebi, + Treecko, + Grovyle, + Sceptile, + Torchic, + Combusken, + Blaziken, + Mudkip, + Marshtomp, + Swampert, + Poochyena, + Mightyena, + Zigzagoon, + Linoone, + Wurmple, + Silcoon, + Beautifly, + Cascoon, + Dustox, + Lotad, + Lombre, + Ludicolo, + Seedot, + Nuzleaf, + Shiftry, + Taillow, + Swellow, + Wingull, + Pelipper, + Ralts, + Kirlia, + Gardevoir, + Surskit, + Masquerain, + Shroomish, + Breloom, + Slakoth, + Vigoroth, + Slaking, + Nincada, + Ninjask, + Shedinja, + Whismur, + Loudred, + Exploud, + Makuhita, + Hariyama, + Azurill, + Nosepass, + Skitty, + Delcatty, + Sableye, + Mawile, + Aron, + Lairon, + Aggron, + Meditite, + Medicham, + Electrike, + Manectric, + Plusle, + Minun, + Volbeat, + Illumise, + Roselia, + Gulpin, + Swalot, + Carvanha, + Sharpedo, + Wailmer, + Wailord, + Numel, + Camerupt, + Torkoal, + Spoink, + Grumpig, + Spinda, + Trapinch, + Vibrava, + Flygon, + Cacnea, + Cacturne, + Swablu, + Altaria, + Zangoose, + Seviper, + Lunatone, + Solrock, + Barboach, + Whiscash, + Corphish, + Crawdaunt, + Baltoy, + Claydol, + Lileep, + Cradily, + Anorith, + Armaldo, + Feebas, + Milotic, + Castform, + Kecleon, + Shuppet, + Banette, + Duskull, + Dusclops, + Tropius, + Chimecho, + Absol, + Wynaut, + Snorunt, + Glalie, + Spheal, + Sealeo, + Walrein, + Clamperl, + Huntail, + Gorebyss, + Relicanth, + Luvdisc, + Bagon, + Shelgon, + Salamence, + Beldum, + Metang, + Metagross, + Regirock, + Regice, + Registeel, + Latias, + Latios, + Kyogre, + Groudon, + Rayquaza, + Jirachi, + Deoxys, + }; + if (pokedexIndex == 438) return Bonsly; + if (pokedexIndex > 387) return NoSpecies; + return speciesIndexFromPkdxIndexTable[(size_t)pokedexIndex]; +} + + +const u8 baseMoveMaxPPs[355] = { + 0, + 35, + 25, + 10, + 15, + 20, + 20, + 15, + 15, + 15, + 35, + 30, + 5, + 10, + 30, + 30, + 35, + 35, + 20, + 15, + 20, + 20, + 10, + 20, + 30, + 5, + 25, + 15, + 15, + 15, + 25, + 20, + 5, + 35, + 15, + 20, + 20, + 20, + 15, + 30, + 35, + 20, + 20, + 30, + 25, + 40, + 20, + 15, + 20, + 20, + 20, + 30, + 25, + 15, + 30, + 25, + 5, + 15, + 10, + 5, + 20, + 20, + 20, + 5, + 35, + 20, + 25, + 20, + 20, + 20, + 15, + 20, + 10, + 10, + 40, + 25, + 10, + 35, + 30, + 15, + 20, + 40, + 10, + 15, + 30, + 15, + 20, + 10, + 15, + 10, + 5, + 10, + 10, + 25, + 10, + 20, + 40, + 30, + 30, + 20, + 20, + 15, + 10, + 40, + 15, + 20, + 30, + 20, + 20, + 10, + 40, + 40, + 30, + 30, + 30, + 20, + 30, + 10, + 10, + 20, + 5, + 10, + 30, + 20, + 20, + 20, + 5, + 15, + 10, + 20, + 15, + 15, + 35, + 20, + 15, + 10, + 20, + 30, + 15, + 40, + 20, + 15, + 10, + 5, + 10, + 30, + 10, + 15, + 20, + 15, + 40, + 40, + 10, + 5, + 15, + 10, + 10, + 10, + 15, + 30, + 30, + 10, + 10, + 20, + 10, + 1, + 1, + 10, + 10, + 10, + 5, + 15, + 25, + 15, + 10, + 15, + 30, + 5, + 40, + 15, + 10, + 25, + 10, + 30, + 10, + 20, + 10, + 10, + 10, + 10, + 10, + 20, + 5, + 40, + 5, + 5, + 15, + 5, + 10, + 5, + 15, + 10, + 5, + 10, + 20, + 20, + 40, + 15, + 10, + 20, + 20, + 25, + 5, + 15, + 10, + 5, + 20, + 15, + 20, + 25, + 20, + 5, + 30, + 5, + 10, + 20, + 40, + 5, + 20, + 40, + 20, + 15, + 35, + 10, + 5, + 5, + 5, + 15, + 5, + 20, + 5, + 5, + 15, + 20, + 10, + 5, + 5, + 15, + 15, + 15, + 15, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 15, + 15, + 15, + 10, + 20, + 20, + 10, + 20, + 20, + 20, + 20, + 20, + 10, + 10, + 10, + 20, + 20, + 5, + 15, + 10, + 10, + 15, + 10, + 20, + 5, + 5, + 10, + 10, + 20, + 5, + 10, + 20, + 10, + 20, + 20, + 20, + 5, + 5, + 15, + 20, + 10, + 15, + 20, + 15, + 10, + 10, + 15, + 10, + 5, + 5, + 10, + 15, + 10, + 5, + 20, + 25, + 5, + 40, + 10, + 5, + 40, + 15, + 20, + 20, + 5, + 15, + 20, + 30, + 15, + 15, + 5, + 10, + 30, + 20, + 30, + 15, + 5, + 40, + 15, + 5, + 20, + 5, + 15, + 25, + 40, + 15, + 20, + 15, + 20, + 15, + 20, + 10, + 20, + 20, + 5, + 5 +}; + +LIBPKMGC_DECL const u32 expTables[6][101] = { + { + 0, + 1, + 8, + 27, + 64, + 125, + 216, + 343, + 512, + 729, + 1000, + 1331, + 1728, + 2197, + 2744, + 3375, + 4096, + 4913, + 5832, + 6859, + 8000, + 9261, + 10648, + 12167, + 13824, + 15625, + 17576, + 19683, + 21952, + 24389, + 27000, + 29791, + 32768, + 35937, + 39304, + 42875, + 46656, + 50653, + 54872, + 59319, + 64000, + 68921, + 74088, + 79507, + 85184, + 91125, + 97336, + 103823, + 110592, + 117649, + 125000, + 132651, + 140608, + 148877, + 157464, + 166375, + 175616, + 185193, + 195112, + 205379, + 216000, + 226981, + 238328, + 250047, + 262144, + 274625, + 287496, + 300763, + 314432, + 328509, + 343000, + 357911, + 373248, + 389017, + 405224, + 421875, + 438976, + 456533, + 474552, + 493039, + 512000, + 531441, + 551368, + 571787, + 592704, + 614125, + 636056, + 658503, + 681472, + 704969, + 729000, + 753571, + 778688, + 804357, + 830584, + 857375, + 884736, + 912673, + 941192, + 970299, + 1000000, + }, + { + 0, + 1, + 15, + 52, + 122, + 237, + 406, + 637, + 942, + 1326, + 1800, + 2369, + 3041, + 3822, + 4719, + 5737, + 6881, + 8155, + 9564, + 11111, + 12800, + 14632, + 16610, + 18737, + 21012, + 23437, + 26012, + 28737, + 31610, + 34632, + 37800, + 41111, + 44564, + 48155, + 51881, + 55737, + 59719, + 63822, + 68041, + 72369, + 76800, + 81326, + 85942, + 90637, + 95406, + 100237, + 105122, + 110052, + 115015, + 120001, + 125000, + 131324, + 137795, + 144410, + 151165, + 158056, + 165079, + 172229, + 179503, + 186894, + 194400, + 202013, + 209728, + 217540, + 225443, + 233431, + 241496, + 249633, + 257834, + 267406, + 276458, + 286328, + 296358, + 305767, + 316074, + 326531, + 336255, + 346965, + 357812, + 367807, + 378880, + 390077, + 400293, + 411686, + 423190, + 433572, + 445239, + 457001, + 467489, + 479378, + 491346, + 501878, + 513934, + 526049, + 536557, + 548720, + 560922, + 571333, + 583539, + 591882, + 600000, + }, + { + 0, + 1, + 4, + 13, + 32, + 65, + 112, + 178, + 276, + 393, + 540, + 745, + 967, + 1230, + 1591, + 1957, + 2457, + 3046, + 3732, + 4526, + 5440, + 6482, + 7666, + 9003, + 10506, + 12187, + 14060, + 16140, + 18439, + 20974, + 23760, + 26811, + 30146, + 33780, + 37731, + 42017, + 46656, + 50653, + 55969, + 60505, + 66560, + 71677, + 78533, + 84277, + 91998, + 98415, + 107069, + 114205, + 123863, + 131766, + 142500, + 151222, + 163105, + 172697, + 185807, + 196322, + 210739, + 222231, + 238036, + 250562, + 267840, + 281456, + 300293, + 315059, + 335544, + 351520, + 373744, + 390991, + 415050, + 433631, + 459620, + 479600, + 507617, + 529063, + 559209, + 582187, + 614566, + 639146, + 673863, + 700115, + 737280, + 765275, + 804997, + 834809, + 877201, + 908905, + 954084, + 987754, + 1035837, + 1071552, + 1122660, + 1160499, + 1214753, + 1254796, + 1312322, + 1354652, + 1415577, + 1460276, + 1524731, + 1571884, + 1640000, + }, + { + 0, + 1, + 9, + 57, + 96, + 135, + 179, + 236, + 314, + 419, + 560, + 742, + 973, + 1261, + 1612, + 2035, + 2535, + 3120, + 3798, + 4575, + 5460, + 6458, + 7577, + 8825, + 10208, + 11735, + 13411, + 15244, + 17242, + 19411, + 21760, + 24294, + 27021, + 29949, + 33084, + 36435, + 40007, + 43808, + 47846, + 52127, + 56660, + 61450, + 66505, + 71833, + 77440, + 83335, + 89523, + 96012, + 102810, + 109923, + 117360, + 125126, + 133229, + 141677, + 150476, + 159635, + 169159, + 179056, + 189334, + 199999, + 211060, + 222522, + 234393, + 246681, + 259392, + 272535, + 286115, + 300140, + 314618, + 329555, + 344960, + 360838, + 377197, + 394045, + 411388, + 429235, + 447591, + 466464, + 485862, + 505791, + 526260, + 547274, + 568841, + 590969, + 613664, + 636935, + 660787, + 685228, + 710266, + 735907, + 762160, + 789030, + 816525, + 844653, + 873420, + 902835, + 932903, + 963632, + 995030, + 1027103, + 1059860, + }, + { + 0, + 1, + 6, + 21, + 51, + 100, + 172, + 274, + 409, + 583, + 800, + 1064, + 1382, + 1757, + 2195, + 2700, + 3276, + 3930, + 4665, + 5487, + 6400, + 7408, + 8518, + 9733, + 11059, + 12500, + 14060, + 15746, + 17561, + 19511, + 21600, + 23832, + 26214, + 28749, + 31443, + 34300, + 37324, + 40522, + 43897, + 47455, + 51200, + 55136, + 59270, + 63605, + 68147, + 72900, + 77868, + 83058, + 88473, + 94119, + 100000, + 106120, + 112486, + 119101, + 125971, + 133100, + 140492, + 148154, + 156089, + 164303, + 172800, + 181584, + 190662, + 200037, + 209715, + 219700, + 229996, + 240610, + 251545, + 262807, + 274400, + 286328, + 298598, + 311213, + 324179, + 337500, + 351180, + 365226, + 379641, + 394431, + 409600, + 425152, + 441094, + 457429, + 474163, + 491300, + 508844, + 526802, + 545177, + 563975, + 583200, + 602856, + 622950, + 643485, + 664467, + 685900, + 707788, + 730138, + 752953, + 776239, + 800000, + }, + { + 0, + 1, + 10, + 33, + 80, + 156, + 270, + 428, + 640, + 911, + 1250, + 1663, + 2160, + 2746, + 3430, + 4218, + 5120, + 6141, + 7290, + 8573, + 10000, + 11576, + 13310, + 15208, + 17280, + 19531, + 21970, + 24603, + 27440, + 30486, + 33750, + 37238, + 40960, + 44921, + 49130, + 53593, + 58320, + 63316, + 68590, + 74148, + 80000, + 86151, + 92610, + 99383, + 106480, + 113906, + 121670, + 129778, + 138240, + 147061, + 156250, + 165813, + 175760, + 186096, + 196830, + 207968, + 219520, + 231491, + 243890, + 256723, + 270000, + 283726, + 297910, + 312558, + 327680, + 343281, + 359370, + 375953, + 393040, + 410636, + 428750, + 447388, + 466560, + 486271, + 506530, + 527343, + 548720, + 570666, + 593190, + 616298, + 640000, + 664301, + 689210, + 714733, + 740880, + 767656, + 795070, + 823128, + 851840, + 881211, + 911250, + 941963, + 973360, + 1005446, + 1038230, + 1071718, + 1105920, + 1140841, + 1176490, + 1212873, + 1250000, + }, +}; + +const PokemonNatureAffinity natureStatAffinities[25][5] = { + {Neutral, Neutral, Neutral, Neutral, Neutral}, + {Beneficial, Detrimental, Neutral, Neutral, Neutral}, + {Beneficial, Neutral, Neutral, Neutral, Detrimental}, + {Beneficial, Neutral, Detrimental, Neutral, Neutral}, + {Beneficial, Neutral, Neutral, Detrimental, Neutral}, + {Detrimental, Beneficial, Neutral, Neutral, Neutral}, + {Neutral, Neutral, Neutral, Neutral, Neutral}, + {Neutral, Beneficial, Neutral, Neutral, Detrimental}, + {Neutral, Beneficial, Detrimental, Neutral, Neutral}, + {Neutral, Beneficial, Neutral, Detrimental, Neutral}, + {Detrimental, Neutral, Neutral, Neutral, Beneficial}, + {Neutral, Detrimental, Neutral, Neutral, Beneficial}, + {Neutral, Neutral, Neutral, Neutral, Neutral}, + {Neutral, Neutral, Detrimental, Neutral, Beneficial}, + {Neutral, Neutral, Neutral, Detrimental, Beneficial}, + {Detrimental, Neutral, Beneficial, Neutral, Neutral}, + {Neutral, Detrimental, Beneficial, Neutral, Neutral}, + {Neutral, Neutral, Beneficial, Neutral, Detrimental}, + {Neutral, Neutral, Neutral, Neutral, Neutral}, + {Neutral, Neutral, Beneficial, Detrimental, Neutral}, + {Detrimental, Neutral, Neutral, Beneficial, Neutral}, + {Neutral, Detrimental, Neutral, Beneficial, Neutral}, + {Neutral, Neutral, Neutral, Beneficial, Detrimental}, + {Neutral, Neutral, Detrimental, Beneficial, Neutral}, + {Neutral, Neutral, Neutral, Neutral, Neutral}, +}; + +LIBPKMGC_DECL const PokemonSpeciesData speciesData[0x19f]= { + { + // NoAbility + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + // Bulbasaur + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {45, 49, 49, 65, 65, 45}, + {0, 0, 0, 1, 0, 0} + }, + { + // Ivysaur + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {60, 62, 63, 80, 80, 60}, + {0, 0, 0, 1, 1, 0} + }, + { + // Venusaur + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {80, 82, 83, 100, 100, 80}, + {0, 0, 0, 2, 1, 0} + }, + { + // Charmander + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {39, 52, 43, 60, 50, 65}, + {0, 0, 0, 0, 0, 1} + }, + { + // Charmeleon + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {58, 64, 58, 80, 65, 80}, + {0, 0, 0, 1, 0, 1} + }, + { + // Charizard + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {78, 84, 78, 109, 85, 100}, + {0, 0, 0, 3, 0, 0} + }, + { + // Squirtle + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {44, 48, 65, 50, 64, 43}, + {0, 0, 1, 0, 0, 0} + }, + { + // Wartortle + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {59, 63, 80, 65, 80, 58}, + {0, 0, 1, 0, 1, 0} + }, + { + // Blastoise + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {79, 83, 100, 85, 105, 78}, + {0, 0, 0, 0, 3, 0} + }, + { + // Caterpie + true, + MediumFast, + M1F1, + 70, + {ShieldDust, NoAbility}, + {45, 30, 35, 20, 20, 45}, + {1, 0, 0, 0, 0, 0} + }, + { + // Metapod + true, + MediumFast, + M1F1, + 70, + {ShedSkin, NoAbility}, + {50, 20, 55, 25, 25, 30}, + {0, 0, 2, 0, 0, 0} + }, + { + // Butterfree + true, + MediumFast, + M1F1, + 70, + {Compoundeyes, NoAbility}, + {60, 45, 50, 80, 80, 70}, + {0, 0, 0, 2, 1, 0} + }, + { + // Weedle + true, + MediumFast, + M1F1, + 70, + {ShieldDust, NoAbility}, + {40, 35, 30, 20, 20, 50}, + {0, 0, 0, 0, 0, 1} + }, + { + // Kakuna + true, + MediumFast, + M1F1, + 70, + {ShedSkin, NoAbility}, + {45, 25, 50, 25, 25, 35}, + {0, 0, 2, 0, 0, 0} + }, + { + // Beedrill + true, + MediumFast, + M1F1, + 70, + {Swarm, NoAbility}, + {65, 80, 40, 45, 80, 75}, + {0, 2, 0, 0, 1, 0} + }, + { + // Pidgey + true, + MediumSlow, + M1F1, + 70, + {KeenEye, NoAbility}, + {40, 45, 40, 35, 35, 56}, + {0, 0, 0, 0, 0, 1} + }, + { + // Pidgeotto + true, + MediumSlow, + M1F1, + 70, + {KeenEye, NoAbility}, + {63, 60, 55, 50, 50, 71}, + {0, 0, 0, 0, 0, 2} + }, + { + // Pidgeot + true, + MediumSlow, + M1F1, + 70, + {KeenEye, NoAbility}, + {83, 80, 75, 70, 70, 91}, + {0, 0, 0, 0, 0, 3} + }, + { + // Rattata + true, + MediumFast, + M1F1, + 70, + {RunAway, Guts}, + {30, 56, 35, 25, 35, 72}, + {0, 0, 0, 0, 0, 1} + }, + { + // Raticate + true, + MediumFast, + M1F1, + 70, + {RunAway, Guts}, + {55, 81, 60, 50, 70, 97}, + {0, 0, 0, 0, 0, 2} + }, + { + // Spearow + true, + MediumFast, + M1F1, + 70, + {KeenEye, NoAbility}, + {40, 60, 30, 31, 31, 70}, + {0, 0, 0, 0, 0, 1} + }, + { + // Fearow + true, + MediumFast, + M1F1, + 70, + {KeenEye, NoAbility}, + {65, 90, 65, 61, 61, 100}, + {0, 0, 0, 0, 0, 2} + }, + { + // Ekans + true, + MediumFast, + M1F1, + 70, + {Intimidate, ShedSkin}, + {35, 60, 44, 40, 54, 55}, + {0, 1, 0, 0, 0, 0} + }, + { + // Arbok + true, + MediumFast, + M1F1, + 70, + {Intimidate, ShedSkin}, + {60, 85, 69, 65, 79, 80}, + {0, 2, 0, 0, 0, 0} + }, + { + // Pikachu + true, + MediumFast, + M1F1, + 70, + {Static, NoAbility}, + {35, 55, 30, 50, 40, 90}, + {0, 0, 0, 0, 0, 2} + }, + { + // Raichu + true, + MediumFast, + M1F1, + 70, + {Static, NoAbility}, + {60, 90, 55, 90, 80, 100}, + {0, 0, 0, 0, 0, 3} + }, + { + // Sandshrew + true, + MediumFast, + M1F1, + 70, + {SandVeil, NoAbility}, + {50, 75, 85, 20, 30, 40}, + {0, 0, 1, 0, 0, 0} + }, + { + // Sandslash + true, + MediumFast, + M1F1, + 70, + {SandVeil, NoAbility}, + {75, 100, 110, 45, 55, 65}, + {0, 0, 2, 0, 0, 0} + }, + { + // Nidoran (F) + true, + MediumSlow, + FemaleOnly, + 70, + {PoisonPoint, NoAbility}, + {55, 47, 52, 40, 40, 41}, + {1, 0, 0, 0, 0, 0} + }, + { + // Nidorina + true, + MediumSlow, + FemaleOnly, + 70, + {PoisonPoint, NoAbility}, + {70, 62, 67, 55, 55, 56}, + {2, 0, 0, 0, 0, 0} + }, + { + // Nidoqueen + true, + MediumSlow, + FemaleOnly, + 70, + {PoisonPoint, NoAbility}, + {90, 82, 87, 75, 85, 76}, + {3, 0, 0, 0, 0, 0} + }, + { + // Nidoran (M) + true, + MediumSlow, + MaleOnly, + 70, + {PoisonPoint, NoAbility}, + {46, 57, 40, 40, 40, 50}, + {0, 1, 0, 0, 0, 0} + }, + { + // Nidorino + true, + MediumSlow, + MaleOnly, + 70, + {PoisonPoint, NoAbility}, + {61, 72, 57, 55, 55, 65}, + {0, 2, 0, 0, 0, 0} + }, + { + // Nidoking + true, + MediumSlow, + MaleOnly, + 70, + {PoisonPoint, NoAbility}, + {81, 92, 77, 85, 75, 85}, + {0, 3, 0, 0, 0, 0} + }, + { + // Clefairy + true, + Fast, + M3F1, + 140, + {CuteCharm, NoAbility}, + {70, 45, 48, 60, 65, 35}, + {2, 0, 0, 0, 0, 0} + }, + { + // Clefable + true, + Fast, + M3F1, + 140, + {CuteCharm, NoAbility}, + {95, 70, 73, 85, 90, 60}, + {3, 0, 0, 0, 0, 0} + }, + { + // Vulpix + true, + MediumFast, + M3F1, + 70, + {FlashFire, NoAbility}, + {38, 41, 40, 50, 65, 65}, + {0, 0, 0, 0, 0, 1} + }, + { + // Ninetails + true, + MediumFast, + M3F1, + 70, + {FlashFire, NoAbility}, + {73, 76, 75, 81, 100, 100}, + {0, 0, 0, 0, 1, 1} + }, + { + // Jigglypuff + true, + Fast, + M3F1, + 70, + {CuteCharm, NoAbility}, + {115, 45, 20, 45, 25, 20}, + {2, 0, 0, 0, 0, 0} + }, + { + // Wigglytuff + true, + Fast, + M3F1, + 70, + {CuteCharm, NoAbility}, + {140, 70, 45, 75, 50, 45}, + {3, 0, 0, 0, 0, 0} + }, + { + // Zubat + true, + MediumFast, + M1F1, + 70, + {InnerFocus, NoAbility}, + {40, 45, 35, 30, 40, 55}, + {0, 0, 0, 0, 0, 1} + }, + { + // Golbat + true, + MediumFast, + M1F1, + 70, + {InnerFocus, NoAbility}, + {75, 80, 70, 65, 75, 90}, + {0, 0, 0, 0, 0, 2} + }, + { + // Oddish + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {45, 50, 55, 75, 65, 30}, + {0, 0, 0, 1, 0, 0} + }, + { + // Gloom + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {60, 65, 70, 85, 75, 40}, + {0, 0, 0, 2, 0, 0} + }, + { + // Vileplume + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {75, 80, 85, 100, 90, 50}, + {0, 0, 0, 3, 0, 0} + }, + { + // Paras + true, + MediumFast, + M1F1, + 70, + {EffectSpore, NoAbility}, + {35, 70, 55, 45, 55, 25}, + {0, 1, 0, 0, 0, 0} + }, + { + // Parasect + true, + MediumFast, + M1F1, + 70, + {EffectSpore, NoAbility}, + {60, 95, 80, 60, 80, 30}, + {0, 2, 1, 0, 0, 0} + }, + { + // Venonat + true, + MediumFast, + M1F1, + 70, + {Compoundeyes, NoAbility}, + {60, 55, 50, 40, 55, 45}, + {0, 0, 0, 0, 1, 0} + }, + { + // Venomoth + true, + MediumFast, + M1F1, + 70, + {ShieldDust, NoAbility}, + {70, 65, 60, 90, 75, 90}, + {0, 0, 0, 1, 0, 1} + }, + { + // Diglett + true, + MediumFast, + M1F1, + 70, + {SandVeil, ArenaTrap}, + {10, 55, 25, 35, 45, 95}, + {0, 0, 0, 0, 0, 1} + }, + { + // Dugtrio + true, + MediumFast, + M1F1, + 70, + {SandVeil, ArenaTrap}, + {35, 80, 50, 50, 70, 120}, + {0, 0, 0, 0, 0, 2} + }, + { + // Meowth + true, + MediumFast, + M1F1, + 70, + {Pickup, NoAbility}, + {40, 45, 35, 40, 40, 90}, + {0, 0, 0, 0, 0, 1} + }, + { + // Persian + true, + MediumFast, + M1F1, + 70, + {Limber, NoAbility}, + {65, 70, 60, 65, 65, 115}, + {0, 0, 0, 0, 0, 2} + }, + { + // Psyduck + true, + MediumFast, + M1F1, + 70, + {Damp, CloudNine}, + {50, 52, 48, 65, 50, 55}, + {0, 0, 0, 1, 0, 0} + }, + { + // Golduck + true, + MediumFast, + M1F1, + 70, + {Damp, CloudNine}, + {80, 82, 78, 95, 80, 85}, + {0, 0, 0, 2, 0, 0} + }, + { + // Mankey + true, + MediumFast, + M1F1, + 70, + {VitalSpirit, NoAbility}, + {40, 80, 35, 35, 45, 70}, + {0, 1, 0, 0, 0, 0} + }, + { + // Primeape + true, + MediumFast, + M1F1, + 70, + {VitalSpirit, NoAbility}, + {65, 105, 60, 60, 70, 95}, + {0, 2, 0, 0, 0, 0} + }, + { + // Growlithe + true, + Slow, + M1F3, + 70, + {Intimidate, FlashFire}, + {55, 70, 45, 70, 50, 60}, + {0, 1, 0, 0, 0, 0} + }, + { + // Arcanine + true, + Slow, + M1F3, + 70, + {Intimidate, FlashFire}, + {90, 110, 80, 100, 80, 95}, + {0, 2, 0, 0, 0, 0} + }, + { + // Poliwag + true, + MediumSlow, + M1F1, + 70, + {WaterAbsorb, Damp}, + {40, 50, 40, 40, 40, 90}, + {0, 0, 0, 0, 0, 1} + }, + { + // Poliwhirl + true, + MediumSlow, + M1F1, + 70, + {WaterAbsorb, Damp}, + {65, 65, 65, 50, 50, 90}, + {0, 0, 0, 0, 0, 2} + }, + { + // Poliwrath + true, + MediumSlow, + M1F1, + 70, + {WaterAbsorb, Damp}, + {90, 85, 95, 70, 90, 70}, + {0, 0, 3, 0, 0, 0} + }, + { + // Abra + true, + MediumSlow, + M1F3, + 70, + {Synchronize, InnerFocus}, + {25, 20, 15, 105, 55, 90}, + {0, 0, 0, 1, 0, 0} + }, + { + // Kadabra + true, + MediumSlow, + M1F3, + 70, + {Synchronize, InnerFocus}, + {40, 35, 30, 120, 70, 105}, + {0, 0, 0, 2, 0, 0} + }, + { + // Alakazam + true, + MediumSlow, + M1F3, + 70, + {Synchronize, InnerFocus}, + {55, 50, 45, 135, 85, 120}, + {0, 0, 0, 3, 0, 0} + }, + { + // Machop + true, + MediumSlow, + M1F3, + 70, + {Guts, NoAbility}, + {70, 80, 50, 35, 35, 35}, + {0, 1, 0, 0, 0, 0} + }, + { + // Machoke + true, + MediumSlow, + M1F3, + 70, + {Guts, NoAbility}, + {80, 100, 70, 50, 60, 45}, + {0, 2, 0, 0, 0, 0} + }, + { + // Machamp + true, + MediumSlow, + M1F3, + 70, + {Guts, NoAbility}, + {90, 130, 80, 65, 85, 55}, + {0, 3, 0, 0, 0, 0} + }, + { + // Bellsprout + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {50, 75, 35, 70, 30, 40}, + {0, 1, 0, 0, 0, 0} + }, + { + // Weepinbell + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {65, 90, 50, 85, 45, 55}, + {0, 2, 0, 0, 0, 0} + }, + { + // Victreebell + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {80, 105, 65, 100, 60, 70}, + {0, 3, 0, 0, 0, 0} + }, + { + // Tentacool + true, + Slow, + M1F1, + 70, + {ClearBody, LiquidOoze}, + {40, 40, 35, 50, 100, 70}, + {0, 0, 0, 0, 1, 0} + }, + { + // Tentacruel + true, + Slow, + M1F1, + 70, + {ClearBody, LiquidOoze}, + {80, 70, 65, 80, 120, 100}, + {0, 0, 0, 0, 2, 0} + }, + { + // Geodude + true, + MediumSlow, + M1F1, + 70, + {RockHead, Sturdy}, + {40, 80, 100, 30, 30, 20}, + {0, 0, 1, 0, 0, 0} + }, + { + // Graveler + true, + MediumSlow, + M1F1, + 70, + {RockHead, Sturdy}, + {55, 95, 115, 45, 45, 35}, + {0, 0, 2, 0, 0, 0} + }, + { + // Golem + true, + MediumSlow, + M1F1, + 70, + {RockHead, Sturdy}, + {80, 110, 130, 55, 65, 45}, + {0, 0, 3, 0, 0, 0} + }, + { + // Ponyta + true, + MediumFast, + M1F1, + 70, + {RunAway, FlashFire}, + {50, 85, 55, 65, 65, 90}, + {0, 0, 0, 0, 0, 1} + }, + { + // Rapidash + true, + MediumFast, + M1F1, + 70, + {RunAway, FlashFire}, + {65, 100, 70, 80, 80, 105}, + {0, 0, 0, 0, 0, 2} + }, + { + // Slowpoke + true, + MediumFast, + M1F1, + 70, + {Oblivious, OwnTempo}, + {90, 65, 65, 40, 40, 15}, + {1, 0, 0, 0, 0, 0} + }, + { + // Slowbro + true, + MediumFast, + M1F1, + 70, + {Oblivious, OwnTempo}, + {95, 75, 110, 100, 80, 30}, + {0, 0, 2, 0, 0, 0} + }, + { + // Magnemite + true, + MediumFast, + GenderlessOnly, + 70, + {MagnetPull, Sturdy}, + {25, 35, 70, 95, 55, 45}, + {0, 0, 0, 1, 0, 0} + }, + { + // Magneton + true, + MediumFast, + GenderlessOnly, + 70, + {MagnetPull, Sturdy}, + {50, 60, 95, 120, 70, 70}, + {0, 0, 0, 2, 0, 0} + }, + { + // Farfetch'd + true, + MediumFast, + M1F1, + 70, + {KeenEye, InnerFocus}, + {52, 65, 55, 58, 62, 60}, + {0, 1, 0, 0, 0, 0} + }, + { + // Doduo + true, + MediumFast, + M1F1, + 70, + {RunAway, EarlyBird}, + {35, 85, 45, 35, 35, 75}, + {0, 1, 0, 0, 0, 0} + }, + { + // Dodrio + true, + MediumFast, + M1F1, + 70, + {RunAway, EarlyBird}, + {60, 110, 70, 60, 60, 100}, + {0, 2, 0, 0, 0, 0} + }, + { + // Seel + true, + MediumFast, + M1F1, + 70, + {ThickFat, NoAbility}, + {65, 45, 55, 45, 70, 45}, + {0, 0, 0, 0, 1, 0} + }, + { + // Dewgong + true, + MediumFast, + M1F1, + 70, + {ThickFat, NoAbility}, + {90, 70, 80, 70, 95, 70}, + {0, 0, 0, 0, 2, 0} + }, + { + // Grimer + true, + MediumFast, + M1F1, + 70, + {Stench, StickyHold}, + {80, 80, 50, 40, 50, 25}, + {1, 0, 0, 0, 0, 0} + }, + { + // Muk + true, + MediumFast, + M1F1, + 70, + {Stench, StickyHold}, + {105, 105, 75, 65, 100, 50}, + {1, 1, 0, 0, 0, 0} + }, + { + // Shellder + true, + Slow, + M1F1, + 70, + {ShellArmor, NoAbility}, + {30, 65, 100, 45, 25, 40}, + {0, 0, 1, 0, 0, 0} + }, + { + // Cloyster + true, + Slow, + M1F1, + 70, + {ShellArmor, NoAbility}, + {50, 95, 180, 85, 45, 70}, + {0, 0, 2, 0, 0, 0} + }, + { + // Gastly + true, + MediumSlow, + M1F1, + 70, + {Levitate, NoAbility}, + {30, 35, 30, 100, 35, 80}, + {0, 0, 0, 1, 0, 0} + }, + { + // Haunter + true, + MediumSlow, + M1F1, + 70, + {Levitate, NoAbility}, + {45, 50, 45, 115, 55, 95}, + {0, 0, 0, 2, 0, 0} + }, + { + // Gengar + true, + MediumSlow, + M1F1, + 70, + {Levitate, NoAbility}, + {60, 65, 60, 130, 75, 110}, + {0, 0, 0, 3, 0, 0} + }, + { + // Onix + true, + MediumFast, + M1F1, + 70, + {RockHead, Sturdy}, + {35, 45, 160, 30, 45, 70}, + {0, 0, 1, 0, 0, 0} + }, + { + // Drowzee + true, + MediumFast, + M1F1, + 70, + {Insomnia, NoAbility}, + {60, 48, 45, 43, 90, 42}, + {0, 0, 0, 0, 1, 0} + }, + { + // Hypno + true, + MediumFast, + M1F1, + 70, + {Insomnia, NoAbility}, + {85, 73, 70, 73, 115, 67}, + {0, 0, 0, 0, 2, 0} + }, + { + // Krabby + true, + MediumFast, + M1F1, + 70, + {HyperCutter, ShellArmor}, + {30, 105, 90, 25, 25, 50}, + {0, 1, 0, 0, 0, 0} + }, + { + // Kingler + true, + MediumFast, + M1F1, + 70, + {HyperCutter, ShellArmor}, + {55, 130, 115, 50, 50, 75}, + {0, 2, 0, 0, 0, 0} + }, + { + // Voltorb + true, + MediumFast, + GenderlessOnly, + 70, + {Soundproof, Static}, + {40, 30, 50, 55, 55, 100}, + {0, 0, 0, 0, 0, 1} + }, + { + // Electrode + true, + MediumFast, + GenderlessOnly, + 70, + {Soundproof, Static}, + {60, 50, 70, 80, 80, 140}, + {0, 0, 0, 0, 0, 2} + }, + { + // Exeggcute + true, + Slow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {60, 40, 80, 60, 45, 40}, + {0, 0, 1, 0, 0, 0} + }, + { + // Exeggcutor + true, + Slow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {95, 95, 85, 125, 65, 55}, + {0, 0, 0, 2, 0, 0} + }, + { + // Cubone + true, + MediumFast, + M1F1, + 70, + {RockHead, Lightningrod}, + {50, 50, 95, 40, 50, 35}, + {0, 0, 1, 0, 0, 0} + }, + { + // Marowak + true, + MediumFast, + M1F1, + 70, + {RockHead, Lightningrod}, + {60, 80, 110, 50, 80, 45}, + {0, 0, 2, 0, 0, 0} + }, + { + // Hitmonlee + true, + MediumFast, + MaleOnly, + 70, + {Limber, NoAbility}, + {50, 120, 53, 35, 110, 87}, + {0, 2, 0, 0, 0, 0} + }, + { + // Hitmonchan + true, + MediumFast, + MaleOnly, + 70, + {KeenEye, NoAbility}, + {50, 105, 79, 35, 110, 76}, + {0, 0, 0, 0, 2, 0} + }, + { + // Lickitung + true, + MediumFast, + M1F1, + 70, + {OwnTempo, Oblivious}, + {90, 55, 75, 60, 75, 30}, + {2, 0, 0, 0, 0, 0} + }, + { + // Koffing + true, + MediumFast, + M1F1, + 70, + {Levitate, NoAbility}, + {40, 65, 95, 60, 45, 35}, + {0, 0, 1, 0, 0, 0} + }, + { + // Weezing + true, + MediumFast, + M1F1, + 70, + {Levitate, NoAbility}, + {65, 90, 120, 85, 70, 60}, + {0, 0, 2, 0, 0, 0} + }, + { + // Rhyhorn + true, + Slow, + M1F1, + 70, + {Lightningrod, RockHead}, + {80, 85, 95, 30, 30, 25}, + {0, 0, 1, 0, 0, 0} + }, + { + // Rhydon + true, + Slow, + M1F1, + 70, + {Lightningrod, RockHead}, + {105, 130, 120, 45, 45, 40}, + {0, 2, 0, 0, 0, 0} + }, + { + // Chansey + true, + Fast, + FemaleOnly, + 140, + {NaturalCure, SereneGrace}, + {250, 5, 5, 35, 105, 50}, + {2, 0, 0, 0, 0, 0} + }, + { + // Tangela + true, + MediumFast, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {65, 55, 115, 100, 40, 60}, + {0, 0, 1, 0, 0, 0} + }, + { + // Kangaskhan + true, + MediumFast, + FemaleOnly, + 70, + {EarlyBird, NoAbility}, + {105, 95, 80, 40, 80, 90}, + {2, 0, 0, 0, 0, 0} + }, + { + // Horsea + true, + MediumFast, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {30, 40, 70, 70, 25, 60}, + {0, 0, 0, 1, 0, 0} + }, + { + // Seadra + true, + MediumFast, + M1F1, + 70, + {PoisonPoint, NoAbility}, + {55, 65, 95, 95, 45, 85}, + {0, 0, 1, 1, 0, 0} + }, + { + // Goldeen + true, + MediumFast, + M1F1, + 70, + {SwiftSwim, WaterVeil}, + {45, 67, 60, 35, 50, 63}, + {0, 1, 0, 0, 0, 0} + }, + { + // Seaking + true, + MediumFast, + M1F1, + 70, + {SwiftSwim, WaterVeil}, + {80, 92, 65, 65, 80, 68}, + {0, 2, 0, 0, 0, 0} + }, + { + // Staryu + true, + Slow, + GenderlessOnly, + 70, + {Illuminate, NaturalCure}, + {30, 45, 55, 70, 55, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Starmie + true, + Slow, + GenderlessOnly, + 70, + {Illuminate, NaturalCure}, + {60, 75, 85, 100, 85, 115}, + {0, 0, 0, 0, 0, 2} + }, + { + // Mr.Mime + true, + MediumFast, + M1F1, + 70, + {Soundproof, NoAbility}, + {40, 45, 65, 100, 120, 90}, + {0, 0, 0, 0, 2, 0} + }, + { + // Scyther + true, + MediumFast, + M1F1, + 70, + {Swarm, NoAbility}, + {70, 110, 80, 55, 80, 105}, + {0, 1, 0, 0, 0, 0} + }, + { + // Jynx + true, + MediumFast, + FemaleOnly, + 70, + {Oblivious, NoAbility}, + {65, 50, 35, 115, 95, 95}, + {0, 0, 0, 2, 0, 0} + }, + { + // Electabuzz + true, + MediumFast, + M1F3, + 70, + {Static, NoAbility}, + {65, 83, 57, 95, 85, 105}, + {0, 0, 0, 0, 0, 2} + }, + { + // Magmar + true, + MediumFast, + M1F3, + 70, + {FlameBody, NoAbility}, + {65, 95, 57, 100, 85, 93}, + {0, 0, 0, 2, 0, 0} + }, + { + // Pinsir + true, + Slow, + M1F1, + 70, + {HyperCutter, NoAbility}, + {65, 125, 100, 55, 70, 85}, + {0, 2, 0, 0, 0, 0} + }, + { + // Tauros + true, + Slow, + MaleOnly, + 70, + {Intimidate, NoAbility}, + {75, 100, 95, 40, 70, 110}, + {0, 1, 0, 0, 0, 1} + }, + { + // Magikarp + true, + Slow, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {20, 10, 55, 15, 20, 80}, + {0, 0, 0, 0, 0, 1} + }, + { + // Gyarados + true, + Slow, + M1F1, + 70, + {Intimidate, NoAbility}, + {95, 125, 79, 60, 100, 81}, + {0, 2, 0, 0, 0, 0} + }, + { + // Lapras + true, + Slow, + M1F1, + 70, + {WaterAbsorb, ShellArmor}, + {130, 85, 80, 85, 95, 60}, + {2, 0, 0, 0, 0, 0} + }, + { + // Ditto + true, + MediumFast, + GenderlessOnly, + 70, + {Limber, NoAbility}, + {48, 48, 48, 48, 48, 48}, + {1, 0, 0, 0, 0, 0} + }, + { + // Eevee + true, + MediumFast, + M7F1, + 70, + {RunAway, NoAbility}, + {55, 55, 50, 45, 65, 55}, + {0, 0, 0, 0, 1, 0} + }, + { + // Vaporeon + true, + MediumFast, + M7F1, + 70, + {WaterAbsorb, NoAbility}, + {130, 65, 60, 110, 95, 65}, + {2, 0, 0, 0, 0, 0} + }, + { + // Jolteon + true, + MediumFast, + M7F1, + 70, + {VoltAbsorb, NoAbility}, + {65, 65, 60, 110, 95, 130}, + {0, 0, 0, 0, 0, 2} + }, + { + // Flareon + true, + MediumFast, + M7F1, + 70, + {FlashFire, NoAbility}, + {65, 130, 60, 95, 110, 65}, + {0, 2, 0, 0, 0, 0} + }, + { + // Porygon + true, + MediumFast, + GenderlessOnly, + 70, + {Trace, NoAbility}, + {65, 60, 70, 85, 75, 40}, + {0, 0, 0, 1, 0, 0} + }, + { + // Omanyte + true, + MediumFast, + M7F1, + 70, + {SwiftSwim, ShellArmor}, + {35, 40, 100, 90, 55, 35}, + {0, 0, 1, 0, 0, 0} + }, + { + // Omastar + true, + MediumFast, + M7F1, + 70, + {SwiftSwim, ShellArmor}, + {70, 60, 125, 115, 70, 55}, + {0, 0, 2, 0, 0, 0} + }, + { + // Kabuto + true, + MediumFast, + M7F1, + 70, + {SwiftSwim, BattleArmor}, + {30, 80, 90, 55, 45, 55}, + {0, 0, 1, 0, 0, 0} + }, + { + // Kabutops + true, + MediumFast, + M7F1, + 70, + {SwiftSwim, BattleArmor}, + {60, 115, 105, 65, 70, 80}, + {0, 2, 0, 0, 0, 0} + }, + { + // Aerodactyl + true, + Slow, + M7F1, + 70, + {RockHead, Pressure}, + {80, 105, 65, 60, 75, 130}, + {0, 0, 0, 0, 0, 2} + }, + { + // Snorlax + true, + Slow, + M7F1, + 70, + {Immunity, ThickFat}, + {160, 110, 65, 65, 110, 30}, + {2, 0, 0, 0, 0, 0} + }, + { + // Articunno + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {90, 85, 100, 95, 125, 85}, + {0, 0, 0, 0, 3, 0} + }, + { + // Zapdos + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {90, 90, 85, 125, 90, 100}, + {0, 0, 0, 3, 0, 0} + }, + { + // Moltres + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {90, 100, 90, 125, 85, 90}, + {0, 0, 0, 3, 0, 0} + }, + { + // Dratini + true, + Slow, + M1F1, + 35, + {ShedSkin, NoAbility}, + {41, 64, 45, 50, 50, 50}, + {0, 1, 0, 0, 0, 0} + }, + { + // Dragonair + true, + Slow, + M1F1, + 35, + {ShedSkin, NoAbility}, + {61, 84, 65, 70, 70, 70}, + {0, 2, 0, 0, 0, 0} + }, + { + // Dragonite + true, + Slow, + M1F1, + 35, + {InnerFocus, NoAbility}, + {91, 134, 95, 100, 100, 80}, + {0, 3, 0, 0, 0, 0} + }, + { + // Mewtwo + true, + Slow, + GenderlessOnly, + 0, + {Pressure, NoAbility}, + {106, 110, 90, 154, 90, 130}, + {0, 0, 0, 3, 0, 0} + }, + { + // Mew + true, + MediumSlow, + GenderlessOnly, + 100, + {Synchronize, NoAbility}, + {100, 100, 100, 100, 100, 100}, + {3, 0, 0, 0, 0, 0} + }, + { + // Chikorita + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {45, 49, 65, 49, 65, 45}, + {0, 0, 0, 0, 1, 0} + }, + { + // Bayleef + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {60, 62, 80, 63, 80, 60}, + {0, 0, 1, 0, 1, 0} + }, + { + // Meganium + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {80, 82, 100, 83, 100, 80}, + {0, 0, 1, 0, 2, 0} + }, + { + // Cyndaquil + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {39, 52, 43, 60, 50, 65}, + {0, 0, 0, 0, 0, 1} + }, + { + // Quilava + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {58, 64, 58, 80, 65, 80}, + {0, 0, 0, 1, 0, 1} + }, + { + // Typhlosion + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {78, 84, 78, 109, 85, 100}, + {0, 0, 0, 3, 0, 0} + }, + { + // Totodile + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {50, 65, 64, 44, 48, 43}, + {0, 1, 0, 0, 0, 0} + }, + { + // Croconaw + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {65, 80, 80, 59, 63, 58}, + {0, 1, 1, 0, 0, 0} + }, + { + // Feraligatr + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {85, 105, 100, 79, 83, 78}, + {0, 2, 1, 0, 0, 0} + }, + { + // Sentret + true, + MediumFast, + M1F1, + 70, + {RunAway, KeenEye}, + {35, 46, 34, 35, 45, 20}, + {0, 1, 0, 0, 0, 0} + }, + { + // Furret + true, + MediumFast, + M1F1, + 70, + {RunAway, KeenEye}, + {85, 76, 64, 45, 55, 90}, + {0, 0, 0, 0, 0, 2} + }, + { + // Hoothoot + true, + MediumFast, + M1F1, + 70, + {Insomnia, KeenEye}, + {60, 30, 30, 36, 56, 50}, + {1, 0, 0, 0, 0, 0} + }, + { + // Noctowl + true, + MediumFast, + M1F1, + 70, + {Insomnia, KeenEye}, + {100, 50, 50, 76, 96, 70}, + {2, 0, 0, 0, 0, 0} + }, + { + // Ledyba + true, + Fast, + M1F1, + 70, + {Swarm, EarlyBird}, + {40, 20, 30, 40, 80, 55}, + {0, 0, 0, 0, 1, 0} + }, + { + // Ledian + true, + Fast, + M1F1, + 70, + {Swarm, EarlyBird}, + {55, 35, 50, 55, 110, 85}, + {0, 0, 0, 0, 2, 0} + }, + { + // Spinarak + true, + Fast, + M1F1, + 70, + {Swarm, Insomnia}, + {40, 60, 40, 40, 40, 30}, + {0, 1, 0, 0, 0, 0} + }, + { + // Ariados + true, + Fast, + M1F1, + 70, + {Swarm, Insomnia}, + {70, 90, 70, 60, 60, 40}, + {0, 2, 0, 0, 0, 0} + }, + { + // Crobat + true, + MediumFast, + M1F1, + 70, + {InnerFocus, NoAbility}, + {85, 90, 80, 70, 80, 130}, + {0, 0, 0, 0, 0, 3} + }, + { + // Chinchou + true, + Slow, + M1F1, + 70, + {VoltAbsorb, Illuminate}, + {75, 38, 38, 56, 56, 67}, + {1, 0, 0, 0, 0, 0} + }, + { + // Lanturn + true, + Slow, + M1F1, + 70, + {VoltAbsorb, Illuminate}, + {125, 58, 58, 76, 76, 67}, + {2, 0, 0, 0, 0, 0} + }, + { + // Pichu + true, + MediumFast, + M1F1, + 70, + {Static, NoAbility}, + {20, 40, 15, 35, 35, 60}, + {0, 0, 0, 0, 0, 1} + }, + { + // Cleffa + true, + Fast, + M3F1, + 140, + {CuteCharm, NoAbility}, + {50, 25, 28, 45, 55, 15}, + {0, 0, 0, 0, 1, 0} + }, + { + // Igglybuff + true, + Fast, + M3F1, + 70, + {CuteCharm, NoAbility}, + {90, 30, 15, 40, 20, 15}, + {1, 0, 0, 0, 0, 0} + }, + { + // Togepi + true, + Fast, + M7F1, + 70, + {Hustle, SereneGrace}, + {35, 20, 65, 40, 65, 20}, + {0, 0, 0, 0, 1, 0} + }, + { + // Togetic + true, + Fast, + M7F1, + 70, + {Hustle, SereneGrace}, + {55, 40, 85, 80, 105, 40}, + {0, 0, 0, 0, 2, 0} + }, + { + // Natu + true, + MediumFast, + M1F1, + 70, + {Synchronize, EarlyBird}, + {40, 50, 45, 70, 45, 70}, + {0, 0, 0, 1, 0, 0} + }, + { + // Xatu + true, + MediumFast, + M1F1, + 70, + {Synchronize, EarlyBird}, + {65, 75, 70, 95, 70, 95}, + {0, 0, 0, 1, 0, 1} + }, + { + // Mareep + true, + MediumSlow, + M1F1, + 70, + {Static, NoAbility}, + {55, 40, 40, 65, 45, 35}, + {0, 0, 0, 1, 0, 0} + }, + { + // Flaaffy + true, + MediumSlow, + M1F1, + 70, + {Static, NoAbility}, + {70, 55, 55, 80, 60, 45}, + {0, 0, 0, 2, 0, 0} + }, + { + // Ampharos + true, + MediumSlow, + M1F1, + 70, + {Static, NoAbility}, + {90, 75, 75, 115, 90, 55}, + {0, 0, 0, 3, 0, 0} + }, + { + // Bellossom + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {75, 80, 85, 90, 100, 50}, + {0, 0, 0, 0, 3, 0} + }, + { + // Marill + true, + Fast, + M1F1, + 70, + {ThickFat, HugePower}, + {70, 20, 50, 20, 50, 40}, + {2, 0, 0, 0, 0, 0} + }, + { + // Azumarill + true, + Fast, + M1F1, + 70, + {ThickFat, HugePower}, + {100, 50, 80, 50, 80, 50}, + {3, 0, 0, 0, 0, 0} + }, + { + // Sudowoodo + true, + MediumFast, + M1F1, + 70, + {Sturdy, RockHead}, + {70, 100, 115, 30, 65, 30}, + {0, 0, 2, 0, 0, 0} + }, + { + // Politoed + true, + MediumSlow, + M1F1, + 70, + {WaterAbsorb, Damp}, + {90, 75, 75, 90, 100, 70}, + {0, 0, 0, 0, 3, 0} + }, + { + // Hoppip + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {35, 35, 40, 35, 55, 50}, + {0, 0, 0, 0, 1, 0} + }, + { + // Skiploom + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {55, 45, 50, 45, 65, 80}, + {0, 0, 0, 0, 0, 2} + }, + { + // Jumpluff + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {75, 55, 70, 55, 85, 110}, + {0, 0, 0, 0, 0, 3} + }, + { + // Aipom + true, + Fast, + M1F1, + 70, + {RunAway, Pickup}, + {55, 70, 55, 40, 55, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Sunkern + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {30, 30, 30, 30, 30, 30}, + {0, 0, 0, 1, 0, 0} + }, + { + // Sunflora + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {75, 75, 55, 105, 85, 30}, + {0, 0, 0, 2, 0, 0} + }, + { + // Yanma + true, + MediumFast, + M1F1, + 70, + {SpeedBoost, Compoundeyes}, + {65, 65, 45, 75, 45, 95}, + {0, 0, 0, 0, 0, 2} + }, + { + // Wooper + true, + MediumFast, + M1F1, + 70, + {Damp, WaterAbsorb}, + {55, 45, 45, 25, 25, 15}, + {1, 0, 0, 0, 0, 0} + }, + { + // Quagsire + true, + MediumFast, + M1F1, + 70, + {Damp, WaterAbsorb}, + {95, 85, 85, 65, 65, 35}, + {2, 0, 0, 0, 0, 0} + }, + { + // Espeon + true, + MediumFast, + M7F1, + 70, + {Synchronize, NoAbility}, + {65, 65, 60, 130, 95, 110}, + {0, 0, 0, 2, 0, 0} + }, + { + // Umbreon + true, + MediumFast, + M7F1, + 35, + {Synchronize, NoAbility}, + {95, 65, 110, 60, 130, 65}, + {0, 0, 0, 0, 2, 0} + }, + { + // Murkrow + true, + MediumSlow, + M1F1, + 35, + {Insomnia, NoAbility}, + {60, 85, 42, 85, 42, 91}, + {0, 0, 0, 0, 0, 1} + }, + { + // Slowking + true, + MediumFast, + M1F1, + 70, + {Oblivious, OwnTempo}, + {95, 75, 80, 100, 110, 30}, + {0, 0, 0, 0, 3, 0} + }, + { + // Misdreavus + true, + Fast, + M1F1, + 35, + {Levitate, NoAbility}, + {60, 60, 60, 85, 85, 85}, + {0, 0, 0, 1, 1, 0} + }, + { + // Unown + true, + MediumFast, + GenderlessOnly, + 70, + {Levitate, NoAbility}, + {48, 72, 48, 72, 48, 48}, + {0, 1, 0, 1, 0, 0} + }, + { + // Wobbuffet + true, + MediumFast, + M1F1, + 70, + {ShadowTag, NoAbility}, + {190, 33, 58, 33, 58, 33}, + {2, 0, 0, 0, 0, 0} + }, + { + // Girafarig + true, + MediumFast, + M1F1, + 70, + {InnerFocus, EarlyBird}, + {70, 80, 65, 90, 65, 85}, + {0, 0, 0, 2, 0, 0} + }, + { + // Pineco + true, + MediumFast, + M1F1, + 70, + {Sturdy, NoAbility}, + {50, 65, 90, 35, 35, 15}, + {0, 0, 1, 0, 0, 0} + }, + { + // Forretress + true, + MediumFast, + M1F1, + 70, + {Sturdy, NoAbility}, + {75, 90, 140, 60, 60, 40}, + {0, 0, 2, 0, 0, 0} + }, + { + // Dunsparce + true, + MediumFast, + M1F1, + 70, + {SereneGrace, RunAway}, + {100, 70, 70, 65, 65, 45}, + {1, 0, 0, 0, 0, 0} + }, + { + // Gligar + true, + MediumSlow, + M1F1, + 70, + {HyperCutter, SandVeil}, + {65, 75, 105, 35, 65, 85}, + {0, 0, 1, 0, 0, 0} + }, + { + // Steelix + true, + MediumFast, + M1F1, + 70, + {RockHead, Sturdy}, + {75, 85, 200, 55, 65, 30}, + {0, 0, 2, 0, 0, 0} + }, + { + // Snubbull + true, + Fast, + M3F1, + 70, + {Intimidate, RunAway}, + {60, 80, 50, 40, 40, 30}, + {0, 1, 0, 0, 0, 0} + }, + { + // Granbull + true, + Fast, + M3F1, + 70, + {Intimidate, Intimidate}, + {90, 120, 75, 60, 60, 45}, + {0, 2, 0, 0, 0, 0} + }, + { + // Qwilfish + true, + MediumFast, + M1F1, + 70, + {PoisonPoint, SwiftSwim}, + {65, 95, 75, 55, 55, 85}, + {0, 1, 0, 0, 0, 0} + }, + { + // Scizor + true, + MediumFast, + M1F1, + 70, + {Swarm, NoAbility}, + {70, 130, 100, 55, 80, 65}, + {0, 2, 0, 0, 0, 0} + }, + { + // Shuckle + true, + MediumSlow, + M1F1, + 70, + {Sturdy, NoAbility}, + {20, 10, 230, 10, 230, 5}, + {0, 0, 1, 0, 1, 0} + }, + { + // Heracross + true, + Slow, + M1F1, + 70, + {Swarm, Guts}, + {80, 125, 75, 40, 95, 85}, + {0, 2, 0, 0, 0, 0} + }, + { + // Sneasel + true, + MediumSlow, + M1F1, + 35, + {InnerFocus, KeenEye}, + {55, 95, 55, 35, 75, 115}, + {0, 0, 0, 0, 0, 1} + }, + { + // Teddiursa + true, + MediumFast, + M1F1, + 70, + {Pickup, NoAbility}, + {60, 80, 50, 50, 50, 40}, + {0, 1, 0, 0, 0, 0} + }, + { + // Ursaring + true, + MediumFast, + M1F1, + 70, + {Guts, NoAbility}, + {90, 130, 75, 75, 75, 55}, + {0, 2, 0, 0, 0, 0} + }, + { + // Slugma + true, + MediumFast, + M1F1, + 70, + {MagmaArmor, FlameBody}, + {40, 40, 40, 70, 40, 20}, + {0, 0, 0, 1, 0, 0} + }, + { + // Magcargo + true, + MediumFast, + M1F1, + 70, + {MagmaArmor, FlameBody}, + {50, 50, 120, 80, 80, 30}, + {0, 0, 2, 0, 0, 0} + }, + { + // Swinub + true, + Slow, + M1F1, + 70, + {Oblivious, NoAbility}, + {50, 50, 40, 30, 30, 50}, + {0, 1, 0, 0, 0, 0} + }, + { + // Piloswine + true, + Slow, + M1F1, + 70, + {Oblivious, NoAbility}, + {100, 100, 80, 60, 60, 50}, + {1, 1, 0, 0, 0, 0} + }, + { + // Corsola + true, + Fast, + M3F1, + 70, + {Hustle, NaturalCure}, + {55, 55, 85, 65, 85, 35}, + {0, 0, 1, 0, 1, 0} + }, + { + // Remoraid + true, + MediumFast, + M1F1, + 70, + {Hustle, NoAbility}, + {35, 65, 35, 65, 35, 65}, + {0, 0, 0, 1, 0, 0} + }, + { + // Octillery + true, + MediumFast, + M1F1, + 70, + {SuctionCups, NoAbility}, + {75, 105, 75, 105, 75, 45}, + {0, 1, 0, 1, 0, 0} + }, + { + // Delibird + true, + Fast, + M1F1, + 70, + {VitalSpirit, Hustle}, + {45, 55, 45, 65, 45, 75}, + {0, 0, 0, 0, 0, 1} + }, + { + // Mantine + true, + Slow, + M1F1, + 70, + {SwiftSwim, WaterAbsorb}, + {65, 40, 70, 80, 140, 70}, + {0, 0, 0, 0, 2, 0} + }, + { + // Skarmory + true, + Slow, + M1F1, + 70, + {KeenEye, Sturdy}, + {65, 80, 140, 40, 70, 70}, + {0, 0, 2, 0, 0, 0} + }, + { + // Houndour + true, + Slow, + M1F1, + 35, + {EarlyBird, FlashFire}, + {45, 60, 30, 80, 50, 65}, + {0, 0, 0, 1, 0, 0} + }, + { + // Houndoom + true, + Slow, + M1F1, + 35, + {EarlyBird, FlashFire}, + {75, 90, 50, 110, 80, 95}, + {0, 0, 0, 2, 0, 0} + }, + { + // Kingdra + true, + MediumFast, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {75, 95, 95, 95, 95, 85}, + {0, 1, 0, 1, 1, 0} + }, + { + // Phanpy + true, + MediumFast, + M1F1, + 70, + {Pickup, NoAbility}, + {90, 60, 60, 40, 40, 40}, + {1, 0, 0, 0, 0, 0} + }, + { + // Donphan + true, + MediumFast, + M1F1, + 70, + {Sturdy, NoAbility}, + {90, 120, 120, 60, 60, 50}, + {0, 1, 1, 0, 0, 0} + }, + { + // Porygon2 + true, + MediumFast, + GenderlessOnly, + 70, + {Trace, NoAbility}, + {85, 80, 90, 105, 95, 60}, + {0, 0, 0, 2, 0, 0} + }, + { + // Stantler + true, + Slow, + M1F1, + 70, + {Intimidate, NoAbility}, + {73, 95, 62, 85, 65, 85}, + {0, 1, 0, 0, 0, 0} + }, + { + // Smeargle + true, + Fast, + M1F1, + 70, + {OwnTempo, NoAbility}, + {55, 20, 35, 20, 45, 75}, + {0, 0, 0, 0, 0, 1} + }, + { + // Tyrogue + true, + MediumFast, + MaleOnly, + 70, + {Guts, NoAbility}, + {35, 35, 35, 35, 35, 35}, + {0, 1, 0, 0, 0, 0} + }, + { + // Hitmontop + true, + MediumFast, + MaleOnly, + 70, + {Intimidate, NoAbility}, + {50, 95, 95, 35, 110, 70}, + {0, 0, 0, 0, 2, 0} + }, + { + // Smoochum + true, + MediumFast, + FemaleOnly, + 70, + {Oblivious, NoAbility}, + {45, 30, 15, 85, 65, 65}, + {0, 0, 0, 1, 0, 0} + }, + { + // Elekid + true, + MediumFast, + M1F3, + 70, + {Static, NoAbility}, + {45, 63, 37, 65, 55, 95}, + {0, 0, 0, 0, 0, 1} + }, + { + // Magby + true, + MediumFast, + M1F3, + 70, + {FlameBody, NoAbility}, + {45, 75, 37, 70, 55, 83}, + {0, 0, 0, 0, 0, 1} + }, + { + // Miltank + true, + Slow, + FemaleOnly, + 70, + {ThickFat, NoAbility}, + {95, 80, 105, 40, 70, 100}, + {0, 0, 2, 0, 0, 0} + }, + { + // Blissey + true, + Fast, + FemaleOnly, + 140, + {NaturalCure, SereneGrace}, + {255, 10, 10, 75, 135, 55}, + {2, 0, 0, 0, 0, 0} + }, + { + // Raikou + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {90, 85, 75, 115, 100, 115}, + {0, 0, 0, 1, 0, 2} + }, + { + // Entei + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {115, 115, 85, 90, 75, 100}, + {1, 2, 0, 0, 0, 0} + }, + { + // Suicune + true, + Slow, + GenderlessOnly, + 35, + {Pressure, NoAbility}, + {100, 75, 115, 90, 115, 85}, + {0, 0, 1, 0, 2, 0} + }, + { + // Larvitar + true, + Slow, + M1F1, + 35, + {Guts, NoAbility}, + {50, 64, 50, 45, 50, 41}, + {0, 1, 0, 0, 0, 0} + }, + { + // Pupitar + true, + Slow, + M1F1, + 35, + {ShedSkin, NoAbility}, + {70, 84, 70, 65, 70, 51}, + {0, 2, 0, 0, 0, 0} + }, + { + // Tyranitar + true, + Slow, + M1F1, + 35, + {SandStream, NoAbility}, + {100, 134, 110, 95, 100, 61}, + {0, 3, 0, 0, 0, 0} + }, + { + // Lugia + true, + Slow, + GenderlessOnly, + 0, + {Pressure, NoAbility}, + {106, 90, 130, 90, 154, 110}, + {0, 0, 0, 0, 3, 0} + }, + { + // Ho-oh + true, + Slow, + GenderlessOnly, + 0, + {Pressure, NoAbility}, + {106, 130, 90, 110, 154, 90}, + {0, 0, 0, 0, 3, 0} + }, + { + // Celebi + true, + MediumSlow, + GenderlessOnly, + 100, + {NaturalCure, NoAbility}, + {100, 100, 100, 100, 100, 100}, + {3, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + // Treecko + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {40, 45, 35, 65, 55, 70}, + {0, 0, 0, 0, 0, 1} + }, + { + // Grovyle + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {50, 65, 45, 85, 65, 95}, + {0, 0, 0, 0, 0, 2} + }, + { + // Sceptile + true, + MediumSlow, + M7F1, + 70, + {Overgrow, NoAbility}, + {70, 85, 65, 105, 85, 120}, + {0, 0, 0, 0, 0, 3} + }, + { + // Torchic + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {45, 60, 40, 70, 50, 45}, + {0, 0, 0, 1, 0, 0} + }, + { + // Combusken + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {60, 85, 60, 85, 60, 55}, + {0, 1, 0, 1, 0, 0} + }, + { + // Blaziken + true, + MediumSlow, + M7F1, + 70, + {Blaze, NoAbility}, + {80, 120, 70, 110, 70, 80}, + {0, 3, 0, 0, 0, 0} + }, + { + // Mudkip + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {50, 70, 50, 50, 50, 40}, + {0, 1, 0, 0, 0, 0} + }, + { + // Marshtomp + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {70, 85, 70, 60, 70, 50}, + {0, 2, 0, 0, 0, 0} + }, + { + // Swampert + true, + MediumSlow, + M7F1, + 70, + {Torrent, NoAbility}, + {100, 110, 90, 85, 90, 60}, + {0, 3, 0, 0, 0, 0} + }, + { + // Poochyena + true, + MediumFast, + M1F1, + 70, + {RunAway, NoAbility}, + {35, 55, 35, 30, 30, 35}, + {0, 1, 0, 0, 0, 0} + }, + { + // Mightyena + true, + MediumFast, + M1F1, + 70, + {Intimidate, NoAbility}, + {70, 90, 70, 60, 60, 70}, + {0, 2, 0, 0, 0, 0} + }, + { + // Zigzagoon + true, + MediumFast, + M1F1, + 70, + {Pickup, NoAbility}, + {38, 30, 41, 30, 41, 60}, + {0, 0, 0, 0, 0, 1} + }, + { + // Linoone + true, + MediumFast, + M1F1, + 70, + {Pickup, NoAbility}, + {78, 70, 61, 50, 61, 100}, + {0, 0, 0, 0, 0, 2} + }, + { + // Wurmple + true, + MediumFast, + M1F1, + 70, + {ShieldDust, NoAbility}, + {45, 45, 35, 20, 30, 20}, + {1, 0, 0, 0, 0, 0} + }, + { + // Silcoon + true, + MediumFast, + M1F1, + 70, + {ShedSkin, NoAbility}, + {50, 35, 55, 25, 25, 15}, + {0, 0, 2, 0, 0, 0} + }, + { + // Beautifly + true, + MediumFast, + M1F1, + 70, + {Swarm, NoAbility}, + {60, 70, 50, 90, 50, 65}, + {0, 0, 0, 3, 0, 0} + }, + { + // Cascoon + true, + MediumFast, + M1F1, + 70, + {ShedSkin, NoAbility}, + {50, 35, 55, 25, 25, 15}, + {0, 0, 2, 0, 0, 0} + }, + { + // Dustox + true, + MediumFast, + M1F1, + 70, + {ShieldDust, NoAbility}, + {60, 50, 70, 50, 90, 65}, + {0, 0, 0, 0, 3, 0} + }, + { + // Lotad + true, + MediumSlow, + M1F1, + 70, + {SwiftSwim, RainDish}, + {40, 30, 30, 40, 50, 30}, + {0, 0, 0, 0, 1, 0} + }, + { + // Lombre + true, + MediumSlow, + M1F1, + 70, + {SwiftSwim, RainDish}, + {60, 50, 50, 60, 70, 50}, + {0, 0, 0, 0, 2, 0} + }, + { + // Ludicolo + true, + MediumSlow, + M1F1, + 70, + {SwiftSwim, RainDish}, + {80, 70, 70, 90, 100, 70}, + {0, 0, 0, 0, 3, 0} + }, + { + // Seedot + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, EarlyBird}, + {40, 40, 50, 30, 30, 30}, + {0, 0, 1, 0, 0, 0} + }, + { + // Nuzleaf + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, EarlyBird}, + {70, 70, 40, 60, 40, 60}, + {0, 2, 0, 0, 0, 0} + }, + { + // Shiftry + true, + MediumSlow, + M1F1, + 70, + {Chlorophyll, EarlyBird}, + {90, 100, 60, 90, 60, 80}, + {0, 3, 0, 0, 0, 0} + }, + { + // Nincada + true, + Erratic, + M1F1, + 70, + {Compoundeyes, NoAbility}, + {31, 45, 90, 30, 30, 40}, + {0, 0, 1, 0, 0, 0} + }, + { + // Ninjask + true, + Erratic, + M1F1, + 70, + {SpeedBoost, NoAbility}, + {61, 90, 45, 50, 50, 160}, + {0, 0, 0, 0, 0, 2} + }, + { + // Shedinja + true, + Erratic, + GenderlessOnly, + 70, + {WonderGuard, NoAbility}, + {1, 90, 45, 30, 30, 40}, + {2, 0, 0, 0, 0, 0} + }, + { + // Taillow + true, + MediumSlow, + M1F1, + 70, + {Guts, NoAbility}, + {40, 55, 30, 30, 30, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Swellow + true, + MediumSlow, + M1F1, + 70, + {Guts, NoAbility}, + {60, 85, 60, 50, 50, 125}, + {0, 0, 0, 0, 0, 2} + }, + { + // Shroomish + true, + Fluctuating, + M1F1, + 70, + {EffectSpore, NoAbility}, + {60, 40, 60, 40, 60, 35}, + {1, 0, 0, 0, 0, 0} + }, + { + // Breloom + true, + Fluctuating, + M1F1, + 70, + {EffectSpore, NoAbility}, + {60, 130, 80, 60, 60, 70}, + {0, 2, 0, 0, 0, 0} + }, + { + // Spinda + true, + Fast, + M1F1, + 70, + {OwnTempo, NoAbility}, + {60, 60, 60, 60, 60, 60}, + {0, 0, 0, 1, 0, 0} + }, + { + // Wingull + true, + MediumFast, + M1F1, + 70, + {KeenEye, NoAbility}, + {40, 30, 30, 55, 30, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Pelipper + true, + MediumFast, + M1F1, + 70, + {KeenEye, NoAbility}, + {60, 50, 100, 85, 70, 65}, + {0, 0, 2, 0, 0, 0} + }, + { + // Surskit + true, + MediumFast, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {40, 30, 32, 50, 52, 65}, + {0, 0, 0, 0, 0, 1} + }, + { + // Masquerain + true, + MediumFast, + M1F1, + 70, + {Intimidate, NoAbility}, + {70, 60, 62, 80, 82, 60}, + {0, 0, 0, 1, 1, 0} + }, + { + // Wailmer + true, + Fluctuating, + M1F1, + 70, + {WaterVeil, Oblivious}, + {130, 70, 35, 70, 35, 60}, + {1, 0, 0, 0, 0, 0} + }, + { + // Wailord + true, + Fluctuating, + M1F1, + 70, + {WaterVeil, Oblivious}, + {170, 90, 45, 90, 45, 60}, + {2, 0, 0, 0, 0, 0} + }, + { + // Skitty + true, + Fast, + M3F1, + 70, + {CuteCharm, NoAbility}, + {50, 45, 45, 35, 35, 50}, + {0, 0, 0, 0, 0, 1} + }, + { + // Delcatty + true, + Fast, + M3F1, + 70, + {CuteCharm, NoAbility}, + {70, 65, 65, 55, 55, 70}, + {1, 0, 0, 0, 0, 1} + }, + { + // Kecleon + true, + MediumSlow, + M1F1, + 70, + {ColorChange, NoAbility}, + {60, 90, 70, 60, 120, 40}, + {0, 0, 0, 0, 1, 0} + }, + { + // Baltoy + true, + MediumFast, + GenderlessOnly, + 70, + {Levitate, NoAbility}, + {40, 40, 55, 40, 70, 55}, + {0, 0, 0, 0, 1, 0} + }, + { + // Claydol + true, + MediumFast, + GenderlessOnly, + 70, + {Levitate, NoAbility}, + {60, 70, 105, 70, 120, 75}, + {0, 0, 0, 0, 2, 0} + }, + { + // Nosepass + true, + MediumFast, + M1F1, + 70, + {Sturdy, MagnetPull}, + {30, 45, 135, 45, 90, 30}, + {0, 0, 1, 0, 0, 0} + }, + { + // Torkoal + true, + MediumFast, + M1F1, + 70, + {WhiteSmoke, NoAbility}, + {70, 85, 140, 85, 70, 20}, + {0, 0, 2, 0, 0, 0} + }, + { + // Sableye + true, + MediumSlow, + M1F1, + 35, + {KeenEye, NoAbility}, + {50, 75, 75, 65, 65, 50}, + {0, 1, 1, 0, 0, 0} + }, + { + // Barboach + true, + MediumFast, + M1F1, + 70, + {Oblivious, NoAbility}, + {50, 48, 43, 46, 41, 60}, + {1, 0, 0, 0, 0, 0} + }, + { + // Whiscash + true, + MediumFast, + M1F1, + 70, + {Oblivious, NoAbility}, + {110, 78, 73, 76, 71, 60}, + {2, 0, 0, 0, 0, 0} + }, + { + // Luvdisc + true, + Fast, + M3F1, + 70, + {SwiftSwim, NoAbility}, + {43, 30, 55, 40, 65, 97}, + {0, 0, 0, 0, 0, 1} + }, + { + // Corphish + true, + Fluctuating, + M1F1, + 70, + {HyperCutter, ShellArmor}, + {43, 80, 65, 50, 35, 35}, + {0, 1, 0, 0, 0, 0} + }, + { + // Crawdaunt + true, + Fluctuating, + M1F1, + 70, + {HyperCutter, ShellArmor}, + {63, 120, 85, 90, 55, 55}, + {0, 2, 0, 0, 0, 0} + }, + { + // Feebas + true, + Erratic, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {20, 15, 20, 10, 55, 80}, + {0, 0, 0, 0, 0, 1} + }, + { + // Milotic + true, + Erratic, + M1F1, + 70, + {MarvelScale, NoAbility}, + {95, 60, 79, 100, 125, 81}, + {0, 0, 0, 0, 2, 0} + }, + { + // Carvanha + true, + Slow, + M1F1, + 35, + {RoughSkin, NoAbility}, + {45, 90, 20, 65, 20, 65}, + {0, 1, 0, 0, 0, 0} + }, + { + // Sharpedo + true, + Slow, + M1F1, + 35, + {RoughSkin, NoAbility}, + {70, 120, 40, 95, 40, 95}, + {0, 2, 0, 0, 0, 0} + }, + { + // Trapinch + true, + MediumSlow, + M1F1, + 70, + {HyperCutter, ArenaTrap}, + {45, 100, 45, 45, 45, 10}, + {0, 1, 0, 0, 0, 0} + }, + { + // Vibrava + true, + MediumSlow, + M1F1, + 70, + {Levitate, Levitate}, + {50, 70, 50, 50, 50, 70}, + {0, 1, 0, 0, 0, 1} + }, + { + // Flygon + true, + MediumSlow, + M1F1, + 70, + {Levitate, Levitate}, + {80, 100, 80, 80, 80, 100}, + {0, 1, 0, 0, 0, 2} + }, + { + // Makuhita + true, + Fluctuating, + M1F3, + 70, + {ThickFat, Guts}, + {72, 60, 30, 20, 30, 25}, + {1, 0, 0, 0, 0, 0} + }, + { + // Hariyama + true, + Fluctuating, + M1F3, + 70, + {ThickFat, Guts}, + {144, 120, 60, 40, 60, 50}, + {2, 0, 0, 0, 0, 0} + }, + { + // Electrike + true, + Slow, + M1F1, + 70, + {Static, Lightningrod}, + {40, 45, 40, 65, 40, 65}, + {0, 0, 0, 0, 0, 1} + }, + { + // Manectric + true, + Slow, + M1F1, + 70, + {Static, Lightningrod}, + {70, 75, 60, 105, 60, 105}, + {0, 0, 0, 0, 0, 2} + }, + { + // Numel + true, + MediumFast, + M1F1, + 70, + {Oblivious, NoAbility}, + {60, 60, 40, 65, 45, 35}, + {0, 0, 0, 1, 0, 0} + }, + { + // Camerupt + true, + MediumFast, + M1F1, + 70, + {MagmaArmor, NoAbility}, + {70, 100, 70, 105, 75, 40}, + {0, 1, 0, 1, 0, 0} + }, + { + // Spheal + true, + MediumSlow, + M1F1, + 70, + {ThickFat, NoAbility}, + {70, 40, 50, 55, 50, 25}, + {1, 0, 0, 0, 0, 0} + }, + { + // Sealeo + true, + MediumSlow, + M1F1, + 70, + {ThickFat, NoAbility}, + {90, 60, 70, 75, 70, 45}, + {2, 0, 0, 0, 0, 0} + }, + { + // Walrein + true, + MediumSlow, + M1F1, + 70, + {ThickFat, NoAbility}, + {110, 80, 90, 95, 90, 65}, + {3, 0, 0, 0, 0, 0} + }, + { + // Cacnea + true, + MediumSlow, + M1F1, + 35, + {SandVeil, NoAbility}, + {50, 85, 40, 85, 40, 35}, + {0, 0, 0, 1, 0, 0} + }, + { + // Cacturne + true, + MediumSlow, + M1F1, + 35, + {SandVeil, NoAbility}, + {70, 115, 60, 115, 60, 55}, + {0, 1, 0, 1, 0, 0} + }, + { + // Snorunt + true, + MediumFast, + M1F1, + 70, + {InnerFocus, NoAbility}, + {50, 50, 50, 50, 50, 50}, + {1, 0, 0, 0, 0, 0} + }, + { + // Glalie + true, + MediumFast, + M1F1, + 70, + {InnerFocus, NoAbility}, + {80, 80, 80, 80, 80, 80}, + {2, 0, 0, 0, 0, 0} + }, + { + // Lunatone + true, + Fast, + GenderlessOnly, + 70, + {Levitate, NoAbility}, + {70, 55, 65, 95, 85, 70}, + {0, 0, 0, 2, 0, 0} + }, + { + // Solrock + true, + Fast, + GenderlessOnly, + 70, + {Levitate, NoAbility}, + {70, 95, 85, 55, 65, 70}, + {0, 2, 0, 0, 0, 0} + }, + { + // Azuril + true, + Fast, + M3F1, + 70, + {ThickFat, HugePower}, + {50, 20, 40, 20, 40, 20}, + {1, 0, 0, 0, 0, 0} + }, + { + // Spoink + true, + Fast, + M1F1, + 70, + {ThickFat, OwnTempo}, + {60, 25, 35, 70, 80, 60}, + {0, 0, 0, 0, 1, 0} + }, + { + // Grumpig + true, + Fast, + M1F1, + 70, + {ThickFat, OwnTempo}, + {80, 45, 65, 90, 110, 80}, + {0, 0, 0, 0, 2, 0} + }, + { + // Plusle + true, + MediumFast, + M1F1, + 70, + {Plus, NoAbility}, + {60, 50, 40, 85, 75, 95}, + {0, 0, 0, 0, 0, 1} + }, + { + // Minun + true, + MediumFast, + M1F1, + 70, + {Minus, NoAbility}, + {60, 40, 50, 75, 85, 95}, + {0, 0, 0, 0, 0, 1} + }, + { + // Mawile + true, + Fast, + M1F1, + 70, + {HyperCutter, Intimidate}, + {50, 85, 85, 55, 55, 50}, + {0, 1, 1, 0, 0, 0} + }, + { + // Meditite + true, + MediumFast, + M1F1, + 70, + {PurePower, NoAbility}, + {30, 40, 55, 40, 55, 60}, + {0, 0, 0, 0, 0, 1} + }, + { + // Medicham + true, + MediumFast, + M1F1, + 70, + {PurePower, NoAbility}, + {60, 60, 75, 60, 75, 80}, + {0, 0, 0, 0, 0, 2} + }, + { + // Swablu + true, + Erratic, + M1F1, + 70, + {NaturalCure, NoAbility}, + {45, 40, 60, 40, 75, 50}, + {0, 0, 0, 0, 1, 0} + }, + { + // Altaria + true, + Erratic, + M1F1, + 70, + {NaturalCure, NoAbility}, + {75, 70, 90, 70, 105, 80}, + {0, 0, 0, 0, 2, 0} + }, + { + // Wynaut + true, + MediumFast, + M1F1, + 70, + {ShadowTag, NoAbility}, + {95, 23, 48, 23, 48, 23}, + {1, 0, 0, 0, 0, 0} + }, + { + // Duskull + true, + Fast, + M1F1, + 35, + {Levitate, NoAbility}, + {20, 40, 90, 30, 90, 25}, + {0, 0, 1, 0, 1, 0} + }, + { + // Dusclops + true, + Fast, + M1F1, + 35, + {Pressure, NoAbility}, + {40, 70, 130, 60, 130, 25}, + {0, 0, 1, 0, 2, 0} + }, + { + // Roselia + true, + MediumSlow, + M1F1, + 70, + {NaturalCure, PoisonPoint}, + {50, 60, 45, 100, 80, 65}, + {0, 0, 0, 1, 0, 0} + }, + { + // Slakoth + true, + Slow, + M1F1, + 70, + {Truant, NoAbility}, + {60, 60, 60, 35, 35, 30}, + {1, 0, 0, 0, 0, 0} + }, + { + // Vigoroth + true, + Slow, + M1F1, + 70, + {VitalSpirit, NoAbility}, + {80, 80, 80, 55, 55, 90}, + {0, 0, 0, 0, 0, 2} + }, + { + // Slaking + true, + Slow, + M1F1, + 70, + {Truant, NoAbility}, + {150, 160, 100, 95, 65, 100}, + {3, 0, 0, 0, 0, 0} + }, + { + // Gulpin + true, + Fluctuating, + M1F1, + 70, + {LiquidOoze, StickyHold}, + {70, 43, 53, 43, 53, 40}, + {1, 0, 0, 0, 0, 0} + }, + { + // Swalot + true, + Fluctuating, + M1F1, + 70, + {LiquidOoze, StickyHold}, + {100, 73, 83, 73, 83, 55}, + {2, 0, 0, 0, 0, 0} + }, + { + // Tropius + true, + Slow, + M1F1, + 70, + {Chlorophyll, NoAbility}, + {99, 68, 83, 72, 87, 51}, + {2, 0, 0, 0, 0, 0} + }, + { + // Whismur + true, + MediumSlow, + M1F1, + 70, + {Soundproof, NoAbility}, + {64, 51, 23, 51, 23, 28}, + {1, 0, 0, 0, 0, 0} + }, + { + // Loudred + true, + MediumSlow, + M1F1, + 70, + {Soundproof, NoAbility}, + {84, 71, 43, 71, 43, 48}, + {2, 0, 0, 0, 0, 0} + }, + { + // Exploud + true, + MediumSlow, + M1F1, + 70, + {Soundproof, NoAbility}, + {104, 91, 63, 91, 63, 68}, + {3, 0, 0, 0, 0, 0} + }, + { + // Clamperl + true, + Erratic, + M1F1, + 70, + {ShellArmor, NoAbility}, + {35, 64, 85, 74, 55, 32}, + {0, 0, 1, 0, 0, 0} + }, + { + // Huntail + true, + Erratic, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {55, 104, 105, 94, 75, 52}, + {0, 1, 1, 0, 0, 0} + }, + { + // Gorebyss + true, + Erratic, + M1F1, + 70, + {SwiftSwim, NoAbility}, + {55, 84, 105, 114, 75, 52}, + {0, 0, 0, 2, 0, 0} + }, + { + // Absol + true, + MediumSlow, + M1F1, + 35, + {Pressure, NoAbility}, + {65, 130, 60, 75, 60, 75}, + {0, 2, 0, 0, 0, 0} + }, + { + // Shuppet + true, + Fast, + M1F1, + 35, + {Insomnia, NoAbility}, + {44, 75, 35, 63, 33, 45}, + {0, 1, 0, 0, 0, 0} + }, + { + // Banette + true, + Fast, + M1F1, + 35, + {Insomnia, NoAbility}, + {64, 115, 65, 83, 63, 65}, + {0, 2, 0, 0, 0, 0} + }, + { + // Seviper + true, + Fluctuating, + M1F1, + 70, + {ShedSkin, NoAbility}, + {73, 100, 60, 100, 60, 65}, + {0, 1, 0, 1, 0, 0} + }, + { + // Zangoose + true, + Erratic, + M1F1, + 70, + {Immunity, NoAbility}, + {73, 115, 60, 60, 60, 90}, + {0, 2, 0, 0, 0, 0} + }, + { + // Relicanth + true, + Slow, + M7F1, + 70, + {SwiftSwim, RockHead}, + {100, 90, 130, 45, 65, 55}, + {1, 0, 1, 0, 0, 0} + }, + { + // Aron + true, + Slow, + M1F1, + 35, + {Sturdy, RockHead}, + {50, 70, 100, 40, 40, 30}, + {0, 0, 1, 0, 0, 0} + }, + { + // Lairon + true, + Slow, + M1F1, + 35, + {Sturdy, RockHead}, + {60, 90, 140, 50, 50, 40}, + {0, 0, 2, 0, 0, 0} + }, + { + // Aggron + true, + Slow, + M1F1, + 35, + {Sturdy, RockHead}, + {70, 110, 180, 60, 60, 50}, + {0, 0, 3, 0, 0, 0} + }, + { + // Castform + true, + MediumFast, + M1F1, + 70, + {Forecast, NoAbility}, + {70, 70, 70, 70, 70, 70}, + {1, 0, 0, 0, 0, 0} + }, + { + // Volbeat + true, + Erratic, + MaleOnly, + 70, + {Illuminate, Swarm}, + {65, 73, 55, 47, 75, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Illumise + true, + Fluctuating, + FemaleOnly, + 70, + {Oblivious, NoAbility}, + {65, 47, 55, 73, 75, 85}, + {0, 0, 0, 0, 0, 1} + }, + { + // Lileep + true, + Erratic, + M7F1, + 70, + {SuctionCups, NoAbility}, + {66, 41, 77, 61, 87, 23}, + {0, 0, 0, 0, 1, 0} + }, + { + // Cradily + true, + Erratic, + M7F1, + 70, + {SuctionCups, NoAbility}, + {86, 81, 97, 81, 107, 43}, + {0, 0, 0, 0, 2, 0} + }, + { + // Anorith + true, + Erratic, + M7F1, + 70, + {BattleArmor, NoAbility}, + {45, 95, 50, 40, 50, 75}, + {0, 1, 0, 0, 0, 0} + }, + { + // Armaldo + true, + Erratic, + M7F1, + 70, + {BattleArmor, NoAbility}, + {75, 125, 100, 70, 80, 45}, + {0, 2, 0, 0, 0, 0} + }, + { + // Ralts + true, + Slow, + M1F1, + 35, + {Synchronize, Trace}, + {28, 25, 25, 45, 35, 40}, + {0, 0, 0, 1, 0, 0} + }, + { + // Kirlia + true, + Slow, + M1F1, + 35, + {Synchronize, Trace}, + {38, 35, 35, 65, 55, 50}, + {0, 0, 0, 2, 0, 0} + }, + { + // Gardevoir + true, + Slow, + M1F1, + 35, + {Synchronize, Trace}, + {68, 65, 65, 125, 115, 80}, + {0, 0, 0, 3, 0, 0} + }, + { + // Bagon + true, + Slow, + M1F1, + 35, + {RockHead, NoAbility}, + {45, 75, 60, 40, 30, 50}, + {0, 1, 0, 0, 0, 0} + }, + { + // Shellgon + true, + Slow, + M1F1, + 35, + {RockHead, NoAbility}, + {65, 95, 100, 60, 50, 50}, + {0, 0, 2, 0, 0, 0} + }, + { + // Salamence + true, + Slow, + M1F1, + 35, + {Intimidate, NoAbility}, + {95, 135, 80, 110, 80, 100}, + {0, 3, 0, 0, 0, 0} + }, + { + // Beldum + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {40, 55, 80, 35, 60, 30}, + {0, 0, 1, 0, 0, 0} + }, + { + // Metang + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {60, 75, 100, 55, 80, 50}, + {0, 0, 2, 0, 0, 0} + }, + { + // Metagross + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {80, 135, 130, 95, 90, 70}, + {0, 0, 3, 0, 0, 0} + }, + { + // Regirock + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {80, 100, 200, 50, 100, 50}, + {0, 0, 3, 0, 0, 0} + }, + { + // Regice + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {80, 50, 100, 100, 200, 50}, + {0, 0, 0, 0, 3, 0} + }, + { + // Registeel + true, + Slow, + GenderlessOnly, + 35, + {ClearBody, NoAbility}, + {80, 75, 150, 75, 150, 50}, + {0, 0, 2, 0, 1, 0} + }, + { + // Kyogre + true, + Slow, + GenderlessOnly, + 0, + {Drizzle, NoAbility}, + {100, 100, 90, 150, 140, 90}, + {0, 0, 0, 3, 0, 0} + }, + { + // Groudon + true, + Slow, + GenderlessOnly, + 0, + {Drought, NoAbility}, + {100, 150, 140, 100, 90, 90}, + {0, 3, 0, 0, 0, 0} + }, + { + // Rayquaza + true, + Slow, + GenderlessOnly, + 0, + {AirLock, NoAbility}, + {105, 150, 90, 150, 90, 95}, + {0, 2, 0, 1, 0, 0} + }, + { + // Latias + true, + Slow, + FemaleOnly, + 90, + {Levitate, NoAbility}, + {80, 80, 90, 110, 130, 110}, + {0, 0, 0, 0, 3, 0} + }, + { + // Latios + true, + Slow, + MaleOnly, + 90, + {Levitate, NoAbility}, + {80, 90, 80, 130, 110, 110}, + {0, 0, 0, 3, 0, 0} + }, + { + // Jirachi + true, + Slow, + GenderlessOnly, + 100, + {SereneGrace, NoAbility}, + {100, 100, 100, 100, 100, 100}, + {3, 0, 0, 0, 0, 0} + }, + { + // Deoxys + true, + Slow, + GenderlessOnly, + 0, + {Pressure, NoAbility}, + {50, 150, 50, 150, 50, 150}, + {0, 1, 0, 1, 0, 1} + }, + { + // Chimecho + true, + Fast, + M1F1, + 70, + {Levitate, NoAbility}, + {65, 50, 70, 95, 80, 65}, + {0, 0, 0, 1, 1, 0} + }, + { + false, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, + { + // Bonsly + true, + MediumFast, + M1F1, + 70, + {Sturdy, RockHead}, + {42, 40, 92, 12, 52, 18}, + {0, 0, 0, 0, 0, 0} + }, + { + // Munchlax + true, + MediumFast, + MaleOnly, + 0, + {NoAbility, NoAbility}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} + }, +}; + + +PokemonSpeciesData getSpeciesData(PokemonSpeciesIndex index) { + if (index > Munchlax) { + PokemonSpeciesData ret = {}; + return ret; + } + return speciesData[(size_t)index]; +} + +const u32* getSpeciesExpTable(PokemonSpeciesIndex index) { + if (index > Munchlax) return NULL; + return expTables[(size_t)getSpeciesData(index).expGrowthType]; +} + +PokemonNatureAffinity getNatureStatAffinity(PokemonNatureIndex nature, size_t stat) { + if (stat == 0 || nature > Quirky) return Neutral; // HP + return natureStatAffinities[(size_t)nature][(size_t)stat - 1]; +} + +u8 getBaseMoveMaxPPs(PokemonMoveIndex move) { + if (move > PsychoBoost) return 0; + return baseMoveMaxPPs[(size_t)move]; +} + +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/BagData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/BagData.cpp new file mode 100644 index 0000000..0f015e9 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/BagData.cpp @@ -0,0 +1,81 @@ +#include + +namespace LibPkmGC { +namespace GC { + +BagData::BagData(size_t inSize, size_t nb_regular_items, const u8* inData) : Base::DataStruct(inSize, inData), nbRegularItems(nb_regular_items){ +} + +void BagData::deleteFields(void) { + delete[] regularItems; +} + +BagData::~BagData() { + BagData::deleteFields(); +} + +void BagData::swap(BagData& other) { + if (nbRegularItems != other.nbRegularItems) throw(std::invalid_argument("this->nbRegularItems != other.nbRegularItems")); + Base::DataStruct::swap(other); + SW(regularItems); + SW_ARRAY(keyItems, 43); + SW_ARRAY(TMs, 64); + SW_ARRAY(berries, 46); + SW_ARRAY(colognes, 3); +} + +BagData::BagData(BagData const & other) : Base::DataStruct(other), nbRegularItems(other.nbRegularItems) { + regularItems = new Item[nbRegularItems]; + CP_ARRAY(regularItems, nbRegularItems); + CP_ARRAY(keyItems, 43); + CP_ARRAY(TMs, 64); + CP_ARRAY(berries, 46); + CP_ARRAY(colognes, 3); +} + +BagData& BagData::operator=(BagData const & other) { + Base::DataStruct::operator=(other); + if (nbRegularItems != other.nbRegularItems) throw(std::invalid_argument("this->nbRegularItems != other.nbRegularItems")); + if (this != &other) { + BagData::deleteFields(); + regularItems = new Item[nbRegularItems]; + CP_ARRAY(regularItems, nbRegularItems); + CP_ARRAY(keyItems, 43); + CP_ARRAY(TMs, 64); + CP_ARRAY(berries, 46); + CP_ARRAY(colognes, 3); + } + return *this; +} + +void BagData::loadFields(void) { + size_t offset = 0; + regularItems = new Item[nbRegularItems]; +#define LD_ITEMS(field, nb) for (size_t i = 0; i < nb; ++i)\ + field[i].load(data + offset + 4*i);\ + offset += 4 * nb; + + LD_ITEMS(regularItems, nbRegularItems); + LD_ITEMS(keyItems, 43); + LD_ITEMS(pokeballs, 16); + LD_ITEMS(TMs, 64); + LD_ITEMS(berries, 46); + LD_ITEMS(colognes, 3); +} + +void BagData::save(void) { + size_t offset = 0; +#define SV_ITEMS(field, nb) for (size_t i = 0; i < nb; ++i)\ + field[i].save(data + offset + 4*i);\ + offset += 4 * nb; + + SV_ITEMS(regularItems, nbRegularItems); + SV_ITEMS(keyItems, 43); + SV_ITEMS(pokeballs, 16); + SV_ITEMS(TMs, 64); + SV_ITEMS(berries, 46); + SV_ITEMS(colognes, 3); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/BattleModeData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/BattleModeData.cpp new file mode 100644 index 0000000..bcb5896 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/BattleModeData.cpp @@ -0,0 +1,35 @@ +#include + +namespace LibPkmGC { +namespace GC { + +BattleModeData::BattleModeData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) { +} + +void BattleModeData::deleteFields(void) { + for (size_t i = 0; i < 6; ++i) delete rules[i]; +} + +BattleModeData::~BattleModeData() { + BattleModeData::deleteFields(); +} + +void BattleModeData::swap(BattleModeData& other) { + Base::DataStruct::swap(other); + for (size_t i = 0; i < 6; ++i) other.rules[i]->swap(*rules[i]); +} + +BattleModeData::BattleModeData(BattleModeData const& other) : Base::DataStruct(other){ + CL_ARRAY(rules, 6); +} + +BattleModeData & BattleModeData::operator=(BattleModeData const& other) { + Base::DataStruct::operator=(other); + if (this != &other) { + CL_ARRAY(rules, 6); + } + return *this; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/DaycareData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/DaycareData.cpp new file mode 100644 index 0000000..0b00f75 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/DaycareData.cpp @@ -0,0 +1,57 @@ +#include + +namespace LibPkmGC { +namespace GC { + +DaycareData::DaycareData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) { +} + +void DaycareData::deleteFields(void) { + delete pkm; +} + +DaycareData::~DaycareData(void) { + DaycareData::deleteFields(); +} + +DaycareData::DaycareData(DaycareData const& other) : Base::DataStruct(other), +status(other.status), initialPkmLevel(other.initialPkmLevel), initialPkmPurifCounter(other.initialPkmPurifCounter) { + pkm = other.pkm->clone(); +} + +void DaycareData::swap(DaycareData& other) { + Base::DataStruct::swap(other); + SW(status); + SW(initialPkmLevel); + SW(initialPkmPurifCounter); + pkm->swap(*other.pkm); +} + +DaycareData& DaycareData::operator=(DaycareData const& other) { + Base::DataStruct::operator=(other); + if (this != &other) { + CP(status); + CP(initialPkmLevel); + CP(initialPkmPurifCounter); + *pkm = *other.pkm; + } + return *this; +} + +void DaycareData::loadFields(void) { + LD_FIELD_E(s8, status, 0, DaycareStatus); + status = ((status < NotVisited) || (status > PkmDeposited)) ? NoPkmDeposited : status; + LD_FIELD(u8, initialPkmLevel, 1); + LD_FIELD(u32, initialPkmPurifCounter, 4); +} + +void DaycareData::save(void) { + SV_FIELD_E(s8, status, 0, DaycareStatus); + SV_FIELD(u8, initialPkmLevel, 1); + SV_FIELD(u32, initialPkmPurifCounter, 4); + + SV_SUBSTRUCTURE2(Pokemon, pkm, 8); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/GroupBattleRule.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/GroupBattleRule.cpp new file mode 100644 index 0000000..05fb2e1 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/GroupBattleRule.cpp @@ -0,0 +1,101 @@ +#include + +namespace LibPkmGC { +namespace GC { + +GroupBattleRule::GroupBattleRule(size_t inSize, size_t nb_bannable_items, const u8* inData) : Base::DataStruct(inSize, inData), nbBannableItems(nb_bannable_items) { +} + + +GroupBattleRule::GroupBattleRule(GroupBattleRule const& other) : Base::DataStruct(other), nbBannableItems(other.nbBannableItems) { + *this = other; +} +void GroupBattleRule::deleteFields(void) { + delete bannedItems; +} + +GroupBattleRule::~GroupBattleRule(void) { + delete bannedItems; +} + +void GroupBattleRule::swap(GroupBattleRule & other) { + if (nbBannableItems != other.nbBannableItems) throw std::invalid_argument("this->nbBannableItems != other.nbBannableItems"); + + Base::DataStruct::swap(other); + SW(minLevel); + SW(maxLevel); + SW(maxLevelSum); + SW(itemRestrictions); + SW(noSpeciesClause); + SW(noItemClause); + SW(noSleepClause); + SW(noFreezeClause); + SW(noSkillSwap); + SW(explosionClause); + SW(noRequiemClause); + SW(allowFixedDmgAbilities); + SW(maxBattleDuration); + SW(orderTimeout); + SW_ARRAY(bannedItems, nbBannableItems); +} + +GroupBattleRule& GroupBattleRule::operator=(GroupBattleRule const& other) { + if (nbBannableItems != other.nbBannableItems) throw std::invalid_argument("this->nbBannableItems != other.nbBannableItems"); + if (this != &other) { + Base::DataStruct::operator=(other); + CP(minLevel); + CP(maxLevel); + CP(maxLevelSum); + CP(itemRestrictions); + CP(noSpeciesClause); + CP(noItemClause); + CP(noSleepClause); + CP(noFreezeClause); + CP(noSkillSwap); + CP(explosionClause); + CP(noRequiemClause); + CP(allowFixedDmgAbilities); + CP(maxBattleDuration); + CP(orderTimeout); + CP_ARRAY(bannedItems, nbBannableItems); + } + return *this; +} + +void GroupBattleRule::loadFields(void) { + bannedItems = new bool[nbBannableItems]; + LD_FIELD(u16, minLevel, 0); + LD_FIELD(u16, maxLevel, 2); + LD_FIELD(u16, maxLevelSum, 4); + LD_FIELD_E(u32, itemRestrictions, 8, ItemRestrictionLevel); + LD_FIELD_B(u8, noSpeciesClause, 12); + LD_FIELD_B(u8, noItemClause, 13); + LD_FIELD_B(u8, noSleepClause, 14); + LD_FIELD_B(u8, noFreezeClause, 15); + LD_FIELD_B(u8, noSkillSwap, 16); + LD_FIELD_B(u8, explosionClause, 17); + LD_FIELD_B(u8, noRequiemClause, 18); + LD_FIELD_B(u8, allowFixedDmgAbilities, 19); + LD_FIELD(s16, maxBattleDuration, 20); + LD_FIELD(s16, orderTimeout, 22); +} + +void GroupBattleRule::save(void) { + SV_FIELD(u16, minLevel, 0); + SV_FIELD(u16, maxLevel, 2); + SV_FIELD(u16, maxLevelSum, 4); + SV_FIELD_E(u32, itemRestrictions, 8, ItemRestrictionLevel); + SV_FIELD_B(u8, noSpeciesClause, 12); + SV_FIELD_B(u8, noItemClause, 13); + SV_FIELD_B(u8, noSleepClause, 14); + SV_FIELD_B(u8, noFreezeClause, 15); + SV_FIELD_B(u8, noSkillSwap, 16); + SV_FIELD_B(u8, explosionClause, 17); + SV_FIELD_B(u8, noRequiemClause, 18); + SV_FIELD_B(u8, allowFixedDmgAbilities, 19); + SV_FIELD(s16, maxBattleDuration, 20); + SV_FIELD(s16, orderTimeout, 22); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/MailboxData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/MailboxData.cpp new file mode 100644 index 0000000..f772b60 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/MailboxData.cpp @@ -0,0 +1,47 @@ +#include + +namespace LibPkmGC { +namespace GC { + +MailboxData::MailboxData(size_t inSize, u16 max_nb_mails, const u8* inData) : Base::DataStruct(inSize, inData), maxNbMails(max_nb_mails) { +} + +void MailboxData::deleteFields(void) { + delete[] mails; +} + +MailboxData::~MailboxData() { + MailboxData::deleteFields(); +} + +void MailboxData::swap(MailboxData & other) { + if (maxNbMails != other.maxNbMails) throw std::invalid_argument("maxNbMails != other.maxNbMails"); + Base::DataStruct::swap(other); + SW(nbMails); + SW(mails); +} + +MailboxData::MailboxData(MailboxData const & other) : Base::DataStruct(other), nbMails(other.nbMails), maxNbMails(other.maxNbMails) { + mails = new u16[nbMails]; + CP_ARRAY(mails, nbMails); +} + +MailboxData & MailboxData::operator=(MailboxData const & other) { + if (maxNbMails != other.maxNbMails) throw std::invalid_argument("maxNbMails != other.maxNbMails"); + + Base::DataStruct::operator=(other); + if (this != &other) { + MailboxData::deleteFields(); + CP(nbMails); + mails = new u16[nbMails]; + CP_ARRAY(mails, nbMails); + } + return *this; +} + +bool MailboxData::isMailEmpty(size_t i) { + return mails[i] == LIBPKMGC_MAILBOX_EMPTY_MAIL; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/PCData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/PCData.cpp new file mode 100644 index 0000000..db090e2 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/PCData.cpp @@ -0,0 +1,48 @@ +#include + +namespace LibPkmGC { +namespace GC { + +PCData::PCData(size_t inSize, size_t nb_boxes, const u8* inData) : Base::DataStruct(inSize, inData), nbBoxes(nb_boxes) { +} + + +void PCData::deleteFields(void) { + for (size_t i = 0; i < nbBoxes; ++i) + delete boxes[i]; + delete[] boxes; +} + +PCData::~PCData(void) { + PCData::deleteFields(); +} + +PCData::PCData(PCData const& other) : Base::DataStruct(other), nbBoxes(other.nbBoxes) { + boxes = new PokemonBox*[nbBoxes]; + CL_ARRAY(boxes, nbBoxes); + CP_ARRAY(items, 235); +} + +void PCData::swap(PCData& other) { + if (nbBoxes != other.nbBoxes) throw std::invalid_argument("this->nbBoxes != other.nbBoxes"); + Base::DataStruct::swap(other); + SW(boxes); + SW_ARRAY(items, 235); +} + +PCData& PCData::operator=(PCData const& other) { + if (nbBoxes != other.nbBoxes) throw std::invalid_argument("this->nbBoxes != other.nbBoxes"); + Base::DataStruct::operator=(other); + + if (this != &other) { + PCData::deleteFields(); + + boxes = new PokemonBox*[nbBoxes]; + CL_ARRAY(boxes, nbBoxes); + CP_ARRAY(items, 235); + } + return *this; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/PlayerData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/PlayerData.cpp new file mode 100644 index 0000000..e0f5d0e --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/PlayerData.cpp @@ -0,0 +1,69 @@ +#include + +namespace LibPkmGC { +namespace GC { + +PlayerData::PlayerData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) { +} + + +void PlayerData::deleteFields(void) { + for (size_t i = 0; i < 6; ++i) delete party[i]; + delete bag; + delete trainerName; +} + +PlayerData::~PlayerData(void) { + PlayerData::deleteFields(); +} + +PlayerData::PlayerData(PlayerData const& other) : Base::DataStruct(other), SID(other.SID), TID(other.TID), money(other.money), pkCoupons(other.pkCoupons), +trainerGender(other.trainerGender){ + CL(trainerName); + CL_ARRAY(party, 6); + CL(bag); +} + +PlayerData& PlayerData::operator=(PlayerData const& other) { + if (size != other.size) throw std::invalid_argument("Cannot assign because *this and other are of different types"); + Base::DataStruct::operator=(other); + if (this != &other) { + PlayerData::deleteFields(); + CP(SID); CP(TID); CP(money); CP(pkCoupons); + CL(trainerName); + CL_ARRAY(party, 6); + CL(bag); + CP(trainerGender); + } + return *this; +} + +void PlayerData::swap(PlayerData& other) { + if (size != other.size) throw std::invalid_argument("Cannot assign because *this and other are of different types"); + Base::DataStruct::swap(other); + SW(SID); SW(TID); SW(money); SW(pkCoupons); + CL(trainerName); + SW_ARRAY(party, 6); + SW(bag); + SW(trainerGender); +} + +void PlayerData::loadFields(void) { + trainerName = new PokemonString(data, 10); + LD_FIELD(u16, SID, 0x2c); + LD_FIELD(u16, TID, 0x2e); +} + +void PlayerData::save(void) { + trainerName->save(data, 10); + SV_FIELD(u16, SID, 0x2c); + SV_FIELD(u16, TID, 0x2e); +} +void PlayerData::swapPokemon(size_t n, size_t m) { + if ((n > 6) || (m > 6)) return; + std::swap(party[n], party[m]); + + +} +} +} diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/Pokemon.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/Pokemon.cpp new file mode 100644 index 0000000..796d8db --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/Pokemon.cpp @@ -0,0 +1,41 @@ +#include + + +namespace LibPkmGC { +namespace GC { + +Pokemon::Pokemon(size_t inSize, const u8* inData) : Base::Pokemon(inSize, inData) { + usesPartyData = true; +} + + +Pokemon::~Pokemon(void) +{ +} + +Pokemon::Pokemon(Pokemon const& other) : Base::Pokemon(other), shadowPkmID(other.shadowPkmID) {} +void Pokemon::swap(Pokemon& other) { Base::Pokemon::swap(other); SW(shadowPkmID); } + + +PokemonAbilityIndex Pokemon::getAbility(void) const { + const PokemonSpeciesData dt = getSpeciesData(species); + return (hasSpecialAbility()) ? dt.possibleAbilities[1] : dt.possibleAbilities[0]; +} + +Pokemon& Pokemon::operator=(Pokemon const& other) { + if (this != &other) { + Base::Pokemon::operator=(other); + CP(shadowPkmID); + } + return *this; +} + +void Pokemon::swap(Base::Pokemon & other) { + return swap((Pokemon&)other); +} +Pokemon& Pokemon::operator=(Base::Pokemon const& other) { + return operator=((Pokemon const&)other); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/PokemonBox.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/PokemonBox.cpp new file mode 100644 index 0000000..0e1d4e7 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/PokemonBox.cpp @@ -0,0 +1,24 @@ +#include + +namespace LibPkmGC { +namespace GC { + +PokemonBox::PokemonBox(size_t inSize, const u8* inData) : Base::PokemonBox(inSize, inData){ +}; + +PokemonBox::~PokemonBox(void) { +} + +PokemonBox::PokemonBox(PokemonBox const& other) : Base::PokemonBox(other) { + +} +void PokemonBox::loadFields(void) { + name = new PokemonString(data, 8); +} + +void PokemonBox::save(void) { + name->save(data, 8); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/PokemonString.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/PokemonString.cpp new file mode 100644 index 0000000..01adc29 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/PokemonString.cpp @@ -0,0 +1,322 @@ +#include +#include +#include + + +namespace LibPkmGC { +namespace GC { + +PokemonString::PokemonString(const char* str) : Base::PokemonString(), _data(NULL), dataSz(0), dataCapacity(0) { + fromUTF8(str); +} + +PokemonString::PokemonString(u8 * data, size_t nb) : Base::PokemonString(), _data(NULL), dataSz(0), dataCapacity(0){ + load(data, nb); +} + +PokemonString::PokemonString(PokemonString const& other) : Base::PokemonString(other), dataSz(other.dataSz), dataCapacity(0), _data(NULL) { + resizeData(); + std::copy(other._data, other._data + dataSz, _data); +} + +PokemonString::~PokemonString(void) { + delete[] _data; +} + +PokemonString * PokemonString::clone(void) const { + return new PokemonString(*this); +} + +PokemonString * PokemonString::create(void) const { + return new PokemonString; +} + +PokemonString & PokemonString::operator=(PokemonString const & other) { + if (this != &other) { + Base::PokemonString::operator=(other); + delete[] _data; + std::copy(other._data, other._data + dataSz, _data); + } + return *this; +} + +PokemonString& PokemonString::operator=(Base::PokemonString const& other) { + return operator=((PokemonString const&)other); +} + + +} +} + +namespace { +using namespace LibPkmGC; +typedef void* conv_t; +typedef u32 ucs4_t; + +// Custom : +#define RET_ILSEQ -1 +#define RET_ILUNI -2 +#define RET_TOOSMALL -3 +#define RET_TOOFEW(c) (-4*(c+1)) + +// Adapted from : + +/* +* Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc. +* This file is part of the GNU LIBICONV Library. +* +* The GNU LIBICONV Library is free software; you can redistribute it +* and/or modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* The GNU LIBICONV Library is distributed in the hope that it will be +* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with the GNU LIBICONV Library; see the file COPYING.LIB. +* If not, write to the Free Software Foundation, Inc., 51 Franklin Street, +* Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +/* +* UCS-2BE = UCS-2 big endian +*/ + +static int +ucs2be_mbtowc(conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 2) { + if (s[0] >= 0xd8 && s[0] < 0xe0) { + return RET_ILSEQ; + } + else if (s[0] == 0xff && s[1] == 0xff) { // [LibPkmGC] + return RET_ILSEQ; + } + else { + *pwc = (s[0] << 8) + s[1]; + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2be_wctomb(conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000) && wc != 0xffff) { // [LibPkmGC] + if (n >= 2) { + r[0] = (unsigned char)(wc >> 8); + r[1] = (unsigned char)wc; + return 2; + } + else + return RET_TOOSMALL; + } + return RET_ILUNI; +} + +/* +* UTF-8 +*/ + +/* Specification: RFC 3629 */ + +static int +utf8_mbtowc(conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = s[0]; + + if (c < 0x80) { + *pwc = c; + return 1; + } + else if (c < 0xc2) { + return RET_ILSEQ; + } + else if (c < 0xe0) { + if (n < 2) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40)) + return RET_ILSEQ; + *pwc = ((ucs4_t)(c & 0x1f) << 6) + | (ucs4_t)(s[1] ^ 0x80); + return 2; + } + else if (c < 0xf0) { + if (n < 3) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0))) + return RET_ILSEQ; + *pwc = ((ucs4_t)(c & 0x0f) << 12) + | ((ucs4_t)(s[1] ^ 0x80) << 6) + | (ucs4_t)(s[2] ^ 0x80); + return 3; + } + else if (c < 0xf8 && sizeof(ucs4_t) * 8 >= 32) { + if (n < 4) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90))) + return RET_ILSEQ; + *pwc = ((ucs4_t)(c & 0x07) << 18) + | ((ucs4_t)(s[1] ^ 0x80) << 12) + | ((ucs4_t)(s[2] ^ 0x80) << 6) + | (ucs4_t)(s[3] ^ 0x80); + return 4; + } + else if (c < 0xfc && sizeof(ucs4_t) * 8 >= 32) { + if (n < 5) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88))) + return RET_ILSEQ; + *pwc = ((ucs4_t)(c & 0x03) << 24) + | ((ucs4_t)(s[1] ^ 0x80) << 18) + | ((ucs4_t)(s[2] ^ 0x80) << 12) + | ((ucs4_t)(s[3] ^ 0x80) << 6) + | (ucs4_t)(s[4] ^ 0x80); + return 5; + } + else if (c < 0xfe && sizeof(ucs4_t) * 8 >= 32) { + if (n < 6) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84))) + return RET_ILSEQ; + *pwc = ((ucs4_t)(c & 0x01) << 30) + | ((ucs4_t)(s[1] ^ 0x80) << 24) + | ((ucs4_t)(s[2] ^ 0x80) << 18) + | ((ucs4_t)(s[3] ^ 0x80) << 12) + | ((ucs4_t)(s[4] ^ 0x80) << 6) + | (ucs4_t)(s[5] ^ 0x80); + return 6; + } + else + return RET_ILSEQ; +} + +static int +utf8_wctomb(conv_t conv, unsigned char *r, ucs4_t wc, int n) /* n == 0 is acceptable */ { + int count; + if (wc < 0x80) + count = 1; + else if (wc < 0x800) + count = 2; + else if (wc < 0x10000) + count = 3; + else if (wc < 0x200000) + count = 4; + else if (wc < 0x4000000) + count = 5; + else if (wc <= 0x7fffffff) + count = 6; + else + return RET_ILUNI; + if (n < count) + return RET_TOOSMALL; + switch (count) { /* note: code falls through cases! */ + case 6: r[5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000; + case 5: r[4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000; + case 4: r[3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000; + case 3: r[2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800; + case 2: r[1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0; + case 1: r[0] = wc; + } + return count; +} + + +} + +namespace LibPkmGC { +namespace GC { + +void PokemonString::fromUTF8(const char * str) { + str = (str == NULL) ? "" : str; + strSz = std::strlen(str) + 1; + resizeStr(); + + dataSz = 2 * strSz; + resizeStr(); + + dataSz = 0; + + int s = 0; + size_t offset = 0; + while (offset < strSz) { + u32 c; + s = utf8_mbtowc(NULL, &c, (const unsigned char*)str + offset, 6); + if (s < 0) break; + offset += s; + s = ucs2be_wctomb(NULL, _data + dataSz, c, 2); + if (s < 0) break; + dataSz += s; + if (c == 0) break; + } + hasChanged = true; +} + +const char * PokemonString::toUTF8(void) const { + if (!hasChanged) return _str; + + strSz = 3 * (dataSz / 2); + resizeStr(); + + strSz = 0; + + int s = 0; + size_t offset = 0; + + while (offset < dataSz) { + u32 c; + s = ucs2be_mbtowc(NULL, &c, (const unsigned char*)_data + offset, 2); + if (s < 0) break; + offset += s; + s = utf8_wctomb(NULL, (unsigned char*) _str + strSz, c, 6); + if (s < 0) break; + strSz += s; + if (c == 0) break; + } + hasChanged = false; + return _str; +} + +size_t PokemonString::size(void) const { + size_t i = 0; + while ((2 * i < dataSz) && (_data[2 * i] != 0 || _data[2 * i + 1] != 0)) i += 2; + return i; +} + +void PokemonString::load(u8 * data, size_t nb) { + dataSz = 2 * nb + 2; + resizeData(); + std::copy(data, data + dataSz, _data); +} + +void PokemonString::save(u8 * data, size_t nb) const { + size_t sz = size(), m = ((nb <= sz) ? nb : sz); // how much characters should we write ? + std::copy(_data, _data + 2*m, data); + + std::fill(data + 2 * m, data + 2 * (nb + 1), 0); +} + +void PokemonString::resizeData(void) { + if (dataCapacity < dataSz) { + dataCapacity = dataSz; + delete[] _data; + _data = new u8[dataSz]; + } +} + + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoData.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoData.cpp new file mode 100644 index 0000000..6203c18 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoData.cpp @@ -0,0 +1,119 @@ +#include +namespace LibPkmGC { +namespace GC { + +StrategyMemoData::StrategyMemoData(size_t inSize, const u8* inData) : Base::DataStruct(inSize, inData) { +} + +void StrategyMemoData::deleteFields(void) { + for (size_t i = 0; i < 500; ++i) + delete entries[i]; +} + +StrategyMemoData::~StrategyMemoData(void) { + StrategyMemoData::deleteFields(); +} + +StrategyMemoData::StrategyMemoData(StrategyMemoData const& other) : nbEntries(other.nbEntries) { + CL_ARRAY(entries, 500); +} + +void StrategyMemoData::swap(StrategyMemoData& other) { + Base::DataStruct::swap(other); + SW(nbEntries); + SW_ARRAY(entries, 500); +} + +StrategyMemoData& StrategyMemoData::operator=(StrategyMemoData const& other) { + Base::DataStruct::operator=(other); + if (this != &other) { + for (size_t i = 0; i < 500; ++i) *entries[i] = *(other.entries[i]); + } + return *this; +} + +void StrategyMemoData::loadFields(void) { + LD_FIELD(u16, nbEntries, 0); + //if (nbEntries > 0x1f4) nbEntries = 0x1f4; +} + +void StrategyMemoData::save(void) { + //if (nbEntries > 0x1f4) nbEntries = 0x1f4; + SV_FIELD(u16, nbEntries, 0); +} + +bool StrategyMemoData::registerSpecies(PokemonSpeciesIndex index, u32 PID, u16 SID, u16 TID) { + u16 i = 0; + + while ((i < nbEntries) && (index != entries[i++]->species)); + if ((i == nbEntries) || (nbEntries == 0x1f4)) return false; + + StrategyMemoEntry* entry = entries[++nbEntries - 1]; + + entry->setInfoCompleteness(true); + entry->species = index; + entry->firstSID = SID; + entry->firstTID = TID; + entry->firstPID = PID; + + return true; +} + +bool StrategyMemoData::registerSpecies(Pokemon * pkm) { + return registerSpecies(pkm->species, pkm->PID, pkm->SID, pkm->TID); +} + +void StrategyMemoData::deleteEntry(size_t index) { + if ((index >= 500) || (nbEntries == 0)) return; + StrategyMemoEntry* entries2[500] = { NULL }; + StrategyMemoEntry* emptyobj = entries[index]->create(); + delete entries[index]; + std::copy(entries, entries + index, entries2); + std::copy(entries + index + 1, entries + 500, entries2 + index); + entries2[499] = emptyobj; + + std::copy(entries2, entries2 + 500, entries); +} + +size_t StrategyMemoData::recount(void) const { + size_t i = 0; + while (i < 500 && getSpeciesData(entries[i++]->species).isValid); + return i; +} + +void StrategyMemoData::sortedBySpeciesIndex(StrategyMemoEntry* dst[0x19b]) { + std::fill(dst, dst + 0x19b, (StrategyMemoEntry*)NULL); + for (size_t i = 0; i < (size_t)nbEntries; ++i) { + size_t index = (size_t)entries[i]->species; + if ((dst[index] != NULL) && (index <= 0x19b) && (getSpeciesData(entries[i]->species).isValid)) dst[index] = entries[i]; + } +} + +void StrategyMemoData::fixInvalidEntries(void) { + StrategyMemoEntry* bySpecies[0x19b] = { NULL }; + StrategyMemoEntry* entries2[500] = { NULL }; + + StrategyMemoEntry* emptyobj = entries[0]->create(); + + nbEntries = 0; + for (size_t i = 0; i < 500; ++i) { + size_t index = (size_t)entries[i]->species; + if ((bySpecies[index] != NULL) && (index <= 0x19b) && (getSpeciesData(entries[i]->species).isValid)) { + bySpecies[index] = entries[i]; + entries2[nbEntries++] = entries[i]; + } + else { + delete entries[i]; + } + } + + for (size_t i = 0; i < 500; ++i) { + if (entries2[i] == NULL) entries2[i] = emptyobj->clone(); + } + + std::copy(entries2, entries2 + nbEntries, entries); + delete emptyobj; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoEntry.cpp b/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoEntry.cpp new file mode 100644 index 0000000..5f5746c --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Common/StrategyMemoEntry.cpp @@ -0,0 +1,48 @@ +#include + +namespace LibPkmGC { +namespace GC { + +StrategyMemoEntry::StrategyMemoEntry(const u8* inData) : Base::DataStruct(0xc, inData) { +} + +void StrategyMemoEntry::deleteFields(void) {} + + +StrategyMemoEntry::~StrategyMemoEntry(void) { + StrategyMemoEntry::deleteFields(); +} + +void StrategyMemoEntry::swap(StrategyMemoEntry& other) { + Base::DataStruct::swap(other); + SW(species); + SW(flags); + SW(firstSID); + SW(firstTID); + SW(firstSID); +} + +void StrategyMemoEntry::loadFields(void) { + u16 speciesIndexTmp; + LD_FIELD(u16, speciesIndexTmp, 0); + LD_FIELD(u16, firstSID, 4); + LD_FIELD(u16, firstTID, 6); + LD_FIELD(u32, firstPID, 8); + + flags = (speciesIndexTmp >> 14); + species = (PokemonSpeciesIndex)(speciesIndexTmp & 0x3fff); +} + +void StrategyMemoEntry::save(void) { + SV_FIELD(u16, species | (flags << 14), 0); + SV_FIELD(u16, firstSID, 4); + SV_FIELD(u16, firstTID, 6); + SV_FIELD(u32, firstPID, 8); +} + +bool StrategyMemoEntry::isEmpty(void) const { + return species == NoSpecies; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/Detail/CircularDependencies.cpp b/LibPkmGC/src/LibPkmGC/GC/Detail/CircularDependencies.cpp new file mode 100644 index 0000000..cd32e96 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/Detail/CircularDependencies.cpp @@ -0,0 +1,23 @@ +#include +#include + +namespace LibPkmGC { + +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(BagData) +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(PCData) +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(PlayerData) +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(MailboxData) +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(GroupBattleRule) +LIBPKMGC_GEN_UNIMPLEMENTED_CONVERTER_CTOR(BattleModeData) + + +LIBPKMGC_GEN_CONVERTER_CTOR(DaycareData) +LIBPKMGC_GEN_CONVERTER_CTOR(Pokemon) +LIBPKMGC_GEN_CONVERTER_CTOR(StrategyMemoData) +LIBPKMGC_GEN_CONVERTER_CTOR(PokemonBox) + + +LIBPKMGC_GEN_UNIMPLEMENTED_SAVE_EDITING_CONVERTER_CTOR(SaveSlot) +LIBPKMGC_GEN_UNIMPLEMENTED_SAVE_EDITING_CONVERTER_CTOR(Save) + +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/SaveEditing/Save.cpp b/LibPkmGC/src/LibPkmGC/GC/SaveEditing/Save.cpp new file mode 100644 index 0000000..35f4349 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/SaveEditing/Save.cpp @@ -0,0 +1,113 @@ +#include + +namespace LibPkmGC { +namespace GC { +namespace SaveEditing { + +Save::Save(size_t inSize, size_t nb_slots, const u8* inData, bool hasGCIData_) : Base::DataStruct(inSize, inData + ((hasGCIData_ && inData != NULL) ? 0x40 : 0)), +hasGCIData(hasGCIData_), nbSlots(nb_slots) { + if (hasGCIData) std::copy(inData, inData + 0x40, GCIData); +} + + +void Save::deleteFields(void) { + for (size_t i = 0; i < nbSlots; ++i) + delete saveSlots[i]; + + delete[] saveSlots; +} + + +Save::~Save(void) { + Save::deleteFields(); +} + +void Save::swap(Save& other) { + if (nbSlots != other.nbSlots) throw std::invalid_argument("this->nbSlots != other.nbSlots"); + Base::DataStruct::swap(other); + SW(saveSlots); + SW(_is_decrypted); + SW(hasGCIData); + SW_ARRAY(GCIData, 0x40); +} + +Save::Save(Save const& other) : Base::DataStruct(other), nbSlots(other.nbSlots), _is_decrypted(other._is_decrypted), hasGCIData(other.hasGCIData) { + saveSlots = new SaveSlot*[nbSlots]; + CL_ARRAY(saveSlots, nbSlots); + CP_ARRAY(GCIData, 64); +} + +Save& Save::operator=(Save const& other) { + if (nbSlots != other.nbSlots) throw std::invalid_argument("this->nbSlots != other.nbSlots"); + Base::DataStruct::operator=(other); + if (this != &other) { + Save::deleteFields(); + + CP(_is_decrypted); + CP(hasGCIData); + CP_ARRAY(GCIData, 64); + + saveSlots = new SaveSlot*[nbSlots]; + for (size_t i = 0; i < nbSlots; ++i) + saveSlots[i] = other.saveSlots[i]->clone(); + } + + return *this; +} + +void Save::loadData(u32 flags) { + _is_decrypted = ((flags & 1) == 1) ? true : false; +} + +void Save::reload(const u8* inData, u32 flags) { + if (inData == NULL) Base::DataStruct::reload(NULL, 1); + else Base::DataStruct::reload(inData, 0); +} + +void Save::saveEncrypted(u8* outBuf, bool exportGCIData) { + if (hasGCIData && exportGCIData) { + std::copy(GCIData, GCIData + 0x40, outBuf); + outBuf += 0x40; + } + std::copy(data, data + 0x6000, outBuf); + size_t sz = saveSlots[0]->fixedSize; + for (size_t i = 0; i < nbSlots; ++i) + saveSlots[i]->saveEncrypted(outBuf + 0x6000 + sz*i); +} + +inline bool date_comparison(SaveSlot* a, SaveSlot* b) { + return (a->saveCount > b->saveCount); // order by saveCount desc +} + +SaveSlot* Save::getMostRecentSlot(size_t index) const { + if (index > nbSlots) return NULL; + SaveSlot** slots2 = new SaveSlot*[nbSlots]; + std::copy(saveSlots, saveSlots + nbSlots, slots2); + std::sort(slots2, slots2 + nbSlots, date_comparison); + + SaveSlot* ret = slots2[index]; + delete[] slots2; + return ret; +} + +SaveSlot * Save::getMostRecentValidSlot(size_t index, size_t *outIndex) { + if (index > nbSlots) return NULL; + SaveSlot** slots2 = new SaveSlot*[nbSlots]; + std::copy(saveSlots, saveSlots + nbSlots, slots2); + std::sort(slots2, slots2 + nbSlots, date_comparison); + + size_t v = 0; + while (v < nbSlots && slots2[v]->isCorrupt()) ++v; + if (outIndex != NULL) *outIndex = v; + if (v == nbSlots) { + delete[] slots2; + return NULL; + } + SaveSlot* ret = slots2[index]; + delete[] slots2; + return ret; +} + +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/GC/SaveEditing/SaveSlot.cpp b/LibPkmGC/src/LibPkmGC/GC/SaveEditing/SaveSlot.cpp new file mode 100644 index 0000000..9ac0421 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/GC/SaveEditing/SaveSlot.cpp @@ -0,0 +1,101 @@ +#include + +namespace LibPkmGC { +namespace GC { +namespace SaveEditing { + +SaveSlot::SaveSlot(size_t inSize, size_t nb_random_bytes, const u8* inData) : Base::DataStruct(inSize, inData), nbRandomBytes(nb_random_bytes) { +} + +void SaveSlot::deleteFields(void) { + delete[] randomBytes; + delete player; + delete PC; + delete mailbox; + delete daycare; + delete strategyMemo; + delete battleMode; +} + +SaveSlot::~SaveSlot(void) { + SaveSlot::deleteFields(); +} + +SaveSlot::SaveSlot(const SaveSlot& other) : Base::DataStruct(other), +magic(other.magic), headerChecksum(other.headerChecksum), saveCount(other.saveCount), +version(other.version), titleScreenLanguage(other.titleScreenLanguage), noRumble(other.noRumble), nbRandomBytes(other.nbRandomBytes){ + randomBytes = new u8[nbRandomBytes]; + std::copy(other.randomBytes, other.randomBytes + nbRandomBytes, randomBytes); + + std::copy(other.memcardUID, other.memcardUID + 2, memcardUID); + + CL(player); + CL(PC); + CL(mailbox); + CL(daycare); + CL(strategyMemo); + + CL(battleMode); + +} + + +void SaveSlot::swap(SaveSlot& other) { + if (nbRandomBytes != other.nbRandomBytes) throw std::invalid_argument("this->nbRandomBytes != other.nbRandomBytes"); + Base::DataStruct::swap(other); + SW(magic); + SW(headerChecksum); + SW(saveCount); + + SW(memcardUID[0]); SW(memcardUID[1]); + + SW(version); + SW(titleScreenLanguage); + SW(noRumble); + SW(player); + SW(PC); + SW(mailbox); + SW(daycare); + SW(strategyMemo); + SW(battleMode); + + SW(randomBytes); +} + +SaveSlot& SaveSlot::operator=(SaveSlot const& other) { + if (nbRandomBytes != other.nbRandomBytes) throw std::invalid_argument("this->nbRandomBytes != other.nbRandomBytes"); + + Base::DataStruct::operator=(other); + if (this != &other) { + SaveSlot::deleteFields(); + randomBytes = new u8[nbRandomBytes]; + CP_ARRAY(randomBytes, nbRandomBytes); + CP(magic); + CP(headerChecksum); + CP(saveCount); + CP(memcardUID[0]); CP(memcardUID[1]); + + CP(version); + CP(titleScreenLanguage); + CP(noRumble); + + + CL(player); + CL(PC); + CL(mailbox); + CL(daycare); + CL(strategyMemo); + CL(battleMode); + } + return *this; +} + +void SaveSlot::reload(const u8* inData, u32 flags) { + if (inData == NULL) Base::DataStruct::reload(NULL, 1); + else Base::DataStruct::reload(inData, 0); +} + + +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/BagData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/BagData.cpp new file mode 100644 index 0000000..778ea40 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/BagData.cpp @@ -0,0 +1,48 @@ +#include + +namespace LibPkmGC { +namespace XD { + +BagData::BagData(void) : GC::BagData(0x418, 30) { + initWithEmptyData(); +} + +BagData::BagData(const u8* inData) : GC::BagData(0x418, 30, inData) { + load(); +} + +BagData::BagData(BagData const& other) : GC::BagData(other) { + CP_ARRAY(battleCDs, 60); +} + + +BagData::~BagData(){ +} + +void BagData::swap(BagData& other) { + GC::BagData::swap(other); + SW_ARRAY(battleCDs, 60); +} + +BagData* BagData::clone(void) const { + return new BagData(*this); +} + +BagData* BagData::create(void) const { + return new BagData; +} + +void BagData::loadFields(void) { + GC::BagData::loadFields(); + for (size_t i = 0; i < 60; ++i) + battleCDs[i].load(data + 0x328 + 4 * i); +} + +void BagData::save(void) { + GC::BagData::save(); + for (size_t i = 0; i < 60; ++i) + battleCDs[i].save(data + 0x328 + 4 * i); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/BattleModeData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/BattleModeData.cpp new file mode 100644 index 0000000..4532b7a --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/BattleModeData.cpp @@ -0,0 +1,47 @@ +#include + +namespace LibPkmGC { +namespace XD { + +BattleModeData::BattleModeData(void) : GC::BattleModeData(0x364) { + initWithEmptyData(); +} + +BattleModeData::BattleModeData(const u8* inData) : GC::BattleModeData(0x364, inData) { + load(); +} + +BattleModeData::BattleModeData(BattleModeData const& other) : GC::BattleModeData(other) {} + +BattleModeData::~BattleModeData() +{ +} + + +void BattleModeData::swap(BattleModeData& other) { + GC::BattleModeData::swap(other); + SW(battleModeUsed); +} +BattleModeData* BattleModeData::clone(void) const +{ + return new BattleModeData(*this); +} + +BattleModeData* BattleModeData::create(void) const +{ + return new BattleModeData; +} + +void BattleModeData::loadFields(void) { + LD_SUBSTRUCTURE_ARRAY(GroupBattleRule, rules, 6, 0); + LD_FIELD_B(u8, battleModeUsed, 0x360); +} + +void BattleModeData::save(void) { + SV_SUBSTRUCTURE_ARRAY(GroupBattleRule, rules, 6, 0); + SV_FIELD_B(u8, battleModeUsed, 0x360); + std::fill(data + 0x361, data + 0x363, 0); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/DaycareData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/DaycareData.cpp new file mode 100644 index 0000000..cba8971 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/DaycareData.cpp @@ -0,0 +1,35 @@ +#include + + +namespace LibPkmGC { +namespace XD { + +DaycareData::DaycareData(void) : GC::DaycareData(0xcc) { + initWithEmptyData(); +} + +DaycareData::DaycareData(const u8* inData) : GC::DaycareData(0xcc, inData) { + load(); +} + +DaycareData::DaycareData(DaycareData const& other) : GC::DaycareData(other) {} + + +DaycareData::~DaycareData(void) { +} + +void DaycareData::loadFields(void) { + GC::DaycareData::loadFields(); + pkm = new Pokemon(data + 8); +} + +DaycareData* DaycareData::clone(void) const { + return new DaycareData(*this); +} + +DaycareData* DaycareData::create(void) const { + return new DaycareData; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/GroupBattleRule.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/GroupBattleRule.cpp new file mode 100644 index 0000000..e8aba9b --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/GroupBattleRule.cpp @@ -0,0 +1,63 @@ +#include + +namespace LibPkmGC { +namespace XD { + +GroupBattleRule::GroupBattleRule(const u8* inData) : GC::GroupBattleRule(0x90, 62, inData) { + load(); +} + +GroupBattleRule::GroupBattleRule(void) : GC::GroupBattleRule(0x90, 62) { + initWithEmptyData(); +} + +GroupBattleRule::GroupBattleRule(GroupBattleRule const& other) : GC::GroupBattleRule(other), revealDeoxysForm(other.revealDeoxysForm), +nbPkm(other.nbPkm), isBattleOpen(other.isBattleOpen) { + CL(customName); +} + +void GroupBattleRule::deleteFields(void) { + delete customName; +} + +GroupBattleRule::~GroupBattleRule() { + GroupBattleRule::deleteFields(); +} + +void GroupBattleRule::swap(GroupBattleRule & other) { + GC::GroupBattleRule::swap(other); + SW(nbPkm); + SW(isBattleOpen); + SW(revealDeoxysForm); + SW(customName); +} + +GroupBattleRule* GroupBattleRule::clone(void) const { + return new GroupBattleRule(*this); +} + +GroupBattleRule* GroupBattleRule::create(void) const { + return new GroupBattleRule; +} + +void GroupBattleRule::loadFields(void) { + GC::GroupBattleRule::loadFields(); + LD_FIELD_B(u8, revealDeoxysForm, 25); + LD_FIELD(u16, nbPkm, 26); + LD_FIELD_B(u16, isBattleOpen, 28); + customName = new GC::PokemonString(data + 30, 25); // (25+1)*2 bytes + LD_ARRAY_B(u8, bannedItems, 62, 82); + +} + +void GroupBattleRule::save(void) { + GC::GroupBattleRule::save(); + SV_FIELD_B(u8, revealDeoxysForm, 25); + SV_FIELD(u16, nbPkm, 26); + SV_FIELD_B(u16, isBattleOpen, 28); + customName->save(data + 30, 25); + SV_ARRAY_B(u8, bannedItems, 62, 82); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/MailboxData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/MailboxData.cpp new file mode 100644 index 0000000..2022245 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/MailboxData.cpp @@ -0,0 +1,41 @@ +#include + +namespace LibPkmGC { +namespace XD { + + +MailboxData::MailboxData(void) : GC::MailboxData(0x4a, 32) { + initWithEmptyData(); +} + +MailboxData::MailboxData(const u8* inData) : GC::MailboxData(0x4a, 32, inData) { + load(); +} + +MailboxData::MailboxData(MailboxData const& other) : GC::MailboxData(other) {} + + +MailboxData::~MailboxData() { +} + +MailboxData* MailboxData::clone(void) const { + return new MailboxData(*this); +} + +MailboxData* MailboxData::create(void) const { + return new MailboxData; +} + +void MailboxData::loadFields(void) { + mails = new u16[32]; + LD_FIELD(u16, nbMails, 0); + LD_ARRAY(u16, mails, 32, 2); +} + +void MailboxData::save(void) { + SV_FIELD(u16, nbMails, 0); + SV_ARRAY(u16, mails, 32, 2); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/PCData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/PCData.cpp new file mode 100644 index 0000000..b53ac9d --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/PCData.cpp @@ -0,0 +1,47 @@ +#include + +namespace LibPkmGC { +namespace XD { + +PCData::PCData(void) : GC::PCData(0xbc50, 8) { + initWithEmptyData(); +} + +PCData::PCData(const u8* inData) : GC::PCData(0xbc50, 8, inData) { + load(); +} + +PCData::PCData(PCData const& other) : GC::PCData(other) {} + + +PCData::~PCData(void) { +} + +PCData* PCData::clone(void) const { + return new PCData(*this); +} + +PCData* PCData::create(void) const { + return new PCData; +} + + + +void PCData::loadFields(void) { + boxes = new GC::PokemonBox*[nbBoxes]; + + LD_SUBSTRUCTURE_ARRAY(PokemonBox, boxes, 8, 0); + + for (size_t i = 0; i < 235; ++i) + items[i].load(data + 0xb860 + 4*i); +} + +void PCData::save(void) { + SV_SUBSTRUCTURE_ARRAY(PokemonBox, boxes, 8, 0); + + for (size_t i = 0; i < 235; ++i) + items[i].save(data + 0xb860 + 4*i); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/PlayerData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/PlayerData.cpp new file mode 100644 index 0000000..eb68360 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/PlayerData.cpp @@ -0,0 +1,55 @@ +#include + +namespace LibPkmGC { +namespace XD { + +PlayerData::PlayerData(void) : GC::PlayerData(0x978) { + initWithEmptyData(); +} + +PlayerData::PlayerData(const u8* inData) : GC::PlayerData(0x978, inData) { + load(); +} + +PlayerData::PlayerData(PlayerData const& other) : GC::PlayerData(other) {} + + +PlayerData::~PlayerData(void){ +} + +PlayerData* PlayerData::clone(void) const { + return new PlayerData(*this); +} + +PlayerData* PlayerData::create(void) const { + return new PlayerData; +} + +void PlayerData::loadFields(void) { + GC::PlayerData::loadFields(); + LD_FIELD_E(u8, trainerGender, 0x8e0, Gender); + if (trainerGender > Female) trainerGender = Male; + + LD_FIELD(u32, money, 0x8e4); + LD_FIELD(u32, pkCoupons, 0x8e8); + + LD_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30); + LD_SUBSTRUCTURE(BagData, bag, 0x4c8); +} + +void PlayerData::save(void) { + GC::PlayerData::save(); + if (trainerGender > Female) trainerGender = Male; + SV_FIELD_E(u8, trainerGender, 0x8e0, Gender); + + SV_FIELD(u32, money, 0x8e4); + SV_FIELD(u32, pkCoupons, 0x8e8); + SV_FIELD(u32, pkCoupons, 0x8ec); + + SV_SUBSTRUCTURE_ARRAY(Pokemon, party, 6, 0x30); + SV_SUBSTRUCTURE(BagData, bag, 0x4c8); + +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/Pokemon.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/Pokemon.cpp new file mode 100644 index 0000000..ce3235b --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/Pokemon.cpp @@ -0,0 +1,174 @@ +#include + +#define EGG_FLAG 0x80 +#define SPECIAL_ABILITY_FLAG 0x40 +#define INVALID_PKM_FLAG 0x20 + +namespace LibPkmGC { +namespace XD { + +Pokemon::Pokemon(const u8* inData) : GC::Pokemon(0xc4, inData) { + load(); +} + +Pokemon::Pokemon(void) : GC::Pokemon(0xc4) { initWithEmptyData(); } + +Pokemon::~Pokemon(void) { +} + +Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other), pkmFlags(other.pkmFlags) {} +Pokemon* Pokemon::clone(void) const { return new Pokemon(*this); } +Pokemon* Pokemon::create(void) const { return new Pokemon; } + +void Pokemon::swap(Pokemon& other) { + GC::Pokemon::swap(other); + SW(pkmFlags); +} + +Pokemon& Pokemon::operator=(Pokemon const& other) { + if (this != &other) { + GC::Pokemon::operator=(other); + CP(pkmFlags); + } + return *this; +} + +void Pokemon::loadFields(void) { + u8 marksTmp = 0; + u16 specialRibbonsTmp = 0; + LD_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex); + LD_FIELD_E(u16, heldItem, 0x02, ItemIndex); + LD_FIELD(u16, partyData.currentHP, 0x04); + + u16 happiness_tmp; + LD_FIELD(u16, happiness_tmp, 0x06); + happiness = (happiness_tmp > 255) ? 255 : happiness_tmp; + + u16 locationCaught_tmp; + LD_FIELD(u16, locationCaught_tmp, 0x08); + locationCaught = (u8)((locationCaught_tmp > 255) ? 255 : locationCaught_tmp); + + LD_FIELD(u8, levelMet, 0x0e); + LD_FIELD_E(u8, ballCaughtWith, 0x0f, ItemIndex); + LD_FIELD_E(u8, OTGender, 0x10, Gender); + LD_FIELD(u8, partyData.level, 0x11); + if (partyData.level > 100) partyData.level = 100; + + LD_FIELD(u8, contestLuster, 0x12); + LD_FIELD(u8, pkrsStatus, 0x13); + LD_FIELD(u8, marksTmp, 0x14); + + LD_FIELD_E(u8, partyData.status, 0x16, PokemonStatus); + partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status; + LD_FIELD(u8, pkmFlags, 0x1d); + LD_FIELD(u32, experience, 0x20); + LD_FIELD(u16, SID, 0x24); + LD_FIELD(u16, TID, 0x26); + LD_FIELD(u32, PID, 0x28); + + OTName = new GC::PokemonString(data + 0x38, 10); + name = new GC::PokemonString(data + 0x4e, 10); + + + + LD_FIELD(u16, specialRibbonsTmp, 0x7c); + LD_ARRAY(u16, partyData.stats, 6, 0x90); + + u16 EVs_tmp[6]; // EVs are internally stored as u16 + LD_ARRAY(u16, EVs_tmp, 6, 0x9c); + for (size_t i = 0; i < 6; ++i) EVs[i] = (u8)((EVs_tmp[i] > 255) ? 255 : EVs_tmp[i]); + + LD_ARRAY(u8, IVs, 6, 0xa8); + for (size_t i = 0; i < 6; ++i) IVs[i] = (IVs[i] > 31) ? 31 : IVs[i]; + + LD_ARRAY(u8, contestStats, 6, 0xae); + LD_ARRAY_E(u8, contestAchievements, 5, 0xb3, ContestAchievementLevel); + + LD_FIELD(u16, shadowPkmID, 0xba); + + markings.load(marksTmp); + + version.load(data + 0x34); + for (size_t i = 0; i < 4; ++i) + moves[i].load(data + 0x80 + 4 * i); + + specialRibbonsTmp >>= 4; + for (size_t i = 0; i < 12; ++i) { + specialRibbons[11 - i] = (specialRibbonsTmp & 1) != 0; + specialRibbonsTmp >>= 1; + } +} + +void Pokemon::save(void) { + u16 specialRibbonsTmp = 0; + + for (size_t i = 0; i < 12; ++i) { + specialRibbonsTmp <<= 1; + specialRibbonsTmp |= (specialRibbons[i]) ? 1 : 0; + } + specialRibbonsTmp <<= 4; + + SV_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex); + SV_FIELD_E(u16, heldItem, 0x02, ItemIndex); + SV_FIELD(u16, partyData.currentHP, 0x04); + SV_FIELD(u16, (u16)happiness, 0x06); + SV_FIELD(u16, (u16)locationCaught, 0x08); + SV_FIELD(u8, levelMet, 0x0e); + SV_FIELD_E(u8, ballCaughtWith, 0x0f, ItemIndex); + SV_FIELD_E(u8, OTGender, 0x10, Gender); + + if (partyData.level > 100) partyData.level = 100; + SV_FIELD(u8, partyData.level, 0x11); + SV_FIELD(u8, contestLuster, 0x12); + SV_FIELD(u8, pkrsStatus, 0x13); + SV_FIELD(u8, markings.save(), 0x14); + + partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status; + SV_FIELD_E(u8, partyData.status, 0x16, PokemonStatus); + SV_FIELD(u8, pkmFlags, 0x1d); + SV_FIELD(u32, experience, 0x20); + SV_FIELD(u16, SID, 0x24); + SV_FIELD(u16, TID, 0x26); + SV_FIELD(u32, PID, 0x28); + + OTName->save(data + 0x38, 10); + name->save(data + 0x4e, 10); + name->save(data + 0x64, 10); + + SV_FIELD(u16, specialRibbonsTmp, 0x7c); + SV_ARRAY(u16, partyData.stats, 6, 0x90); + + u16 EVs_tmp[6]; for (size_t i = 0; i < 6; ++i) EVs_tmp[i] = (u16)EVs[i]; + SV_ARRAY(u16, EVs_tmp, 6, 0x9c); + for (size_t i = 0; i < 6; ++i) IVs[i] = (IVs[i] > 31) ? 31 : IVs[i]; + SV_ARRAY(u8, IVs, 6, 0xa8); + + + SV_ARRAY(u8, contestStats, 6, 0xae); + SV_ARRAY_E(u8, contestAchievements, 5, 0xb3, ContestAchievementLevel); + + SV_FIELD(u16, shadowPkmID, 0xba); + + version.save(data + 0x34); + for (size_t i = 0; i < 4; ++i) + moves[i].save(data + 0x80 + 4 * i); + + +} + +bool Pokemon::isEmptyOrInvalid(void) const { + return GC::Pokemon::isEmptyOrInvalid() || (pkmFlags & INVALID_PKM_FLAG) != 0; +} +bool Pokemon::hasSpecialAbility(void) const{ + return isSpecialAbilityDefined() && ((pkmFlags & SPECIAL_ABILITY_FLAG) != 0); +} + +void Pokemon::setSpecialAbilityStatus(bool status) { + status = isSpecialAbilityDefined() && status; + pkmFlags &= ~SPECIAL_ABILITY_FLAG; // reset bit 5 + pkmFlags |= (status) ? SPECIAL_ABILITY_FLAG : 0; +} + +LIBPKMGC_GC_GEN_XD_VTF(Pokemon) +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/PokemonBox.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/PokemonBox.cpp new file mode 100644 index 0000000..6435465 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/PokemonBox.cpp @@ -0,0 +1,40 @@ +#include + +namespace LibPkmGC { +namespace XD { + +PokemonBox::PokemonBox(void) : GC::PokemonBox(0x170c) { + initWithEmptyData(); +} + +PokemonBox::PokemonBox(const u8* inData) : GC::PokemonBox(0x170c, inData) { + load(); +} + +PokemonBox::PokemonBox(PokemonBox const& other) : GC::PokemonBox(other) {} +PokemonBox::~PokemonBox(void) +{ +} + + + +PokemonBox* PokemonBox::clone(void) const { + return new PokemonBox(*this); +} + +PokemonBox* PokemonBox::create(void) const { + return new PokemonBox; +} + +void PokemonBox::loadFields(void) { + GC::PokemonBox::loadFields(); + LD_SUBSTRUCTURE_ARRAY(Pokemon, pkm, 30, 0x14); +} + +void PokemonBox::save(void) { + GC::PokemonBox::save(); + SV_SUBSTRUCTURE_ARRAY(Pokemon, pkm, 30, 0x14); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/PurificationChamber.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/PurificationChamber.cpp new file mode 100644 index 0000000..6bc1916 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/PurificationChamber.cpp @@ -0,0 +1,66 @@ +#include + +namespace LibPkmGC { +namespace XD { + +PurificationChamber::PurificationChamber(void) : Base::DataStruct(0x3d8) { + initWithEmptyData(); +} + +PurificationChamber::PurificationChamber(const u8* inData) : Base::DataStruct(0x3d8, inData) { + load(); +} + + +void PurificationChamber::deleteFields(void) { + for (size_t i = 0; i < 4; ++i) delete normalPkm[i]; + delete shadowPkm; +} + +PurificationChamber::~PurificationChamber(void) { + PurificationChamber::deleteFields(); +} + +PurificationChamber::PurificationChamber(PurificationChamber const & other) : Base::DataStruct(other) { + CL_ARRAY(normalPkm, 4); + CL(shadowPkm); +} + +PurificationChamber & PurificationChamber::operator=(PurificationChamber const & other) { + if (this != &other) { + Base::DataStruct::operator=(other); + PurificationChamber::deleteFields(); + CL_ARRAY(normalPkm, 4); + CL(shadowPkm); + } + return *this; +} + +void PurificationChamber::swap(PurificationChamber & other) { + Base::DataStruct::swap(other); + SW_ARRAY(normalPkm, 4); + SW(shadowPkm); +} + +PurificationChamber* PurificationChamber::clone(void) const { + return new PurificationChamber(*this); +} + +PurificationChamber* PurificationChamber::create(void) const { + return new PurificationChamber; +} + +void PurificationChamber::loadFields(void) { + LD_SUBSTRUCTURE_ARRAY(Pokemon, normalPkm, 4, 0); + LD_SUBSTRUCTURE(Pokemon, shadowPkm, 0x310); +} + +void PurificationChamber::save(void) { + SV_SUBSTRUCTURE_ARRAY(Pokemon, normalPkm, 4, 0); + SV_SUBSTRUCTURE(Pokemon, shadowPkm, 0x310); + + std::fill(data + 0x3d5, data + 0x3d8, 0); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/PurifierData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/PurifierData.cpp new file mode 100644 index 0000000..23740d0 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/PurifierData.cpp @@ -0,0 +1,57 @@ +#include + +namespace LibPkmGC { +namespace XD { + +PurifierData::PurifierData(void) : Base::DataStruct(0x2298) { + initWithEmptyData(); +} + +PurifierData::PurifierData(const u8* inData) : Base::DataStruct(0x2298, inData) { + load(); +} + + +void PurifierData::deleteFields(void) { + for (size_t i = 0; i < 9; ++i) delete chambers[i]; +} + +PurifierData::~PurifierData(void) { + PurifierData::deleteFields(); +} + +PurifierData::PurifierData(PurifierData const & other) : Base::DataStruct(other) { + CL_ARRAY(chambers, 9); +} + +PurifierData & PurifierData::operator=(PurifierData const & other){ + Base::DataStruct::operator=(other); + if (this != &other) { + CL_ARRAY(chambers, 9); + } + return *this; +} + +void PurifierData::swap(PurifierData & other) { + Base::DataStruct::swap(other); + SW_ARRAY(chambers, 9); +} + +PurifierData* PurifierData::clone(void) const { + return new PurifierData(*this); +} + +PurifierData* PurifierData::create(void) const { + return new PurifierData; +} + +void PurifierData::loadFields(void) { + LD_SUBSTRUCTURE_ARRAY(PurificationChamber, chambers, 9, 0); +} + +void PurifierData::save(void) { + SV_SUBSTRUCTURE_ARRAY(PurificationChamber, chambers, 9, 0); +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoData.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoData.cpp new file mode 100644 index 0000000..e4bc340 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoData.cpp @@ -0,0 +1,48 @@ +#include + +namespace LibPkmGC { +namespace XD { + +StrategyMemoData::StrategyMemoData(void) : GC::StrategyMemoData(0x1774) { + initWithEmptyData(); +} + +StrategyMemoData::StrategyMemoData(const u8* inData) : GC::StrategyMemoData(0x1774, inData) { + load(); +} + +StrategyMemoData::StrategyMemoData(StrategyMemoData const& other) : GC::StrategyMemoData(other) {} + + +bool StrategyMemoData::isXD(void) const { + return true; +} + +StrategyMemoData* StrategyMemoData::clone(void) const +{ + return new StrategyMemoData(*this); +} + +StrategyMemoData* StrategyMemoData::create(void) const +{ + return new StrategyMemoData; +} + +void StrategyMemoData::loadFields(void) { + GC::StrategyMemoData::loadFields(); + LD_SUBSTRUCTURE_ARRAY(StrategyMemoEntry, entries, 500, 4); +} + +void StrategyMemoData::save(void) { + GC::StrategyMemoData::save(); + SV_SUBSTRUCTURE_ARRAY(StrategyMemoEntry, entries, 500, 4); + +} + + +StrategyMemoData::~StrategyMemoData(void) +{ +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoEntry.cpp b/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoEntry.cpp new file mode 100644 index 0000000..e3992cf --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/Common/StrategyMemoEntry.cpp @@ -0,0 +1,38 @@ +#include + +namespace LibPkmGC { +namespace XD { + +StrategyMemoEntry::~StrategyMemoEntry(void) { +} + +StrategyMemoEntry::StrategyMemoEntry(void) : GC::StrategyMemoEntry() { + initWithEmptyData(); +} + +StrategyMemoEntry::StrategyMemoEntry(const u8* inData) : GC::StrategyMemoEntry(inData) { + load(); +} + +bool StrategyMemoEntry::isXD(void) const { + return true; +} + +StrategyMemoEntry* StrategyMemoEntry::clone(void) const { + return new StrategyMemoEntry(*this); +} + +StrategyMemoEntry* StrategyMemoEntry::create(void) const { + return new StrategyMemoEntry; +} + +bool StrategyMemoEntry::isInfoPartial(void) const{ + return false; +} + +void StrategyMemoEntry::setInfoCompleteness(bool partial){ + flags = (species == NoSpecies) ? 0 : 2; +} + +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/SaveEditing/Save.cpp b/LibPkmGC/src/LibPkmGC/XD/SaveEditing/Save.cpp new file mode 100644 index 0000000..18048b7 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/SaveEditing/Save.cpp @@ -0,0 +1,60 @@ +#include + +namespace LibPkmGC { +namespace XD { +namespace SaveEditing { + + +Save::Save(void) : GC::SaveEditing::Save(0x56000, 2) { + initWithEmptyData(); +} + +Save::Save(const u8* inData, bool hasGCIData_, bool isDecrypted) : GC::SaveEditing::Save(0x56000, 2, inData, hasGCIData_) { + load((isDecrypted) ? 1 : 0); +} + +Save::Save(Save const& other) : GC::SaveEditing::Save(other) {} + +Save* Save::clone(void) const { + return new Save(*this); +} + +Save* Save::create(void) const { + return new Save; +} + +/* + 0x0000 -- 0x6000: save file title + icon (ignored here) + 0x6000: SaveSlot saveSlots[2] +*/ +void Save::loadFields(void) { + // deleteFields(); + + saveSlots = new GC::SaveEditing::SaveSlot*[2]; + u8* start = data + 0x6000; + /*delete saveSlots[0]; + delete saveSlots[1];*/ + saveSlots[0] = new SaveSlot(start, _is_decrypted); + saveSlots[1] = new SaveSlot(start + 0x28000, _is_decrypted); +} + +void Save::save(void) { + SV_SUBSTRUCTURE_ARRAY(SaveSlot, saveSlots, 2, 0x6000); +} + +void Save::saveUnshuffled(void) { + //nb_saveSlots = 2; + for (size_t i = 0; i < 2; ++i) { + SaveSlot* slot = (SaveSlot*)saveSlots[i]; + slot->saveUnshuffled(); + } + + u8* start = data + 0x6000; + + std::copy(saveSlots[0]->data, saveSlots[0]->data + 0x28000, start); + std::copy(saveSlots[1]->data, saveSlots[1]->data + 0x28000, start + 0x28000); +} + +} +} +} \ No newline at end of file diff --git a/LibPkmGC/src/LibPkmGC/XD/SaveEditing/SaveSlot.cpp b/LibPkmGC/src/LibPkmGC/XD/SaveEditing/SaveSlot.cpp new file mode 100644 index 0000000..851d9e7 --- /dev/null +++ b/LibPkmGC/src/LibPkmGC/XD/SaveEditing/SaveSlot.cpp @@ -0,0 +1,363 @@ +#include + +namespace LibPkmGC { +namespace XD { +namespace SaveEditing { + + +static const s8 substructureOrder[16] = { 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,15,14 }; +static const u16 substructureMaxSizes[16] = /* default sizes */ +{ + 0x88, 0x978, 0xbc50, 0x4a, 0xcc, 0x1774, + 0x364, 0x2400, 0x6b4, 0xb, 0x400, 0x800, 0x1000, 0x2000, + 0x2298, 0xc800 +}; +static const u16 substructureOffsetIncrements[16] = +{ + 0xa0, 0x990, 0xbc60, 0x60, 0xe0, 0x1790, + 0x380, 0x2410, 0x6d0, 0x20, 0x410, 0x810, + 0x1010, 0x2010, 0x22b0, 0xc810 +}; + +inline void advanceKeys(u16 keys[4]) { + u16 a = keys[0] + 0x43, b = keys[1] + 0x29, c = keys[2] + 0x17, d = keys[3] + 0x13; + + keys[0] = (a & 0xf) | ((b << 4) & 0xf0) | ((c << 8) & 0xf00) | ((d << 12) & 0xf000); + keys[1] = ((a >> 4) & 0xf) | (b & 0xf0) | ((c << 4) & 0xf00) | ((d << 8) & 0xf000); + keys[2] = (c & 0xf00) | ((b & 0xf00) >> 4) | ((a & 0xf00) >> 8) | ((d << 4) & 0xf000); + keys[3] = ((a >> 12) & 0xf) | ((b >> 8) & 0xf0) | ((c >> 4) & 0xf00) | (d & 0xf000); +} + +inline void decrypt_impl(u8* in, u8* out, u16 encryptionKeys[4]) { //the encryption algorithm isn't really strong, isn't it? + using namespace IntegerManip::BE; + u32 end = 0x27fd8; + u16 keys[4] = { 0 }; + std::copy(encryptionKeys, encryptionKeys + 4, keys); + u16 tmp = 0; + + for (size_t i = 16; i < end; i += 8) { + for (size_t j = 0; j < 4; ++j) { + tmp = toInteger(in + i + 2 * j, 2); + tmp -= keys[j]; + fromInteger(out + i + 2 * j, tmp, 2); + } + advanceKeys(keys); + } +} + +inline void encrypt_impl(u8* in, u8* out, const u16 encryptionKeys[4], u32 end = 0x27fd8) { + using namespace IntegerManip::BE; + + u16 keys[4] = { 0 }; + std::copy(encryptionKeys, encryptionKeys + 4, keys); + u16 tmp = 0; + + for (size_t i = 16; i < end; i += 8) { + for (size_t j = 0; j < 4; ++j) { + tmp = toInteger(in + i + 2 * j, 2); + tmp += keys[j]; + fromInteger(out + i + 2 * j, tmp, 2); + } + advanceKeys(keys); + } +} + + + + +SaveSlot::SaveSlot(void) : GC::SaveEditing::SaveSlot(0x28000, 40) { + initWithEmptyData(1); +} + + +SaveSlot::SaveSlot(const u8* inData, bool isDecrypted) : GC::SaveEditing::SaveSlot(0x28000, 40, inData) { + u32 flags = (isDecrypted) ? 1 : 0; + load(flags); +} + +SaveSlot::SaveSlot(SaveSlot const& other) : GC::SaveEditing::SaveSlot(other) { + CP_ARRAY(checksum, 4); + CP_ARRAY(encryptionKeys, 4); + CP_ARRAY(substructureOffsets, 16); + + + + CL(purifier); + + CP(_other_corruption_flags); + for (size_t i = 0; i < 16; ++i) { + if (other.unhandledSubstructures[i] != NULL) unhandledSubstructures[i] = other.unhandledSubstructures[i]->clone(); + else unhandledSubstructures[i] = NULL; + } +} + +void SaveSlot::deleteFields(void) { + GC::SaveEditing::SaveSlot::deleteFields(); + _deleteFields_extension(); +} + +SaveSlot::~SaveSlot(void) { + _deleteFields_extension(); +} + +SaveSlot* SaveSlot::clone(void) const { + return new SaveSlot(*this); +} + +SaveSlot* SaveSlot::create(void) const { + return new SaveSlot; +} + +void SaveSlot::swap(SaveSlot& other) { + GC::SaveEditing::SaveSlot::swap(other); + SW_ARRAY(encryptionKeys, 4); + SW_ARRAY(checksum, 4); + + SW_ARRAY(substructureOffsets, 16); + SW_ARRAY(unhandledSubstructures, 16); + + SW(purifier); +} + +SaveSlot& SaveSlot::operator=(SaveSlot const & other) { + GC::SaveEditing::SaveSlot::operator=(other); + if (this != &other) { + CP_ARRAY(checksum, 4); + CP_ARRAY(encryptionKeys, 4); + CP_ARRAY(substructureOffsets, 16); + for (size_t i = 0; i < 16; ++i) { + if (other.unhandledSubstructures[i] != NULL) unhandledSubstructures[i] = other.unhandledSubstructures[i]->clone(); + else unhandledSubstructures[i] = NULL; + } + CL(purifier); + } + return *this; +} + +void SaveSlot::loadData(u32 flags) { + bool decrypted = (flags & 1) == 1; + + LD_ARRAY(u16, encryptionKeys, 4, 8); + + if (!decrypted) decrypt_impl(data, data, encryptionKeys); +} + + +void SaveSlot::loadFields(void) { + randomBytes = new u8[40]; + LD_FIELD_E(u32, magic, 0, SaveMagic); + LD_FIELD(s32, saveCount, 4); + u16 checksum_tmp[8]; + LD_ARRAY(u16, checksum_tmp, 8, 0x10); + + std::reverse(checksum_tmp, checksum_tmp + 8); + + for (size_t i = 0; i < 4; ++i) + checksum[i] = ((u32)checksum_tmp[2 * i] << 16) | (u32)checksum_tmp[2 * i + 1]; + + + u16 substructureSizes[16], substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones + LD_ARRAY(u16, substructureSizes, 16, 0x20); + LD_ARRAY(u16, substructureOffsetsTmp, 32, 0x40); + + u8* start = data + 8 + 0xa0; + for (size_t i = 0; i < 16; ++i) + substructureOffsets[i] = (substructureOffsetsTmp[2 * i + 1] << 16) | substructureOffsetsTmp[2 * i]; + + _other_corruption_flags = substructureSizes[0] != 0x88; + for (size_t i = 0; i < 16; ++i) { + s8 subscript = substructureOrder[i]; // substructure order if unshuffled + + if ((subscript <= 6) || (subscript == 14)) { + unhandledSubstructures[i] = NULL; + continue; + } + + // the game uses the following condition instead : substructureSizes[n] = max(substructureSizes[n], substructureMaxSizes[n]); we won't +#define COND(n) substructureSizes[n] != substructureMaxSizes[n] || substructureOffsets[n] + 0xa8 >= size + + if (COND(i)) + unhandledSubstructures[i] = new Base::UnimplementedStruct(substructureMaxSizes[i]); + else + unhandledSubstructures[i] = new Base::UnimplementedStruct(substructureMaxSizes[i], start + substructureOffsets[i]); + } + +#define LD_IMPLEMENTED_SUBSTRUCTURE(type, field, id) if(COND(id))\ + field = new type;\ + else\ + field = new type(start + substructureOffsets[id]); + + LD_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player, 1); + LD_IMPLEMENTED_SUBSTRUCTURE(PCData, PC, 2); + LD_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox, 3); + LD_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare, 4); + LD_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo, 5); + LD_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode, 6); + LD_IMPLEMENTED_SUBSTRUCTURE(PurifierData, purifier, 14); + + version.load(start); + LD_ARRAY(u32, memcardUID, 2, 0xa8 + 8); + LD_FIELD_B(u8, noRumble, 0xa8 + 0x29); + LD_FIELD_E(u16, titleScreenLanguage, 0xa8 + 0x2a, LanguageIndex); + LD_FIELD(s32, headerChecksum, 0xa8 + 0x38); + + std::copy(data + size - 40, data + size, randomBytes); +} + +bool SaveSlot::checkChecksum(bool fix) { + using namespace IntegerManip::BE; + u32 new_checksum[4] = { 0 }; + + u8 tmpbuf[0x10]; + std::copy(data + 0x10, data + 0x20, tmpbuf); + std::fill(data + 0x10, data + 0x20, 0); + + u8* dt = data + 0x08; + + for (size_t i = 0; i < 4; ++i) { + for (size_t j = 0; j < 0x9ff4; j += 2) { + new_checksum[i] += (u32)toInteger(dt, 2); + dt += 2; + } + } + + bool ret = std::equal(checksum, checksum + 4, new_checksum); + + if (!ret && fix) std::copy(new_checksum, new_checksum + 4, checksum); + + std::copy(tmpbuf, tmpbuf + 0x10, data + 0x10); + return ret; +} + +bool SaveSlot::checkHeaderChecksum(bool fix) { + s32 new_header_checksum = 0; + for (size_t i = 0; i < 8; ++i) new_header_checksum += (s32)(u32)data[i]; + + bool ret = new_header_checksum == headerChecksum; + if (!ret && fix) headerChecksum = new_header_checksum; + + return ret; +} + +std::pair SaveSlot::checkBothChecksums(bool fixGlobalChecksum, bool fixHeaderChecksum) { + if (!fixGlobalChecksum || !fixHeaderChecksum) return std::pair(checkChecksum(fixGlobalChecksum), checkHeaderChecksum(fixHeaderChecksum)); + else { + bool first, second; + s32 oldHC = headerChecksum; + first = checkHeaderChecksum(true); + SV_FIELD(s32, headerChecksum, 0xa8 + 0x38); + second = checkChecksum(true); + SV_FIELD(s32, oldHC, 0xa8 + 0x38); + return std::pair(first, second); + } +} + +bool SaveSlot::isCorrupt(void) { + if (((static_cast(magic) & 0xffffff00) != (u32)XDMagic) || _other_corruption_flags) return true; // substructureSizes[0] != 0x88; + std::pair chk = checkBothChecksums(); + return !chk.first || !chk.second; +} + +void SaveSlot::save(void) { + magic = XDMagic; + + u8* start = data + 8 + 0xa0; + + SV_FIELD_E(u32, XDMagic, 0, SaveMagic); + SV_FIELD(s32, saveCount, 4); + SV_ARRAY(u16, encryptionKeys, 4, 8); + + std::copy(randomBytes, randomBytes + 40, data + size - 40); + + + std::fill(start + substructureMaxSizes[0], data + size, 0); // clean the filler bytes + + for (size_t i = 0; i < 16; ++i) { + if (unhandledSubstructures[i] == NULL) continue; + std::copy(unhandledSubstructures[i]->data, unhandledSubstructures[i]->data + substructureMaxSizes[i], start + substructureOffsets[i]); + } + +#define SV_IMPLEMENTED_SUBSTRUCTURE(type, field, id) field->save(); std::copy(field->data, field->data + substructureMaxSizes[id], start + substructureOffsets[id]); + + SV_IMPLEMENTED_SUBSTRUCTURE(PlayerData, player, 1); + SV_IMPLEMENTED_SUBSTRUCTURE(PCData, PC, 2); + SV_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox, 3); + SV_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare, 4); + SV_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo, 5); + SV_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode, 6); + SV_IMPLEMENTED_SUBSTRUCTURE(PurifierData, purifier, 14); + + + + u16 substructureSizes[16], substructureOffsetsTmp[32]; // the upper 16 bits of each offset are stored AFTER the lower ones + std::copy(substructureMaxSizes, substructureMaxSizes + 16, substructureSizes); + SV_ARRAY(u16, substructureSizes, 16, 0x20); + _other_corruption_flags = false; + + + for (size_t i = 0; i < 16; ++i) { + substructureOffsetsTmp[2 * i] = (u16)substructureOffsets[i]; + substructureOffsetsTmp[2 * i + 1] = (u16)(substructureOffsets[i] >> 16); + } + + SV_ARRAY(u16, substructureOffsetsTmp, 32, 0x40); + + + version.save(start); + SV_ARRAY(u32, memcardUID, 2, 0xa8 + 8); + SV_FIELD_B(u8, noRumble, 0xa8 + 0x29); + SV_FIELD_E(u16, titleScreenLanguage, 0xa8 + 0x2a, LanguageIndex); + + checkHeaderChecksum(true); + SV_FIELD(u32, headerChecksum, 0xa8 + 0x38); + + checkChecksum(true); + + u16 checksum_tmp[8]; + + for (size_t i = 0; i < 4; ++i) { + checksum_tmp[2 * i] = (u16)(checksum[i] >> 16); + checksum_tmp[2 * i + 1] = (u16)checksum[i]; + } + std::reverse(checksum_tmp, checksum_tmp + 8); + SV_ARRAY(u16, checksum_tmp, 8, 0x10); + +} + + +void SaveSlot::reorderSubstructures(void) { + u32 offset = 0; + for (size_t i = 0; i < 16; ++i) { + s8 subscript = substructureOrder[i]; + if (subscript == -1) continue; + substructureOffsets[(size_t)subscript] = offset; + offset += substructureOffsetIncrements[(size_t)subscript]; + } + + for (size_t i = 10; i < 14; ++i) { + substructureOffsets[i] = offset; + offset += substructureOffsetIncrements[i]; + } +} + +void SaveSlot::saveUnshuffled(void) { + reorderSubstructures(); + save(); +} + +void SaveSlot::saveEncrypted(u8* outBuf) { + save(); + std::copy(data, data + 0x10, outBuf); + std::copy(data + 0x28000 - 40, data + 0x28000, outBuf + 0x28000 - 40); + encrypt_impl(data, outBuf, encryptionKeys); +} + +void SaveSlot::_deleteFields_extension(void) { + for (size_t i = 0; i < 16; ++i) delete unhandledSubstructures[i]; + delete purifier; + //delete groupBattleRules; +} + +} +} +} \ No newline at end of file diff --git a/PkmGCSaveEditor/CMakeLists.txt b/PkmGCSaveEditor/CMakeLists.txt new file mode 100644 index 0000000..7abf880 --- /dev/null +++ b/PkmGCSaveEditor/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 2.8.12) +project(PkmGCSaveEditor) + +# Include generated moc files +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# Instruct CMake to run moc automatically when needed. +set(CMAKE_AUTOMOC ON) + +find_package(Qt5Widgets) +find_package(Qt5LinguistTools OPTIONAL) + +file(GLOB_RECURSE source_files src/*) + +include_directories(${LIBPKMGC_INCLUDE_DIRS} src/) + +add_executable(PkmGCSaveEditor WIN32 ${source_files}) +target_link_libraries(PkmGCSaveEditor LibPkmGC Qt5::Widgets) + +set(PKMGCSAVEEDITOR_SUPPORTED_LANGUAGES en fr CACHE INTERNAL "PkmGCSaveEditor's supported languages" FORCE) + +if(Qt5LinguistTools_FOUND) + unset(PKMGCSAVEEDITOR_TRANSLATION_FILES) + get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + execute_process(COMMAND ${QT5_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT5_QM_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + foreach(language ${PKMGCSAVEEDITOR_SUPPORTED_LANGUAGES}) + list(APPEND PKMGCSAVEEDITOR_TRANSLATION_FILES translations/PkmGCSaveEditor_${language}.ts) + if(EXISTS ${QT5_QM_DIR}/qt_${language}.qm) # qt_en.qm does not exist + list(APPEND QT5_TRANSLATION_QM ${QT5_QM_DIR}/qt_${language}.qm) + elseif(EXISTS translations/qt/qt_${language}.qm) + list(APPEND QT5_TRANSLATION_QM translations/qt/qt_${language}.qm) + endif() + + if(EXISTS ${QT5_QM_DIR}/qtbase_${language}.qm) + list(APPEND QT5_TRANSLATION_QM ${QT5_QM_DIR}/qtbase_${language}.qm) # Required for Qt > 5.3 + elseif(EXISTS translations/qt/qtbase_${language}.qm) + list(APPEND QT5_TRANSLATION_QM translations/qt/qtbase_${language}.qm) + endif() + endforeach() + list(REMOVE_DUPLICATES QT5_TRANSLATION_QM) + set(QT5_TRANSLATION_QM ${QT5_TRANSLATION_QM} CACHE INTERNAL "Qt5 *.qm") + + set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1) # prevent make clean from removing TS files + + qt5_create_translation(TRANSLATION_MESSAGES ${source_files} ${PKMGCSAVEEDITOR_TRANSLATION_FILES}) + qt5_add_translation(TRANSLATION_QM ${PKMGCSAVEEDITOR_TRANSLATION_FILES}) + add_custom_target(PkmGCSaveEditor_translations_update DEPENDS ${TRANSLATION_MESSAGES}) + add_custom_target(PkmGCSaveEditor_translations DEPENDS ${TRANSLATION_QM}) + + install(FILES ${TRANSLATION_QM} DESTINATION Debug/bin/languages CONFIGURATIONS Debug) + install(FILES ${TRANSLATION_QM} DESTINATION Release/bin/languages CONFIGURATIONS Release RelWithDebInfo MinSizeRel) +endif() + + +# DLL hell + + +if(NOT WIN32 AND NOT COPY_QT_LIBS_UNIX) + set(COPY_QT_LIBS OFF) +else() + set(COPY_QT_LIBS ON) +endif() + +if(COPY_QT_LIBS) + get_target_property(qt_libs Qt5::Widgets INTERFACE_LINK_LIBRARIES) + get_target_property(qt_widgets_location Qt5::Widgets LOCATION_Release) + list(APPEND QT5_RUNTIME_RELEASE ${qt_widgets_location}) + foreach(qt_lib ${qt_libs}) + get_target_property(qt_lib_location ${qt_lib} LOCATION_Release) + list(APPEND QT5_RUNTIME_RELEASE ${qt_lib_location}) + endforeach() + list(REMOVE_DUPLICATES QT5_RUNTIME_RELEASE) + set(QT5_RUNTIME_RELEASE ${QT5_RUNTIME_RELEASE} CACHE INTERNAL "Qt5 release libraries" FORCE) + + get_target_property(qt_libs Qt5::Widgets INTERFACE_LINK_LIBRARIES) + get_target_property(qt_widgets_location Qt5::Widgets LOCATION_Debug) + list(APPEND QT5_RUNTIME_DEBUG ${qt_widgets_location}) + foreach(qt_lib ${qt_libs}) + get_target_property(qt_lib_location ${qt_lib} LOCATION_Debug) + list(APPEND QT5_RUNTIME_DEBUG ${qt_lib_location}) + endforeach() + + list(REMOVE_DUPLICATES QT5_RUNTIME_DEBUG) + + set(QT5_RUNTIME_DEBUG ${QT5_RUNTIME_DEBUG} CACHE INTERNAL "Qt5 debug libraries" FORCE) + +endif() + +install(PROGRAMS $ DESTINATION Debug/bin CONFIGURATIONS Debug) +install(PROGRAMS $ DESTINATION Release/bin CONFIGURATIONS Release RelWithDebInfo MinSizeRel) diff --git a/PkmGCSaveEditor/src/Core/DataUI.cpp b/PkmGCSaveEditor/src/Core/DataUI.cpp new file mode 100644 index 0000000..b924d3c --- /dev/null +++ b/PkmGCSaveEditor/src/Core/DataUI.cpp @@ -0,0 +1,23 @@ +#include + +DataUI::DataUI(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f), IDataUI(), mainLayout(new QVBoxLayout), +dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)) { + connect(dialogButtonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(dialogButtonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +void DataUI::accept(void) { + saveChanges(); + changesMade = true; + QDialog::accept(); +} + +void DataUI::reject(void) { + cancelChanges(); + QDialog::reject(); +} + +void DataUI::initWidget(void) { + mainLayout->addWidget(dialogButtonBox); + this->setLayout(mainLayout); +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/DataUI.h b/PkmGCSaveEditor/src/Core/DataUI.h new file mode 100644 index 0000000..9ae20b9 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/DataUI.h @@ -0,0 +1,28 @@ +#ifndef _PKMGCSAVEEDITOR_DATA_UI_H +#define _PKMGCSAVEEDITOR_DATA_UI_H + +#include +#include +#include +#include +#include + +class DataUI : public QDialog, public IDataUI { + Q_OBJECT + +public: + DataUI(QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + +public slots: + void accept(void); + void reject(void); +protected: + bool isXD; + + void initWidget(void); + + QVBoxLayout *mainLayout; + QDialogButtonBox *dialogButtonBox; +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/Globals.cpp b/PkmGCSaveEditor/src/Core/Globals.cpp new file mode 100644 index 0000000..3b94733 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/Globals.cpp @@ -0,0 +1,35 @@ +#include + +QString currentSaveFileName; +LibPkmGC::GC::SaveEditing::Save* currentSave = NULL; +LibPkmGC::GC::SaveEditing::SaveSlot* currentSaveSlot = NULL; +bool ignoreDataCorruption = false; +QString interfaceLanguage = ""; +LibPkmGC::LanguageIndex dumpedNamesLanguage = LibPkmGC::NoLanguage; +bool changesMade = false; +QString lastPkmDirectory = ""; +QString lastSaveDirectory = ""; + + +inline QMap gen_lang_map(void) { + QMap ret; + ret["auto"] = (size_t)LibPkmGC::NoLanguage; + ret["ja"] = (size_t)LibPkmGC::Japanese; + ret["en"] = (size_t)LibPkmGC::English; + ret["de"] = (size_t)LibPkmGC::German; + ret["fr"] = (size_t)LibPkmGC::French; + ret["it"] = (size_t)LibPkmGC::Italian; + ret["es"] = (size_t)LibPkmGC::Spanish; + return ret; +} + +const QMap languageCodeToIndexMap = gen_lang_map(); + +LibPkmGC::LanguageIndex generateDumpedNamesLanguage(void) { + if (dumpedNamesLanguage != LibPkmGC::NoLanguage) return dumpedNamesLanguage; + + QString lg = interfaceLanguage; + LibPkmGC::LanguageIndex ret = (LibPkmGC::LanguageIndex) languageCodeToIndexMap.value(lg, (size_t)LibPkmGC::English); + if (ret > LibPkmGC::Spanish) ret = LibPkmGC::English; + return ret; +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/Globals.h b/PkmGCSaveEditor/src/Core/Globals.h new file mode 100644 index 0000000..1a01b86 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/Globals.h @@ -0,0 +1,30 @@ +#ifndef _PKMGCSAVEEDITOR_GLOBALS_H +#define _PKMGCSAVEEDITOR_GLOBALS_H + +#define PKMGCSAVEEDITOR_VERSION 1000000 +#define PKMGCSAVEEDITOR_VERSION_MAJOR ((PKMGCSAVEEDITOR_VERSION / 1000000) % 1000) +#define PKMGCSAVEEDITOR_VERSION_MINOR ((PKMGCSAVEEDITOR_VERSION / 1000) % 1000) +#define PKMGCSAVEEDITOR_VERSION_BUILD (PKMGCSAVEEDITOR_VERSION % 1000) + +#include +#include +#include +#include +#include +#include + +extern const QMap languageCodeToIndexMap; + +extern QString currentSaveFileName; +extern LibPkmGC::GC::SaveEditing::Save* currentSave; +extern LibPkmGC::GC::SaveEditing::SaveSlot* currentSaveSlot; +extern bool ignoreDataCorruption; +extern QString interfaceLanguage; +extern LibPkmGC::LanguageIndex dumpedNamesLanguage; +extern bool changesMade; +extern QString lastPkmDirectory; +extern QString lastSaveDirectory; + +LibPkmGC::LanguageIndex generateDumpedNamesLanguage(void); + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/IDataUI.h b/PkmGCSaveEditor/src/Core/IDataUI.h new file mode 100644 index 0000000..eb1a721 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/IDataUI.h @@ -0,0 +1,21 @@ +#ifndef _PKMGCSAVEEDITOR_I_DATA_UI_H +#define _PKMGCSAVEEDITOR_I_DATA_UI_H + +#include +#include + +class IDataUI { +public: + virtual void parseData(void) = 0; + virtual void saveChanges(void) = 0; + virtual void cancelChanges(void) {} +protected: + + virtual void init(void) { + initWidget(); + parseData(); + } + virtual void initWidget(void) = 0; +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/ItemComboBox.cpp b/PkmGCSaveEditor/src/Core/ItemComboBox.cpp new file mode 100644 index 0000000..45237bd --- /dev/null +++ b/PkmGCSaveEditor/src/Core/ItemComboBox.cpp @@ -0,0 +1,77 @@ +#include + +using namespace LibPkmGC; +using namespace LibPkmGC::Localization; + +ItemComboBox::ItemComboBox(unsigned int inFlags, bool isXD, QWidget* parent) : QComboBox(parent), _flags(inFlags), _isXD(isXD){ + _indices = new ItemIndex[336]; // 245 + 91 + _reverseIndices = new int[594]; + resetItemList(); +} + +ItemComboBox::~ItemComboBox(void){ + delete[] _indices; + delete[] _reverseIndices; +} + +void ItemComboBox::resetItemList(void){ + this->clear(); + LanguageIndex lg = generateDumpedNamesLanguage(); + int j = 0; + _flags = (_flags == EMPTY_ITEM_FORBIDDEN) ? 0 : _flags; + unsigned int fl = _flags; + if ((_flags & EMPTY_ITEM_FORBIDDEN) == 0) { + this->addItem(getItemName(lg, NoItem, _isXD)); + _reverseIndices[0] = 0; + _indices[j++] = NoItem; + } + else { + _reverseIndices[0] = -1; + } + fl &= ~1; // since (1 << (getItemCategory() )) == 1 ... + + for (int i = 1; i <= (int)BattleCD60; ++i) { // 593 + unsigned int ctgFlg = (1U << (int)getItemCategory((ItemIndex)i, _isXD)); + if ((fl & ctgFlg) != 0) { + this->addItem(getItemName(lg, (ItemIndex)i, _isXD)); + _reverseIndices[i] = j; + _indices[j++] = (ItemIndex)i; + } + else { + _reverseIndices[i] = -1; + } + } +} + +ItemIndex ItemComboBox::currentItemIndex(void) const{ + return _indices[this->currentIndex()]; +} + +void ItemComboBox::setCurrentItemIndex(ItemIndex index){ + if ((index > BattleCD60) || (_reverseIndices[(size_t)index] == -1)) this->setCurrentIndex(0); + else this->setCurrentIndex(_reverseIndices[(size_t)index]); +} + +unsigned int ItemComboBox::flags(void) const{ + return _flags; +} + +void ItemComboBox::setFlags(unsigned int inFlags){ + _flags = inFlags; + resetItemList(); +} + +bool ItemComboBox::version(void) const{ + return _isXD; +} + +void ItemComboBox::setVersion(bool isXD){ + _isXD = isXD; + resetItemList(); +} + +void ItemComboBox::set(unsigned int inFlags, bool isXD){ + _flags = inFlags; + _isXD = isXD; + resetItemList(); +} diff --git a/PkmGCSaveEditor/src/Core/ItemComboBox.h b/PkmGCSaveEditor/src/Core/ItemComboBox.h new file mode 100644 index 0000000..4e90898 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/ItemComboBox.h @@ -0,0 +1,45 @@ +#ifndef _PKMGCSAVEEDITOR_ITEM_COMBO_BOX_H +#define _PKMGCSAVEEDITOR_ITEM_COMBO_BOX_H + +#include +#include +#include + +// (1 << ((int)categoryIndex) +#define EMPTY_ITEM_FORBIDDEN 1 + +#define POKEBALLS_ALLOWED 2 +#define REGULAR_ITEMS_ALLOWED 4 // This includes PokéSnacks and Time flutes +#define BERRIES_ALLOWED 8 +#define TMS_ALLOWED 16 +#define KEY_ITEMS_ALLOWED 32 +#define COLOGNES_ALLOWED 64 +#define BATTLE_CDS_ALLOWED 128 + +#define GIVABLE_ITEMS_ALLOWED 30 // (2|4|8|16) + +class ItemComboBox : public QComboBox { +public: + ItemComboBox(unsigned int inFlags = 0, bool isXD = false, QWidget* parent = NULL); + ~ItemComboBox(void); + + void resetItemList(void); + LibPkmGC::ItemIndex currentItemIndex(void) const; + void setCurrentItemIndex(LibPkmGC::ItemIndex index); + + unsigned int flags(void) const; + void setFlags(unsigned int inFlags = 0); + + bool version(void) const; + void setVersion(bool isXD); + + void set(unsigned int inFlags, bool isXD); +private: + LibPkmGC::ItemIndex* _indices; + int* _reverseIndices; + unsigned int _flags; + bool _isXD; + +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/ItemPocketEditor.cpp b/PkmGCSaveEditor/src/Core/ItemPocketEditor.cpp new file mode 100644 index 0000000..d21bbe0 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/ItemPocketEditor.cpp @@ -0,0 +1,138 @@ +#include +using namespace LibPkmGC; +using namespace Localization; + +ItemPocketEditor::ItemPocketEditor(LibPkmGC::Item* inPocket, size_t inPocketMaxSize, unsigned int inFlags, bool inIsXD, QWidget* parent) : QWidget(parent), +IDataUI(), pocket(inPocket), pocketMaxSize(inPocketMaxSize), flags(inFlags), isXD(inIsXD), items(NULL) { + init(); +} + + +ItemPocketEditor::~ItemPocketEditor(void){ + delete[] items; +} + +void ItemPocketEditor::initWidget(void) { + mainLayout = new QVBoxLayout; + tbl = new QTableWidget(0, 2); + actionLayout = new QHBoxLayout; + tbl->setHorizontalHeaderLabels(QStringList(tr("Item")) << tr("Quantity")); + //tbl->horizontalHeader()->setStretchLastSection(true); + + tbl->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + tbl->verticalHeader()->hide(); + tbl->setSelectionBehavior(QAbstractItemView::SelectRows); + tbl->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); + tbl->setEditTriggers(QAbstractItemView::NoEditTriggers); + + itemNameFld = new ItemComboBox; + quantityFld = new UnsignedSpinbox<8>; + modifyButton = new QPushButton(tr("Modify")); + deleteButton = new QPushButton(tr("Delete")); + + actionLayout->addWidget(new QLabel(tr("Item"))); + actionLayout->addWidget(itemNameFld); + actionLayout->addWidget(new QLabel(tr("Quantity"))); + actionLayout->addWidget(quantityFld); + actionLayout->addWidget(modifyButton); + actionLayout->addWidget(deleteButton); + + mainLayout->addWidget(tbl); + mainLayout->addLayout(actionLayout); + this->setLayout(mainLayout); + + QShortcut* shortcut = new QShortcut(QKeySequence(QKeySequence::Delete), this); + connect(shortcut, SIGNAL(activated()), this, SLOT(deleteSelected())); + + + connect(tbl, SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)), this, SLOT(displayItem())); + connect(itemNameFld, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMaxQuantity())); + connect(modifyButton, SIGNAL(clicked(bool)), this, SLOT(modifySelected())); + connect(deleteButton, SIGNAL(clicked(bool)), this, SLOT(deleteSelected())); +} + +void ItemPocketEditor::setItemAt(int i) { + LanguageIndex lg = generateDumpedNamesLanguage(); + + QTableWidgetItem *qty = new QTableWidgetItem(QString::number(items[i].quantity)); + qty->setTextAlignment((int)Qt::AlignRight | (int)Qt::AlignVCenter); + tbl->setItem(i, 0, new QTableWidgetItem(getItemName(lg, items[i].index, isXD))); + tbl->setItem(i, 1, qty); +} + + +void ItemPocketEditor::parseData(void) { + if (pocket == NULL) return; + flags &= ~EMPTY_ITEM_FORBIDDEN; + blockSignals(true); + tbl->clearContents(); + + delete[] items; + items = new Item[pocketMaxSize]; + std::copy(pocket, pocket + pocketMaxSize, items); + + tbl->setRowCount((int)pocketMaxSize); + for (size_t i = 0; i < pocketMaxSize; ++i) + setItemAt((int)i); + itemNameFld->set(flags, isXD); + /*quantityFld->setRange(0, 0);*/ quantityFld->setDisabled(true); // (None) + blockSignals(false); +} + +void ItemPocketEditor::saveChanges(void) { + std::copy(items, items + pocketMaxSize, pocket); +} + +LibPkmGC::Item ItemPocketEditor::editedItem(void) const{ + Item item_ = { itemNameFld->currentItemIndex(), (u8) quantityFld->value() }; + return item_; +} + +void ItemPocketEditor::setEditedItem(LibPkmGC::Item const & val){ + itemNameFld->setCurrentItemIndex(val.index); + quantityFld->setValue(val.quantity); +} + +void ItemPocketEditor::updateMaxQuantity(void) { + const int maxqty[] = { 99, 99, 99, 99, 99, 99, 99, 99 }; + + //const int maxqty[] = { 0, 99, 99, 99, 99, 1, 99, 1 }; + ItemCategoryIndex ctgy = getItemCategory(itemNameFld->currentItemIndex(), isXD); + //quantityFld->setRange(0, maxqty[(size_t)ctgy]); + quantityFld->setDisabled(maxqty[(size_t)ctgy] == 0); +} +void ItemPocketEditor::displayItem(void) { + QTableWidgetItem *it = tbl->currentItem(); + setEditedItem(items[it->row()]); +} + +void ItemPocketEditor::modifySelected(void) { + // All selected items will be modified + QModelIndexList indices = tbl->selectionModel()->selectedIndexes(); + Item item_ = editedItem(); + + for (int i = 0; i < indices.count(); ++i) { + items[indices[i].row()] = item_; + setItemAt(indices[i].row()); + } +} + +void ItemPocketEditor::deleteSelected(void) { + // All selected items will be deleted + QModelIndexList indices = tbl->selectionModel()->selectedIndexes(); + Item* items2 = new Item[pocketMaxSize]; + std::fill(items2, items2 + pocketMaxSize, Item()); + + int j = 0; + for (size_t i = 0; i < pocketMaxSize; ++i) { + if (!tbl->item((int)i, 0)->isSelected()) items2[j++] = items[i]; + } + + delete[] items; + items = items2; + for (size_t i = 0; i < pocketMaxSize; ++i) + setItemAt((int)i); + displayItem(); +} + + diff --git a/PkmGCSaveEditor/src/Core/ItemPocketEditor.h b/PkmGCSaveEditor/src/Core/ItemPocketEditor.h new file mode 100644 index 0000000..9696287 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/ItemPocketEditor.h @@ -0,0 +1,51 @@ +#ifndef _PKMGCSAVEEDITOR_ITEM_POCKET_EDITOR +#define _PKMGCSAVEEDITOR_ITEM_POCKET_EDITOR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ItemPocketEditor : public QWidget, public IDataUI { + Q_OBJECT +public: + ItemPocketEditor(LibPkmGC::Item* inPocket = NULL, size_t inPocketMaxSize = 0, unsigned int inFlags = 0, bool inIsXD = false, QWidget* parent = NULL); + ~ItemPocketEditor(void); + + LibPkmGC::Item* pocket; + size_t pocketMaxSize; + unsigned int flags; + bool isXD; + + void parseData(void); + void saveChanges(void); + + LibPkmGC::Item editedItem(void) const; + void setEditedItem(LibPkmGC::Item const& val); +public slots: + void updateMaxQuantity(void); + void displayItem(void); + void modifySelected(void); + void deleteSelected(void); +protected: + void initWidget(void); +private: + void setItemAt(int i); + LibPkmGC::Item *items; + QVBoxLayout* mainLayout; + QTableWidget* tbl; + + QHBoxLayout* actionLayout; + ItemComboBox *itemNameFld; + UnsignedSpinbox<8> *quantityFld; + QPushButton *modifyButton, *deleteButton; +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/TrainerInfoLayout.cpp b/PkmGCSaveEditor/src/Core/TrainerInfoLayout.cpp new file mode 100644 index 0000000..f5c46e5 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/TrainerInfoLayout.cpp @@ -0,0 +1,70 @@ +#include + +using namespace LibPkmGC; +TrainerInfoLayout::TrainerInfoLayout(LibPkmGC::Base::PokemonString* inName, LibPkmGC::u16 inTID, LibPkmGC::u16 inSID, LibPkmGC::Gender inGender) : +QFormLayout(){ + genderLayout = new QHBoxLayout; + TIDSIDLayout = new QHBoxLayout; + genderButtonGroup = new QButtonGroup; + maleButton = new QRadioButton(tr("Male", "Trainer")); femaleButton = new QRadioButton(tr("Female", "Trainer")); + nameFld = new QLineEdit; + TIDFld = new UnsignedSpinbox<16>; SIDFld = new UnsignedSpinbox<16>; + + genderButtonGroup->addButton(maleButton, 0); + genderButtonGroup->addButton(femaleButton, 1); + + genderLayout->addWidget(maleButton); + genderLayout->addWidget(femaleButton); + + TIDSIDLayout->addWidget(TIDFld); TIDSIDLayout->addWidget(SIDFld); + + nameFld->setMaxLength(10); + this->addRow(tr("Gender", "Trainer"), genderLayout); + this->addRow(tr("Name"), nameFld); + this->addRow(tr("TID/SID"), TIDSIDLayout); + set(inName, inSID, inTID, inGender); +} + +void TrainerInfoLayout::trainerName(LibPkmGC::Base::PokemonString * outName) { + outName->fromUTF8(nameFld->text().toUtf8().data()); +} + +u16 TrainerInfoLayout::TID(void) const { + return (u16) TIDFld->value(); +} + +u16 TrainerInfoLayout::SID(void) const { + return (u16) SIDFld->value(); +} + +Gender TrainerInfoLayout::trainerGender(void) const { + return (maleButton->isChecked()) ? Male : Female; +} + +void TrainerInfoLayout::setTrainerName(LibPkmGC::Base::PokemonString* inName) { + if(inName != NULL) nameFld->setText(inName->toUTF8()); +} + +void TrainerInfoLayout::setTID(LibPkmGC::u16 inTID) { + TIDFld->setValue((int)inTID); +} + +void TrainerInfoLayout::setSID(LibPkmGC::u16 inSID) { + SIDFld->setValue((int)inSID); +} + +void TrainerInfoLayout::setTrainerGender(LibPkmGC::Gender inGender){ + maleButton->setChecked(inGender == LibPkmGC::Male); + femaleButton->setChecked(inGender == LibPkmGC::Female); +} + +void TrainerInfoLayout::set(LibPkmGC::Base::PokemonString * inName, LibPkmGC::u16 inTID, LibPkmGC::u16 inSID, LibPkmGC::Gender inGender){ + setTrainerName(inName); + setTID(inTID); + setSID(inSID); + setTrainerGender(inGender); +} + +void TrainerInfoLayout::TIDorSIDChangedEmmiter(void) { + emit TIDorSIDChanged(); +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/TrainerInfoLayout.h b/PkmGCSaveEditor/src/Core/TrainerInfoLayout.h new file mode 100644 index 0000000..9568f47 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/TrainerInfoLayout.h @@ -0,0 +1,45 @@ +#ifndef _PKMGCSAVEEDITOR_TRAINER_INFO_LAYOUT_H +#define _PKMGCSAVEEDITOR_TRAINER_INFO_LAYOUT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +class TrainerInfoLayout : public QFormLayout{ + Q_OBJECT +public: + TrainerInfoLayout(LibPkmGC::Base::PokemonString *inName = NULL, LibPkmGC::u16 inTID = 0, LibPkmGC::u16 inSID = 0, LibPkmGC::Gender inGender = LibPkmGC::Male); + + void trainerName(LibPkmGC::Base::PokemonString* outName); + LibPkmGC::u16 TID(void) const; + LibPkmGC::u16 SID(void) const; + LibPkmGC::Gender trainerGender(void) const; + + void setTrainerName(LibPkmGC::Base::PokemonString* inName); + void setTID(LibPkmGC::u16 inTID); + void setSID(LibPkmGC::u16 inSID); + void setTrainerGender(LibPkmGC::Gender inGender); + + void set(LibPkmGC::Base::PokemonString *inName = NULL, LibPkmGC::u16 inTID = 0, LibPkmGC::u16 inSID = 0, LibPkmGC::Gender inGender = LibPkmGC::Male); + +signals: + void TIDorSIDChanged(void); + +public slots: + void TIDorSIDChangedEmmiter(void); +private: + QHBoxLayout* genderLayout; + QButtonGroup* genderButtonGroup; + QRadioButton *maleButton, *femaleButton; + QLineEdit* nameFld; + QHBoxLayout* TIDSIDLayout; + UnsignedSpinbox<16> *SIDFld, *TIDFld; + +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/UnsignedSpinbox.h b/PkmGCSaveEditor/src/Core/UnsignedSpinbox.h new file mode 100644 index 0000000..a2676f5 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/UnsignedSpinbox.h @@ -0,0 +1,113 @@ +#ifndef _PKMGCSAVEEDITOR_UNSIGNED_SPINBOX_H +#define _PKMGCSAVEEDITOR_UNSIGNED_SPINBOX_H + +#include +#include +namespace{ + template struct BMask{ + static const unsigned int bitmask = (int)((1U << nb_bits) - 1); + }; + + template<> struct BMask<32>{ + static const unsigned int bitmask = 0xffffffff; // to avoid compiler warnings + }; +} + +template // nb_bits must be <= 32 +class UnsignedSpinbox : public QSpinBox{ +public: + static const unsigned int nbBits = nb_bits; + static const int bitmask = BMask::bitmask; + + UnsignedSpinbox(QWidget* parent = 0) : QSpinBox(parent){ + setRange(0, bitmask); + } + + QValidator::State validate(QString& input, int& pos) const { + QString stripped = input.trimmed(); + if (stripped.isEmpty()) return QValidator::Intermediate; + + bool ok; + uint num = input.toUInt(&ok); + if (!ok) return QValidator::Invalid; + else if (num < m) return QValidator::Intermediate; + else if (num > M) return QValidator::Invalid; + else return QValidator::Acceptable; + } + + + + int minimum(void) const { + return (int)m; + } + uint unsignedMinimum(void) const { + return m; + } + int maximum(void) const { + return (int)M; + } + uint unsignedMaximum(void) const { + return M; + } + + void setMinimum(int min) { + setRange(min, (int)M); + } + void setMaximum(int max) { + setRange((int)m, max); + } + + void setUnsignedMinimum(uint min) { + setUnsignedRange(min, M); + } + void setUnsignedMaximum(uint max) { + setUnsignedRange(m, max); + } + + void setRange(int min, int max) { + m = (uint)min; + M = (uint)max; + if (M > bitmask) M = bitmask; + QSpinBox::setRange(INT_MIN, INT_MAX); + setUnsignedValue(unsignedValue()); + } + + void setUnsignedRange(uint min, uint max) { + setRange((int)min, (int)max); + } + + uint unsignedValue(void) const{ + return (uint)(value()); + } + + void setUnsignedValue(uint val){ + if (val < m) val = m; + if (val > M) val = M; + QSpinBox::setValue((int)val); + } + int value(void) const { + return (uint)QSpinBox::value(); + } + void setValue(int val) { + setUnsignedValue((uint)val); + } + + void stepBy(int step) { + uint uval = unsignedValue(); + if ((step > 0) && ((uval + step) < uval)) return; // overflow + if ((step < 0) && (uval + step) > uval) return; // underflow + setUnsignedValue(uval + step); + } +protected: + QString textFromValue(int val) const{ + return QString::number((uint)val ); + } + + int valueFromText(const QString& txt) const { + return ((int)txt.toUInt()); + } +private: + uint m, M; +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/VersionInfoLayout.cpp b/PkmGCSaveEditor/src/Core/VersionInfoLayout.cpp new file mode 100644 index 0000000..11263f0 --- /dev/null +++ b/PkmGCSaveEditor/src/Core/VersionInfoLayout.cpp @@ -0,0 +1,60 @@ +#include +#include +using namespace LibPkmGC; + + +const int gameNameToID[] = { 0, 1, 2, 8, 9, 10, 11 }; +const int gameIDToName[] = { 0, 1, 2, 0,0,0,0,0, 3, 4, 5, 6 }; + +QStringList VersionInfoLayout::languageNames(void) { + return QStringList() << tr("None", "Language name") << tr("Japanese") << tr("English") << tr("German") << tr("French") << tr("Italian") << tr("Spanish"); +} + +QStringList VersionInfoLayout::languageCodes(void) { + return QStringList("auto") << "ja" << "en" << "de" << "fr" << "it" << "es"; + +} +VersionInfoLayout::VersionInfoLayout(LibPkmGC::VersionInfo const& info) : QFormLayout(){ + const QStringList gameNames = QStringList() << tr("None", "Game name") << tr("Fire Red") << tr("Leaf Green") << + tr("Ruby") << tr("Sapphire") << tr("Emerald") << tr("Colosseum/XD"); + + const QStringList regionNames = QStringList() << tr("None", "Region name") << tr("NTSC-J") << tr("NTSC-U") << tr("PAL"); + + gameFld = new QComboBox; + currentRegionFld = new QComboBox; + originalRegionFld = new QComboBox; + languageFld = new QComboBox; + + gameFld->addItems(gameNames); + currentRegionFld->addItems(regionNames); + originalRegionFld->addItems(regionNames); + languageFld->addItems(languageNames()); + + + this->addRow(tr("Game"), gameFld); + this->addRow(tr("Current region"), currentRegionFld); + this->addRow(tr("Original region"), originalRegionFld); + this->addRow(tr("Language"), languageFld); + + QComboBox* flds[] = { gameFld, currentRegionFld, originalRegionFld, languageFld }; + for (size_t i = 0; i < 4; ++i) connect(flds[i], SIGNAL(currentIndexChanged(int)), this, SLOT(versionChangedEmitter())); + setInfo(info); +} + +VersionInfo VersionInfoLayout::info(void) const { + VersionInfo ret = { (GameIndex) gameNameToID[gameFld->currentIndex()], (RegionIndex) currentRegionFld->currentIndex(), + (RegionIndex) originalRegionFld->currentIndex(), (LanguageIndex) languageFld->currentIndex()}; + + return ret; +} + +void VersionInfoLayout::setInfo(LibPkmGC::VersionInfo const & info) { + gameFld->setCurrentIndex(gameIDToName[(size_t)info.game]); + currentRegionFld->setCurrentIndex(info.currentRegion); + originalRegionFld->setCurrentIndex(info.originalRegion); + languageFld->setCurrentIndex(info.language); +} + +void VersionInfoLayout::versionChangedEmitter(void) { + emit versionChanged(); +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/Core/VersionInfoLayout.h b/PkmGCSaveEditor/src/Core/VersionInfoLayout.h new file mode 100644 index 0000000..e562a4d --- /dev/null +++ b/PkmGCSaveEditor/src/Core/VersionInfoLayout.h @@ -0,0 +1,33 @@ +#ifndef _PKMGCSAVEEDITOR_VERSION_INFO_LAYOUT_H +#define _PKMGCSAVEEDITOR_VERSION_INFO_LAYOUT_H + +#include +#include +#include +#include +#include + + +class VersionInfoLayout : public QFormLayout { + Q_OBJECT +public: + static QStringList languageNames(void); + static QStringList languageCodes(void); + //LibPkmGC::VersionInfo info; + + VersionInfoLayout(LibPkmGC::VersionInfo const& inInfo = LibPkmGC::VersionInfo()); + + LibPkmGC::VersionInfo info(void) const; + void setInfo(LibPkmGC::VersionInfo const& info); + +signals: + void versionChanged(void); + +public slots: + void versionChangedEmitter(void); +private: + + QComboBox *gameFld, *currentRegionFld, *originalRegionFld, *languageFld; +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/BagEditor.cpp b/PkmGCSaveEditor/src/GCUIs/BagEditor.cpp new file mode 100644 index 0000000..879b0b4 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/BagEditor.cpp @@ -0,0 +1,81 @@ +#include + +using namespace LibPkmGC; +namespace GCUIs { + +BagEditor::BagEditor(LibPkmGC::GC::BagData* inBag, QWidget* parent) : QWidget(parent), bag(inBag) { + init(); +} + +BagEditor::~BagEditor(void){ + if (!isXD) delete battleCDsPocket; +} + +void BagEditor::initWidget(void) { + mainLayout = new QVBoxLayout; + tabs = new QTabWidget; + + + // pokeballs, TMs, berries and colognes do not have to take isXD into account + + regularItemsPocket = new ItemPocketEditor(NULL, 0, REGULAR_ITEMS_ALLOWED); + keyItemsPocket = new ItemPocketEditor(NULL, 43, KEY_ITEMS_ALLOWED); + + pokeballsPocket = new ItemPocketEditor(NULL, 16, POKEBALLS_ALLOWED); + TMsPocket = new ItemPocketEditor(NULL, 64, TMS_ALLOWED); + berriesPocket = new ItemPocketEditor(NULL, 46, BERRIES_ALLOWED); + colognesPocket = new ItemPocketEditor(NULL, 3, COLOGNES_ALLOWED); + battleCDsPocket = new ItemPocketEditor(NULL, 60, BATTLE_CDS_ALLOWED, true); + + tabs->addTab(regularItemsPocket, tr("Regular items")); + tabs->addTab(keyItemsPocket, tr("Key items")); + tabs->addTab(pokeballsPocket, tr("Pok\xc3\xa9""balls")); + tabs->addTab(TMsPocket, tr("TMs")); + tabs->addTab(berriesPocket, tr("Berries")); + tabs->addTab(colognesPocket, tr("Colognes")); + + tabs->setUsesScrollButtons(false); + mainLayout->addWidget(tabs); + this->setLayout(mainLayout); +} + +void BagEditor::parseData(void){ + if (bag == NULL) return; + isXD = LIBPKMGC_IS_XD(BagData, bag); + + int c = tabs->count(); + battleCDsPocket->pocket = NULL; + + if (isXD) { + XD::BagData* bag_xd = (XD::BagData*) bag; + battleCDsPocket->pocket = bag_xd->battleCDs; + battleCDsPocket->parseData(); + if(c != 7) tabs->addTab(battleCDsPocket, tr("Battle CDs")); + } + if (!isXD && (c == 7)) tabs->removeTab(6); + +#define ST(pkt) pkt##Pocket->pocket = bag->pkt; pkt##Pocket->isXD = isXD; pkt##Pocket->parseData(); + regularItemsPocket->pocketMaxSize = bag->nbRegularItems; + + ST(regularItems); + ST(keyItems); + ST(pokeballs); + ST(TMs); + ST(berries); + ST(colognes); +#undef ST +} + +void BagEditor::saveChanges(void){ + regularItemsPocket->saveChanges(); + keyItemsPocket->saveChanges(); + pokeballsPocket->saveChanges(); + TMsPocket->saveChanges(); + berriesPocket->saveChanges(); + colognesPocket->saveChanges(); + if (isXD) battleCDsPocket->saveChanges(); +} + + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/BagEditor.h b/PkmGCSaveEditor/src/GCUIs/BagEditor.h new file mode 100644 index 0000000..74d38b2 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/BagEditor.h @@ -0,0 +1,33 @@ +#ifndef _PKMGCSAVEEDITOR_BAG_EDITOR_H +#define _PKMGCSAVEEDITOR_BAG_EDITOR_H + +#include +#include +#include +#include + +namespace GCUIs { + +class BagEditor : public QWidget, public IDataUI { + Q_OBJECT +public: + BagEditor(LibPkmGC::GC::BagData* inBag = NULL, QWidget* parent = NULL); + ~BagEditor(void); + void parseData(void); + LibPkmGC::GC::BagData* bag; + + void saveChanges(void); + +protected: + void initWidget(void); + +private: + bool isXD; + QVBoxLayout* mainLayout; + QTabWidget* tabs; + ItemPocketEditor *regularItemsPocket, *keyItemsPocket, *pokeballsPocket, *TMsPocket, *berriesPocket, *colognesPocket, *battleCDsPocket; +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/DaycareUI.cpp b/PkmGCSaveEditor/src/GCUIs/DaycareUI.cpp new file mode 100644 index 0000000..33e8cfe --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/DaycareUI.cpp @@ -0,0 +1,74 @@ +#include + +namespace GCUIs { + +using namespace LibPkmGC; +DaycareUI::DaycareUI(LibPkmGC::GC::DaycareData * inDaycare, QWidget * parent, Qt::WindowFlags f) : DataUI(parent, f), daycare(inDaycare) { + init(); +} + +void DaycareUI::initWidget(void) { + daycareLayout = new QFormLayout; + + daycareStatusButtonLayout = new QHBoxLayout; // NotVisited = -1, NoPkmDeposited = 0, PkmDeposited = 1 + daycareStatusButtonGroup = new QButtonGroup; + notVisitedButton = new QRadioButton(tr("Not visited yet")); + emptyButton = new QRadioButton(tr("Empty")); + pkmDepositedButton = new QRadioButton(tr("Pok\xc3\xa9mon deposited")); + + pkmInitialLevelFld = new UnsignedSpinbox<7>; + pkmInitialPurifCtrFld = new UnsignedSpinbox<32>; + + pkmInitialLevelFld->setRange(1, 100); + + PokemonStorageInfo loc = { StoredInDaycare, 0, 0 }; + pkmFld = new PokemonDisplayWidget(NULL, loc); + + daycareStatusButtonGroup->addButton(notVisitedButton, 0); daycareStatusButtonLayout->addWidget(notVisitedButton, 0); + daycareStatusButtonGroup->addButton(emptyButton, 1); daycareStatusButtonLayout->addWidget(emptyButton, 1); + daycareStatusButtonGroup->addButton(pkmDepositedButton, 2); daycareStatusButtonLayout->addWidget(pkmDepositedButton, 2); + notVisitedButton->hide(); + emptyButton->setChecked(true); + + daycareLayout->addRow(tr("Daycare status"), daycareStatusButtonLayout); + daycareLayout->addRow(tr("Initial Pok\xc3\xa9mon level"), pkmInitialLevelFld); + daycareLayout->addRow(tr("Initial Pok\xc3\xa9mon purification counter"), pkmInitialPurifCtrFld); + //daycareLayout->addRow(tr(""), pkmFld); + mainLayout->addLayout(daycareLayout); + mainLayout->addWidget(pkmFld); + + DataUI::initWidget(); +} + + +void DaycareUI::parseData(void) { + if (daycare == NULL) return; + + isXD = LIBPKMGC_IS_XD(DaycareData, daycare); + notVisitedButton->setVisible(isXD); + + notVisitedButton->setChecked(daycare->status == NotVisited); + emptyButton->setChecked(daycare->status == NoPkmDeposited); + pkmDepositedButton->setChecked(daycare->status == PkmDeposited); + + pkmInitialLevelFld->setValue(daycare->initialPkmLevel); + pkmInitialPurifCtrFld->setValue(daycare->initialPkmPurifCounter); + + pkmFld->pkm = daycare->pkm; + pkmFld->parseData(); +} + +void DaycareUI::saveChanges(void) { + daycare->status = (DaycareStatus)(daycareStatusButtonGroup->checkedId() - 1); + daycare->initialPkmLevel = (u8)pkmInitialLevelFld->unsignedValue(); + daycare->initialPkmPurifCounter = pkmInitialPurifCtrFld->unsignedValue(); + + pkmFld->saveChanges(); +} + +void DaycareUI::cancelChanges(void){ + pkmFld->cancelChanges(); +} + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/DaycareUI.h b/PkmGCSaveEditor/src/GCUIs/DaycareUI.h new file mode 100644 index 0000000..6f0111b --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/DaycareUI.h @@ -0,0 +1,41 @@ +#ifndef _PKMGCSAVEEDITOR_DAYCARE_UI_H +#define _PKMGCSAVEEDITOR_DAYCARE_UI_H + +#include + +namespace GCUIs { + +class DaycareUI : public DataUI { + Q_OBJECT +public: + DaycareUI(LibPkmGC::GC::DaycareData* inDaycare = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + + LibPkmGC::GC::DaycareData* daycare; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); +protected: + void initWidget(void); + +private: + QFormLayout* daycareLayout; + + QButtonGroup* daycareStatusButtonGroup; + QHBoxLayout* daycareStatusButtonLayout; + QRadioButton *notVisitedButton, *emptyButton, *pkmDepositedButton; + + UnsignedSpinbox<7>* pkmInitialLevelFld; + UnsignedSpinbox<32>* pkmInitialPurifCtrFld; + // Cost of daycare : 100*(1 + (currentLevel - initialLevel) + 1 + int((purifCtr - initialPurifCtr)/100)) + // or 100*(1 + currentLevel - initialLvl) if (purifCtr - initialPurifCtr) < 100. 0 if status != PkmDeposited + + + + PokemonDisplayWidget *pkmFld; + +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/GameConfigUI.cpp b/PkmGCSaveEditor/src/GCUIs/GameConfigUI.cpp new file mode 100644 index 0000000..28ecda5 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/GameConfigUI.cpp @@ -0,0 +1,86 @@ +#include +#include + +using namespace LibPkmGC; +using namespace GC::SaveEditing; +namespace GCUIs { + +GameConfigUI::GameConfigUI(SaveSlot * inSaveSlot, QWidget * parent, Qt::WindowFlags f) : DataUI(parent, f), saveSlot_(inSaveSlot) { + init(); +} + +void GameConfigUI::initWidget(void) { + versionBox = new QGroupBox(tr("Game version")); + versionFld = new VersionInfoLayout; + + titleScreenOptionsBox = new QGroupBox(tr("Title screen options")); + titleScreenOptionsLayout = new QFormLayout; + noRumbleFld = new QCheckBox; + titleScreenLanguageFld = new QComboBox; + + miscellaneousBox = new QGroupBox(tr("Miscellaneous")); + miscellaneousLayout = new QFormLayout; + storyModeSaveCountFld = new UnsignedSpinbox<32>; + + titleScreenLanguageFld->addItems(VersionInfoLayout::languageNames()); + + versionBox->setLayout(versionFld); + + titleScreenOptionsLayout->addRow(tr("Rumble function disabled"), noRumbleFld); + titleScreenOptionsLayout->addRow(tr("Language"), titleScreenLanguageFld); + titleScreenOptionsBox->setLayout(titleScreenOptionsLayout); + + miscellaneousLayout->addRow(tr("Story mode save count"), storyModeSaveCountFld); + miscellaneousBox->setLayout(miscellaneousLayout); + + mainLayout->addWidget(versionBox); + mainLayout->addWidget(titleScreenOptionsBox); + mainLayout->addWidget(miscellaneousBox); + + connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler())); + DataUI::initWidget(); +} + +void GameConfigUI::parseData(void) { + if (saveSlot_ == NULL) return; + SaveSlot* sl = saveSlot_; + isXD = LIBPKMGC_IS_XD(SaveEditing::SaveSlot, sl); + + versionFld->disconnect(SIGNAL(versionChanged())); + versionFld->setInfo(sl->version); + connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler())); + + noRumbleFld->setChecked(sl->noRumble); + titleScreenLanguageFld->setCurrentIndex((int)sl->titleScreenLanguage); + + miscellaneousBox->setVisible(!isXD); + if (!isXD) { + Colosseum::SaveEditing::SaveSlot *sl_c = (Colosseum::SaveEditing::SaveSlot*) sl; + storyModeSaveCountFld->setUnsignedValue(sl_c->storyModeSaveCount); + } + + versionChangeHandler(); +} + +void GameConfigUI::saveChanges(void) { + SaveSlot* sl = saveSlot_; + + sl->version = versionFld->info(); + sl->noRumble = noRumbleFld->isChecked(); + sl->titleScreenLanguage = (LanguageIndex)titleScreenLanguageFld->currentIndex(); + if (!isXD) { + Colosseum::SaveEditing::SaveSlot *sl_c = (Colosseum::SaveEditing::SaveSlot*) sl; + sl_c->storyModeSaveCount = storyModeSaveCountFld->unsignedValue(); + } + +} + +void GameConfigUI::versionChangeHandler(void) { + if (versionFld->info().isIncomplete()) + QMessageBox::warning(this, tr("Warning"), tr("The version info you specified is invalid, and will make the game unplayable.")); +} + + + + +} diff --git a/PkmGCSaveEditor/src/GCUIs/GameConfigUI.h b/PkmGCSaveEditor/src/GCUIs/GameConfigUI.h new file mode 100644 index 0000000..b41dc0a --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/GameConfigUI.h @@ -0,0 +1,47 @@ +#ifndef _PKMGCSAVEEDITOR_GAME_CONFIG_UI_H +#define _PKMGCSAVEEDITOR_GAME_CONFIG_UI_H + +#include +#include +#include +#include +#include +#include + +namespace GCUIs { + +class GameConfigUI : public DataUI { + Q_OBJECT +public: + GameConfigUI(LibPkmGC::GC::SaveEditing::SaveSlot *inSaveSlot = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + + LibPkmGC::GC::SaveEditing::SaveSlot* saveSlot_; // not using ::currentSaveSlot here + + void parseData(void); + + void saveChanges(void); + +public slots: + void versionChangeHandler(void); +protected: + void initWidget(void); + +private: + QGroupBox* versionBox; + VersionInfoLayout* versionFld; + + QGroupBox* titleScreenOptionsBox; + QFormLayout* titleScreenOptionsLayout; + QCheckBox *noRumbleFld; + QComboBox* titleScreenLanguageFld; + + QGroupBox* miscellaneousBox; + QFormLayout* miscellaneousLayout; + UnsignedSpinbox<32>* storyModeSaveCountFld; + + +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PCUI.cpp b/PkmGCSaveEditor/src/GCUIs/PCUI.cpp new file mode 100644 index 0000000..196cd1f --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PCUI.cpp @@ -0,0 +1,80 @@ +#include + +using namespace LibPkmGC; + +namespace GCUIs { + +PCUI::PCUI(LibPkmGC::GC::PCData* inPC, QWidget* parent, Qt::WindowFlags f) : DataUI(parent, f), PC(inPC) { + init(); +} + + +void PCUI::initWidget(void) { + tabs = new QTabWidget; + + pkmStorageTab = new QWidget; + pkmStorageTabLayout = new QVBoxLayout; + boxSelectorLayout = new QFormLayout; + boxSelector = new QComboBox; + boxes = new QStackedWidget; + + itemsTab = new ItemPocketEditor(NULL, 0xeb, GIVABLE_ITEMS_ALLOWED); + + boxSelectorLayout->addRow(tr("Selected box"), boxSelector); + pkmStorageTabLayout->addLayout(boxSelectorLayout); + pkmStorageTabLayout->addWidget(boxes); + pkmStorageTab->setLayout(pkmStorageTabLayout); + + tabs->addTab(pkmStorageTab, tr("Pok\xc3\xa9mon")); + tabs->addTab(itemsTab, tr("Items")); + + mainLayout->addWidget(tabs); + DataUI::initWidget(); + + connect(boxSelector, SIGNAL(currentIndexChanged(int)), boxes, SLOT(setCurrentIndex(int))); +} + +void PCUI::parseData(void) { + if (PC == NULL) return; + isXD = LIBPKMGC_IS_XD(PCData, PC); + + int nb = (int) PC->nbBoxes; + int c = boxes->count(); + for (int i = 0; i < c; ++i) { + QWidget* w = boxes->widget(i); + boxes->removeWidget(w); + delete w; + } + boxSelector->clear(); + for (int i = 0; i < nb; ++i) { + PokemonBoxEditor* box = new PokemonBoxEditor(PC->boxes[i], (size_t)i); + boxes->addWidget(box); + boxSelector->addItem(box->currentBoxName(), i); + connect(box, SIGNAL(nameChanged(size_t, QString const&)), this, SLOT(boxNameChangeHandler(size_t, QString const&))); + } + + itemsTab->pocket = PC->items; + itemsTab->isXD = isXD; + itemsTab->parseData(); +} + +void PCUI::saveChanges(void) { + for (size_t i = 0; i < PC->nbBoxes; ++i) { + PokemonBoxEditor* box = (PokemonBoxEditor*)boxes->widget((int)i); + box->saveChanges(); + } + itemsTab->saveChanges(); +} + +void PCUI::cancelChanges(void) { + for (size_t i = 0; i < PC->nbBoxes; ++i) { + PokemonBoxEditor* box = (PokemonBoxEditor*)boxes->widget((int)i); + box->cancelChanges(); + } +} + +void PCUI::boxNameChangeHandler(size_t nb, QString const & newName) { + boxSelector->setItemText((int)nb, newName); +} + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PCUI.h b/PkmGCSaveEditor/src/GCUIs/PCUI.h new file mode 100644 index 0000000..8915480 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PCUI.h @@ -0,0 +1,39 @@ +#ifndef _PKMGCSAVEEDITOR_PC_UI_H +#define _PKMGCSAVEEDITOR_PC_UI_H + +#include +#include + +namespace GCUIs { + +class PCUI : public DataUI { + Q_OBJECT +public: + PCUI(LibPkmGC::GC::PCData* inPC = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + + LibPkmGC::GC::PCData* PC; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); +public slots: + void boxNameChangeHandler(size_t nb, QString const& newName); +protected: + void initWidget(void); + +private: + QTabWidget* tabs; + + QVBoxLayout* pkmStorageTabLayout; + QWidget* pkmStorageTab; + QFormLayout* boxSelectorLayout; + QComboBox* boxSelector; + QStackedWidget* boxes; + + + ItemPocketEditor* itemsTab; +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PlayerUI.cpp b/PkmGCSaveEditor/src/GCUIs/PlayerUI.cpp new file mode 100644 index 0000000..13f61b4 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PlayerUI.cpp @@ -0,0 +1,113 @@ +#include + +using namespace LibPkmGC; + +namespace GCUIs{ + +PlayerUI::PlayerUI(LibPkmGC::GC::PlayerData* inPlayer, QWidget* parent, Qt::WindowFlags f) : DataUI(parent, f), player(inPlayer) { + init(); +} + +void PlayerUI::initWidget(void){ + tabs = new QTabWidget; + + generalTab = new QWidget; + generalTabLayout = new QVBoxLayout; + trainerInfoBox = new QGroupBox(tr("Trainer information")); + trainerInfoFld = new TrainerInfoLayout; + + trainerInfoBox->setLayout(trainerInfoFld); + + currenciesBox = new QGroupBox(tr("Currencies")); + currenciesLayout = new QFormLayout; + moneyFld = new UnsignedSpinbox<32>; + pkCouponsFld = new UnsignedSpinbox<32>; + + currenciesLayout->addRow(tr("Money"), moneyFld); + currenciesLayout->addRow(tr("Pok""\xc3\xa9""coupons"), pkCouponsFld); // Pokécoupons + + currenciesBox->setLayout(currenciesLayout); + + generalTabLayout->addWidget(trainerInfoBox); + generalTabLayout->addWidget(currenciesBox); + generalTab->setLayout(generalTabLayout); + + bagTab = new BagEditor; + + partyTab = new QWidget; + partyTabLayout = new QVBoxLayout; + partyTabLayout->addStretch(); + for (size_t i = 0; i < 6; ++i) { + pkmFlds[i] = new PokemonDisplayWidget; + partyTabLayout->addWidget(pkmFlds[i]); + connect(pkmFlds[i], SIGNAL(pkmDeleted(LibPkmGC::PokemonStorageInfo const&)), this, SLOT(pkmDeletionHandler(LibPkmGC::PokemonStorageInfo const&))); + } + partyTabLayout->addStretch(); + + partyTab->setLayout(partyTabLayout); + + tabs->addTab(generalTab, tr("General")); + tabs->addTab(bagTab, tr("Bag")); + tabs->addTab(partyTab, tr("Party")); + mainLayout->addWidget(tabs); + DataUI::initWidget(); +} + +PlayerUI::~PlayerUI(void){ + //for (size_t i = 0; i < 6; ++i) delete partyBackup[i]; +} + +void PlayerUI::parseData(void){ + if (player == NULL) return; + isXD = LIBPKMGC_IS_XD(PlayerData, player); + + trainerInfoFld->set(player->trainerName, player->TID, player->SID, player->trainerGender); + moneyFld->setValue((int)player->money); + pkCouponsFld->setValue((int)player->pkCoupons); + + bagTab->bag = player->bag; + bagTab->parseData(); + + for (size_t i = 0; i < 6; ++i) { + PokemonStorageInfo loc = { StoredInParty, i, 0 }; + pkmFlds[i]->location = loc; + pkmFlds[i]->pkm = player->party[i]; + pkmFlds[i]->parseData(); + } + +} + +void PlayerUI::saveChanges(void) { + trainerInfoFld->trainerName(player->trainerName); + player->TID = trainerInfoFld->TID(); + player->SID = trainerInfoFld->SID(); + player->trainerGender = trainerInfoFld->trainerGender(); + player->money = moneyFld->unsignedValue(); + player->pkCoupons = pkCouponsFld->unsignedValue(); + + for (size_t i = 0; i < 6; ++i) pkmFlds[i]->saveChanges(); + bagTab->saveChanges(); + +} + +void PlayerUI::cancelChanges(void) { + for (size_t i = 0; i < 6; ++i) pkmFlds[i]->cancelChanges(); +} + +void PlayerUI::pkmDeletionHandler(LibPkmGC::PokemonStorageInfo const & location) { + size_t i = location.index; + GC::Pokemon *party2[6] = { NULL }; + GC::Pokemon *deltd = player->party[i]; + std::copy(player->party, player->party + i, party2); + std::copy(player->party + i + 1, player->party + 6, party2 + i); + std::copy(party2, party2 + 5, player->party); + player->party[5] = deltd; + for (size_t i = 0; i < 6; ++i) { + PokemonStorageInfo loc = { StoredInParty, i, 0 }; + pkmFlds[i]->location = loc; + pkmFlds[i]->pkm = player->party[i]; + pkmFlds[i]->parseData(); + } +} + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PlayerUI.h b/PkmGCSaveEditor/src/GCUIs/PlayerUI.h new file mode 100644 index 0000000..394d226 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PlayerUI.h @@ -0,0 +1,52 @@ +#ifndef _PKMGCSAVEEDITOR_PLAYER_UI +#define _PKMGCSAVEEDITOR_PLAYER_UI + +#include +#include +#include +#include +#include + + +namespace GCUIs{ + +class PlayerUI : public DataUI{ + Q_OBJECT +public: + PlayerUI(LibPkmGC::GC::PlayerData* inPlayer = NULL, QWidget *parent = NULL, Qt::WindowFlags f = Qt::Window); + ~PlayerUI(void); + void parseData(void); + + LibPkmGC::GC::PlayerData *player; + + void saveChanges(void); + void cancelChanges(void); + +public slots: + void pkmDeletionHandler(LibPkmGC::PokemonStorageInfo const& location); + +protected: + void initWidget(void); +private: + + QTabWidget* tabs; + + QWidget* generalTab; + QVBoxLayout* generalTabLayout; + QGroupBox* trainerInfoBox; + TrainerInfoLayout* trainerInfoFld; + + QGroupBox* currenciesBox; + QFormLayout* currenciesLayout; + UnsignedSpinbox<32> *moneyFld, *pkCouponsFld; + + BagEditor* bagTab; + + QWidget* partyTab; + QVBoxLayout* partyTabLayout; + PokemonDisplayWidget* pkmFlds[6]; +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.cpp b/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.cpp new file mode 100644 index 0000000..3bbbd1c --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.cpp @@ -0,0 +1,75 @@ +#include + +using namespace LibPkmGC; +namespace GCUIs { + +PokemonBoxEditor::PokemonBoxEditor(LibPkmGC::GC::PokemonBox* inBox, size_t inBoxNb, QWidget* parent) : QWidget(parent), box(inBox), boxNb(inBoxNb){ + init(); +} + + +PokemonBoxEditor::~PokemonBoxEditor(void) { +} + +void PokemonBoxEditor::initWidget(void) { + mainLayout = new QVBoxLayout; + nameLayout = new QFormLayout; + nameFld = new QLineEdit; + tabs = new QTabWidget; + + QString tmpl(tr("%1 to %2")); + for (size_t i = 0; i < 5; ++i) { + pages[i] = new QWidget; + pageLayouts[i] = new QVBoxLayout; + for (size_t j = 0; j < 6; ++j) { + pkmFlds[6 * i + j] = new PokemonDisplayWidget; + pageLayouts[i]->addWidget(pkmFlds[6 * i + j]); + } + connect(nameFld, SIGNAL(textChanged(QString const&)), this, SLOT(nameChangedEmitter(QString const&))); + pages[i]->setLayout(pageLayouts[i]); + tabs->addTab(pages[i], tmpl.arg(1 + 6 * i).arg(6 + 6 * i)); + } + nameFld->setMaxLength(8); + nameLayout->addRow(tr("Box name"), nameFld); + mainLayout->addLayout(nameLayout); + mainLayout->addWidget(tabs); + this->setLayout(mainLayout); + +} + +void PokemonBoxEditor::parseData(void) { + if (box == NULL) return; + isXD = LIBPKMGC_IS_XD(PokemonBox, box); + + nameFld->setText(box->name->toUTF8()); + + for (size_t i = 0; i < 30; ++i) { + PokemonStorageInfo loc = { StoredInPC, boxNb, i }; + pkmFlds[i]->location = loc; + pkmFlds[i]->pkm = (GC::Pokemon*)box->pkm[i]; + pkmFlds[i]->parseData(); + } +} + +void PokemonBoxEditor::saveChanges(void) { + box->name->fromUTF8(nameFld->text().toUtf8().data()); + for (size_t i = 0; i < 30; ++i) + pkmFlds[i]->saveChanges(); +} + +void PokemonBoxEditor::cancelChanges(void) { + for (size_t i = 0; i < 30; ++i) + pkmFlds[i]->cancelChanges(); +} + +QString PokemonBoxEditor::currentBoxName(void) const { + return nameFld->text(); +} + + +void PokemonBoxEditor::nameChangedEmitter(QString const & newName) { + emit nameChanged(boxNb, newName); +} + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.h b/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.h new file mode 100644 index 0000000..0fe3b2d --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonBoxEditor.h @@ -0,0 +1,43 @@ +#ifndef _PKMGCSAVEEDITOR_POKEMON_BOX_EDITOR_H +#define _PKMGCSAVEEDITOR_POKEMON_BOX_EDITOR_H +#include + +namespace GCUIs { + +class PokemonBoxEditor : public QWidget, public IDataUI { + Q_OBJECT +public: + PokemonBoxEditor(LibPkmGC::GC::PokemonBox* inBox = NULL, size_t inBoxNb = 0, QWidget* parent = NULL); + ~PokemonBoxEditor(void); + + void parseData(void); + LibPkmGC::GC::PokemonBox* box; + size_t boxNb; + + void saveChanges(void); + void cancelChanges(void); + QString currentBoxName(void) const; + +signals: + void nameChanged(size_t nb, QString const& newName); +public slots: + //void pkmDeletionHandler(LibPkmGC::PokemonStorageInfo const & location); + void nameChangedEmitter(QString const& newName); +protected: + void initWidget(void); +private: + bool isXD; +// LibPkmGC::GC::PokemonBox* boxBackup; + + QVBoxLayout* mainLayout; + QFormLayout* nameLayout; + QLineEdit* nameFld; + QTabWidget *tabs; + QWidget *pages[5]; + QVBoxLayout *pageLayouts[5]; + PokemonDisplayWidget* pkmFlds[30]; +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.cpp b/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.cpp new file mode 100644 index 0000000..c35e60b --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.cpp @@ -0,0 +1,221 @@ +#include + +#include +#include +#include +#include + +using namespace LibPkmGC; +using namespace Localization; + +namespace GCUIs { + +PokemonDisplayWidget::PokemonDisplayWidget(GC::Pokemon* inPkm, LibPkmGC::PokemonStorageInfo const& inLocation, QWidget* parent) : + QWidget(parent), pkm(inPkm), location(inLocation), pkmBackup(NULL) { + init(); +} + +PokemonDisplayWidget::~PokemonDisplayWidget(void) { + delete pkmBackup; +} + +void PokemonDisplayWidget::initWidget(void) { + mainLayout = new QHBoxLayout; + buttonsLayout = new QHBoxLayout; + nameFld = new QLabel; + summary = new QLabel; + editButton = new QPushButton(tr("Edit")); + deleteButton = new QPushButton(tr("Delete")); + importButton = new QPushButton(tr("Import")); + exportButton = new QPushButton(tr("Export")); + + mainLayout->addWidget(nameFld); + mainLayout->addWidget(summary); + buttonsLayout->addWidget(editButton); + buttonsLayout->addWidget(deleteButton); + buttonsLayout->addWidget(importButton); + buttonsLayout->addWidget(exportButton); + mainLayout->addLayout(buttonsLayout); + + connect(editButton, SIGNAL(clicked()), this, SLOT(openPkmUI())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deletePkm())); + + connect(importButton, SIGNAL(clicked()), this, SLOT(openImportPkmDialog())); + connect(exportButton, SIGNAL(clicked()), this, SLOT(openExportPkmDialog())); + this->setLayout(mainLayout); +} + +void PokemonDisplayWidget::parseData(void) { + if (pkm == NULL) return; + if (pkmBackup == NULL) pkmBackup = pkm->clone(); + + updatePkmNameAndSummary(); +} + +void PokemonDisplayWidget::saveChanges(void) { + delete pkmBackup; // PokemonUI::saveChanges has been called already, we don't need to call it again + pkmBackup = pkm->clone(); +} + +void PokemonDisplayWidget::cancelChanges(void) { + *pkm = *pkmBackup; +} + +void PokemonDisplayWidget::updatePkmNameAndSummary(void) { + LanguageIndex lg = generateDumpedNamesLanguage(); + QString s, tt; + + if (pkm == NULL || pkm->species == NoSpecies) { + nameFld->setText(getPokemonSpeciesName(lg, (pkm == NULL) ? NoSpecies : pkm->species)); + summary->setText(""); + return; + } + + nameFld->setText(pkm->name->toUTF8()); + + s = "("; + if (!getSpeciesData(pkm->species).isValid) { + tt = tr("Invalid species"); + } + if (pkm->version.isIncomplete()) { + if (!tt.isEmpty()) tt += "\n"; + tt = tr("Invalid version info"); + } + if (LIBPKMGC_IS_XD(Pokemon, pkm) && (static_cast(pkm)->pkmFlags & 0x20) != 0) { + if (!tt.isEmpty()) tt += "\n"; + tt += tr("Bit 5 set on byte at offset 0x1d"); + } + + summary->setToolTip(tt); + + if (!tt.isEmpty()) { + s += "INVALID"; + } + else { + s += tr("Lv. %n ", "", (pkm->partyData.level > 100) ? 100 : pkm->partyData.level); + s += PokemonUI::getShortPkmAttributeText(pkm->species, pkm->PID, pkm->TID, pkm->SID); + } + s += ")"; + + summary->setText(s); +} + + +void PokemonDisplayWidget::openPkmUI(void) { + PokemonUI dlg(pkm, location, this); + if (dlg.exec() == 1) { + updatePkmNameAndSummary(); + emit pkmUpdated(pkm, location); + } +} + +void PokemonDisplayWidget::deletePkm(void) { + std::fill(pkm->data, pkm->data + pkm->fixedSize, 0); + pkm->reload(); + emit pkmDeleted(location); + updatePkmNameAndSummary(); +} + + + +QString PokemonDisplayWidget::selectFilters(void) { + const QString colofilter = tr("Colosseum Pok\xc3\xa9mon files (*.colopkm)"); + const QString xdfilter = tr("XD Pok\xc3\xa9mon files (*.xdpkm)"); + const QString allfilesfilter = tr("All files (*)"); + return ((pkm == NULL || LIBPKMGC_IS_COLOSSEUM(Pokemon, pkm)) ? + colofilter + ";;" + xdfilter + ";;" + allfilesfilter : + xdfilter + ";;" + colofilter + ";;" + allfilesfilter); +} + +void PokemonDisplayWidget::openImportPkmDialog(void) { + const QString errmsg = tr("Could not open file."); + const QString errmsg2 = tr("An error occured while reading the specified Pok\xc3\xa9mon file."); + + QString fileName = QFileDialog::getOpenFileName(this, tr("Open Pok\xc3\xa9mon file"), lastPkmDirectory, selectFilters()); + if (fileName.isEmpty()) return; + + QFileInfo fileInfo(fileName); + size_t fileSize = (size_t) fileInfo.size(); + if (fileSize == 0x138) { // Colosseum Pokémon + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Error"), errmsg); + return; + } + + QByteArray ba = file.readAll(); + if (ba.size() != 0x138) { + QMessageBox::critical(this, tr("Error"), errmsg2); + return; + } + + Colosseum::Pokemon importedPkm((u8*)ba.data()); + if (pkm == NULL) pkm = importedPkm.clone(); + else { *pkm = importedPkm; } + parseData(); + lastPkmDirectory = fileInfo.canonicalPath(); + } + else if (fileSize == 0xc4) { + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Error"), errmsg); + return; + } + + QByteArray ba = file.readAll(); + if (ba.size() != 0xc4) { + QMessageBox::critical(this, tr("Error"), errmsg2); + return; + } + + XD::Pokemon importedPkm((const u8*)ba.data()); + if (pkm == NULL) pkm = importedPkm.clone(); + else { *pkm = importedPkm; } + parseData(); + lastPkmDirectory = fileInfo.canonicalPath(); + } + else { + QMessageBox::critical(this, tr("Error"), tr("Invalid file size.")); + } +} + +void PokemonDisplayWidget::openExportPkmDialog(void) { + const QString errmsg = tr("Could not write to file."); + const QString errmsg2 = tr("An error occured while writing to the specified Pok\xc3\xa9mon file."); + + QString fileName = QFileDialog::getSaveFileName(this, tr("Save Pok\xc3\xa9mon file"), lastPkmDirectory, selectFilters()); + if (fileName.isEmpty()) return; + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::critical(this, tr("Error"), errmsg); + return; + } + + QString selectedExt = fileName.section(".", -1); + + + GC::Pokemon* exportedPkm = pkm; + bool created = false; + + if ((selectedExt == "colopkm") && !LIBPKMGC_IS_COLOSSEUM(Pokemon, pkm)) { + exportedPkm = new Colosseum::Pokemon(*(XD::Pokemon*)pkm); + created = true; + } + else if ((selectedExt == "xdpkm") && !LIBPKMGC_IS_XD(Pokemon, pkm)) { + exportedPkm = new XD::Pokemon(*(Colosseum::Pokemon*)pkm); + created = true; + } + + exportedPkm->save(); + + if (file.write((const char*)exportedPkm->data, exportedPkm->fixedSize) != (qint64)exportedPkm->fixedSize) + QMessageBox::critical(this, tr("Error"), errmsg2); + else + lastPkmDirectory = QFileInfo(fileName).canonicalPath(); + + if (created) delete exportedPkm; + +} + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.h b/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.h new file mode 100644 index 0000000..2c0b60e --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonDisplayWidget.h @@ -0,0 +1,51 @@ +#ifndef _PKMGCSAVEEDITOR_POKEMON_DISPLAY_WIDGET_H +#define _PKMGCSAVEEDITOR_POKEMON_DISPLAY_WIDGET_H + +#include + +namespace GCUIs { + +class PokemonDisplayWidget : public QWidget, IDataUI { + Q_OBJECT +public: + PokemonDisplayWidget(LibPkmGC::GC::Pokemon* inPkm = NULL, LibPkmGC::PokemonStorageInfo const& inLocation = LibPkmGC::emptyStorageInfo, + QWidget* parent = NULL); + ~PokemonDisplayWidget(void); + + LibPkmGC::GC::Pokemon *pkm, *pkmBackup; + LibPkmGC::PokemonStorageInfo location; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); + +protected: + void initWidget(void); +signals: + void pkmUpdated(LibPkmGC::GC::Pokemon* pkm, LibPkmGC::PokemonStorageInfo location); + void pkmDeleted(LibPkmGC::PokemonStorageInfo const& location); + +public slots: + void updatePkmNameAndSummary(void); + void openImportPkmDialog(void); + void openExportPkmDialog(void); + void deletePkm(void); + void openPkmUI(void); + +private: + QHBoxLayout* mainLayout; + QLabel* nameFld; + QLabel* summary; + QHBoxLayout *buttonsLayout; + QPushButton *editButton; + QPushButton *deleteButton; + QPushButton *importButton; + QPushButton *exportButton; + + QString selectFilters(void); + +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonUI.cpp b/PkmGCSaveEditor/src/GCUIs/PokemonUI.cpp new file mode 100644 index 0000000..78e890e --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonUI.cpp @@ -0,0 +1,679 @@ +#include +#include + +using namespace LibPkmGC; using namespace Localization; using namespace Base; + + +static QString s1[] = QT_TRANSLATE_NOOP3("GCUIs::PokemonUI", "None", "Status"); + + +namespace GCUIs { + +PokemonMoveLayout::PokemonMoveLayout(PokemonMove const& inMove) : QHBoxLayout(){ + LanguageIndex lg = generateDumpedNamesLanguage(); + moveNameFld = new QComboBox; + currentPPsFld = new UnsignedSpinbox<7>; + maxPPsFld = new QLabel(tr("(max. %n)", "", 0)); + nbPPUpsUsedFld = new UnsignedSpinbox<2>; + nbPPUpsUsedText = new QLabel(tr("PP Up(s) used")); + + currentPPsFld->setRange(0, 64); + + this->addWidget(moveNameFld); + this->addWidget(currentPPsFld); + this->addWidget(maxPPsFld); + this->addWidget(nbPPUpsUsedFld, 0, Qt::AlignRight); + this->addWidget(nbPPUpsUsedText, 0, Qt::AlignRight); + + + for (size_t i = 0; i <= (size_t)PsychoBoost; ++i) + moveNameFld->addItem(getPokemonMoveName(lg, (PokemonMoveIndex)i)); + + connect(moveNameFld, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFields())); + connect(nbPPUpsUsedFld, SIGNAL(valueChanged(int)), this, SLOT(updateFields())); + + setMove(inMove); +} + +PokemonMove PokemonMoveLayout::move(void) const { + PokemonMove _move = { (PokemonMoveIndex)moveNameFld->currentIndex(), (u8)currentPPsFld->value(), (u8)nbPPUpsUsedFld->value() }; + return _move; +} + +void PokemonMoveLayout::setMove(PokemonMove const& inMove) { + blockSignals(true); + currentPPsFld->setUnsignedRange(0, 64); + currentPPsFld->setUnsignedValue(inMove.currentPPs); + moveNameFld->setCurrentIndex((inMove.moveIndex > PsychoBoost) ? 0 : (int) inMove.moveIndex); + nbPPUpsUsedFld->setUnsignedValue(inMove.nbPPUpsUsed); + blockSignals(false); + updateFields(); +} + +void PokemonMoveLayout::updateFields(void) { + PokemonMove _move = move(); + u8 maxPPs = _move.calculateMaxPP(); + maxPPsFld->setText(tr("(max. %n)", "", maxPPs)); + currentPPsFld->setRange(0, (int)maxPPs); +} + +PokemonStatLayout::PokemonStatLayout(u8 inIV, u8 inEV, u16 inStat) : QHBoxLayout(){ + IVFld = new UnsignedSpinbox<5>; + EVFld = new UnsignedSpinbox<8>; + statFld = new UnsignedSpinbox<16>; + + IVFld->setValue((int)inIV); + EVFld->setValue((int)inEV); + statFld->setValue((int)inStat); + this->addWidget(IVFld); + this->addWidget(EVFld); + this->addWidget(statFld); + connect(IVFld, SIGNAL(valueChanged(int)), this, SLOT(IVOrEVChangedEmitter())); + connect(EVFld, SIGNAL(valueChanged(int)), this, SLOT(IVOrEVChangedEmitter())); +} + +void PokemonStatLayout::IVOrEVChangedEmitter(void) { + emit IVOrEVChanged(); +} + + +PokemonUI::PokemonUI(GC::Pokemon * inPkm, + PokemonStorageInfo const& inLocation, QWidget * parent, Qt::WindowFlags f) : DataUI(parent,f), pkm(inPkm), location(inLocation){ + init(); +} + +QStringList PokemonUI::statusNames(void) { + return QStringList() << tr("None", "Status") << tr("Poisoned") << tr("Badly poisoned") << + tr("Paralyzed") << tr("Burnt") << tr("Frozen") << tr("Asleep"); +} + +void PokemonUI::initWidget(void){ + const QStringList contestStatNames = QStringList() << tr("Coolness") << tr("Beauty") << tr("Cuteness") + << tr("Cleverness") << tr("Toughness"); + + const QStringList contestAchivementLevelNames = QStringList() << tr("None", "Contest") << tr("Normal", "Contest") + << tr("Super", "Contest") << tr("Hyper", "Contest") + << tr("Master", "Contest"); + + const QStringList statNames = QStringList() << tr("HP") << tr("Attack") << tr("Defense") << + tr("S. Attack") << tr("S. Defense") << tr("Speed"); + + const QStringList srNames = QStringList() << tr("Champion") << tr("Winning") << tr("Victory") << tr("Artist") << + tr("Effort") << tr("Marine") << tr("Land") << tr("Sky") << + tr("Country") << tr("National") << tr("Earth") << tr("World"); + + LanguageIndex lg = generateDumpedNamesLanguage(); + + mainLayout = new QVBoxLayout; + tabs = new QTabWidget; + + generalTab = new QWidget; + metTab = new QWidget; + statsTab = new QWidget; + movesTab = new QWidget; + ribbonsTab = new QWidget; + + generalTabLayout = new QFormLayout; + metTabLayout = new QVBoxLayout; + statsTabLayout = new QVBoxLayout; + movesTabLayout = new QVBoxLayout; + ribbonsTabLayout = new QVBoxLayout; + + //-----------------------------"General" tab:----------------------------------------------- + + speciesFld = new QComboBox; + nameLayout = new QHBoxLayout; + nameFld = new QLineEdit; + resetNameButton = new QPushButton(tr("Reset")); + PIDFld = new UnsignedSpinbox<32>; + attributesFld = new QLabel; + abilityFld = new QComboBox; + experienceLevelAndSyncLayout = new QHBoxLayout; + levelAndSyncLayout = new QHBoxLayout; + experienceFld = new UnsignedSpinbox<32>; + levelFld = new UnsignedSpinbox<7>; + syncLevelAndExpFldsCheckBox = new QCheckBox; + + heldItemFld = new ItemComboBox; + happinessFld = new UnsignedSpinbox<8>; + pkrsStatusFld = new UnsignedSpinbox<8>; + statusFld = new QComboBox; + statusFld->addItems(statusNames()); + + for (size_t i = 0; i < 387; ++i) + speciesFld->addItem(Localization::getPokemonSpeciesNameByPkdxIndex(lg, i)); + + nameFld->setMaxLength(10); + nameLayout->addWidget(nameFld); + nameLayout->addWidget(resetNameButton); + abilityFld->addItem(Localization::getPokemonAbilityName(lg, NoAbility)); + abilityFld->setDisabled(true); + + levelFld->setRange(1, 100); + syncLevelAndExpFldsCheckBox->setChecked(true); + + + experienceLevelAndSyncLayout->addWidget(experienceFld,2); + levelAndSyncLayout->addWidget(levelFld,1); + levelAndSyncLayout->addWidget(syncLevelAndExpFldsCheckBox); + levelAndSyncLayout->setAlignment(Qt::AlignRight); + experienceLevelAndSyncLayout->addLayout(levelAndSyncLayout); + + markingsLayout = new QHBoxLayout; + markingsButtonGroup = new QButtonGroup; + circleMarkingCheckBox = new QCheckBox("\xe2\x97\x8f"); squareMarkingCheckBox = new QCheckBox("\xe2\x96\xa0"); + triangleMarkingCheckBox = new QCheckBox("\xe2\x96\xb2"); heartMarkingCheckBox = new QCheckBox("\xe2\x99\xa5"); + + markingsButtonGroup->setExclusive(false); + markingsButtonGroup->addButton(circleMarkingCheckBox); markingsButtonGroup->addButton(squareMarkingCheckBox); + markingsButtonGroup->addButton(triangleMarkingCheckBox); markingsButtonGroup->addButton(heartMarkingCheckBox); + markingsLayout->addWidget(circleMarkingCheckBox); markingsLayout->addWidget(squareMarkingCheckBox); + markingsLayout->addWidget(triangleMarkingCheckBox); markingsLayout->addWidget(heartMarkingCheckBox); + + generalTabLayout->addRow(tr("Species"), speciesFld); + generalTabLayout->addRow(tr("Name or nickname"), nameLayout); + generalTabLayout->addRow(tr("PID"), PIDFld); + generalTabLayout->addRow(tr("Attributes"), attributesFld); + generalTabLayout->addRow(tr("Ability"), abilityFld); + generalTabLayout->addRow(tr("Experience and level"), experienceLevelAndSyncLayout); + generalTabLayout->addRow(tr("Held item"), heldItemFld); + generalTabLayout->addRow(tr("Happiness"), happinessFld); + generalTabLayout->addRow(tr("Pok\xc3\xa9rus"), pkrsStatusFld); + generalTabLayout->addRow(tr("Status"), statusFld); + generalTabLayout->addRow(tr("Markings"), markingsLayout); + + + //---------------------------------------------------------------------------------------- + + + // ---------------------------------"Met" tab:--------------------------------------------- + + coreCaptureInfoBox = new QGroupBox(tr("Core information")); + OTBox = new QGroupBox(tr("Original trainer")); + versionBox = new QGroupBox(tr("Game version")); + + coreCaptureInfoLayout = new QFormLayout; + OTField = new TrainerInfoLayout; + versionFld = new VersionInfoLayout; + + ballCaughtWithFld = new ItemComboBox(POKEBALLS_ALLOWED | EMPTY_ITEM_FORBIDDEN); + locationCaughtFld = new UnsignedSpinbox<8>; + + metActionsLayout = new QHBoxLayout; + copyInfoFromSaveButton = new QPushButton(tr("Copy info from save")); + generateShinyIDsButton = new QPushButton(tr("Generate shiny IDs")); + + coreCaptureInfoLayout->addRow(tr("Ball caught with"), ballCaughtWithFld); + coreCaptureInfoLayout->addRow(tr("Location caught"), locationCaughtFld); + + coreCaptureInfoBox->setLayout(coreCaptureInfoLayout); + OTBox->setLayout(OTField); + versionBox->setLayout(versionFld); + + metActionsLayout->addWidget(copyInfoFromSaveButton); + metActionsLayout->addWidget(generateShinyIDsButton); + + metTabLayout->addWidget(coreCaptureInfoBox); + metTabLayout->addWidget(OTBox); + metTabLayout->addWidget(versionBox); + metTabLayout->addLayout(metActionsLayout); + + + //---------------------------------------------------------------------------------------- + + // --------------------------------"Stats" tab:-------------------------------------------- + + + statsSubTabs = new QTabWidget; + + + mainStatsTab = new QWidget; + + mainStatsLayout = new QVBoxLayout; + mainStatsTitleLayout = new QHBoxLayout; + mainStatsFormLayout = new QFormLayout; + + mainStatsTitleLayout->addWidget(new QLabel(tr("IV"))); + mainStatsTitleLayout->addWidget(new QLabel(tr("EV"))); + mainStatsTitleLayout->addWidget(new QLabel(tr("Stat"))); + + currentHPFld = new UnsignedSpinbox<16>; + mainStatsFormLayout->addRow(tr("Current HP"), currentHPFld); + mainStatsFormLayout->addRow("", mainStatsTitleLayout); + for (size_t i = 0; i < 6; ++i) { + mainStatsFlds[i] = new PokemonStatLayout; + mainStatsFormLayout->addRow(statNames[i], mainStatsFlds[i]); + connect(mainStatsFlds[i], SIGNAL(IVOrEVChanged()), this, SLOT(updateMainStats())); + } + + autoUpdateMainStatsCheckBox = new QCheckBox(tr("Update stats automatically")); + autoUpdateMainStatsCheckBox->setChecked(true); + + mainStatsLayout->addLayout(mainStatsFormLayout); + mainStatsLayout->addWidget(autoUpdateMainStatsCheckBox); + mainStatsTab->setLayout(mainStatsLayout); + + + contestStatsTab = new QWidget; + contestStatsLayout = new QFormLayout; + + contestStatsLusterFld = new UnsignedSpinbox<8>; + contestStatsLayout->addRow(tr("Luster"), contestStatsLusterFld); + for (size_t i = 0; i < 5; ++i) { + contestStatsFlds[i] = new UnsignedSpinbox<8>; + contestStatsLayout->addRow(contestStatNames[i], contestStatsFlds[i]); + } + contestStatsTab->setLayout(contestStatsLayout); + + statsSubTabs->addTab(mainStatsTab, tr("Main stats")); + statsSubTabs->addTab(contestStatsTab, tr("Contest stats")); + + statsTabLayout->addWidget(statsSubTabs); + //---------------------------------------------------------------------------------------- + + // --------------------------------"Moves" tab-------------------------------------------- + movesTabLayout->addStretch(); + + for (size_t i = 0; i < 4; ++i) { + moveLayouts[i] = new PokemonMoveLayout; + movesTabLayout->addLayout(moveLayouts[i]); + } + + movesTabLayout->addStretch(); + + //---------------------------------------------------------------------------------------- + + + // -------------------------------"Ribbons" tab------------------------------------------- + contestAchievementsBox = new QGroupBox(tr("Contest ribbons")); + contestAchievementsLayout = new QFormLayout; + contestTypeSelector = new QComboBox; + contestAchievementLevelFldsStack = new QStackedWidget; + + for (size_t i = 0; i < 5; ++i) { + contestAchievementFlds[i] = new QComboBox; + contestAchievementFlds[i]->addItems(contestAchivementLevelNames); + contestAchievementLevelFldsStack->addWidget(contestAchievementFlds[i]); + } + + contestTypeSelector->addItems(contestStatNames); + + contestAchievementsLayout->addRow(tr("Contest type"), contestTypeSelector); + contestAchievementsLayout->addRow(tr("Achievement"), contestAchievementLevelFldsStack); + + contestAchievementsBox->setLayout(contestAchievementsLayout); + + specialRibbonsBox = new QGroupBox(tr("Special ribbons")); + specialRibbonsLayout = new QGridLayout; + specialRibbonsFldGroup = new QButtonGroup; + specialRibbonsFldGroup->setExclusive(false); + + for (size_t i = 0; i < 12; ++i) { + specialRibbonsFlds[i] = new QCheckBox(srNames[i]); + specialRibbonsFldGroup->addButton(specialRibbonsFlds[i], (int)i); + specialRibbonsLayout->addWidget(specialRibbonsFlds[i], (int)(i % 4), (int)(i / 4)); + } + + specialRibbonsBox->setLayout(specialRibbonsLayout); + + ribbonsTabLayout->addWidget(contestAchievementsBox); + ribbonsTabLayout->addWidget(specialRibbonsBox); + //---------------------------------------------------------------------------------------- + + + + + generalTab->setLayout(generalTabLayout); + metTab->setLayout(metTabLayout); + statsTab->setLayout(statsTabLayout); + movesTab->setLayout(movesTabLayout); + ribbonsTab->setLayout(ribbonsTabLayout); + + tabs->addTab(generalTab, tr("General")); + tabs->addTab(metTab, tr("Met/OT")); + tabs->addTab(statsTab, tr("Stats")); + tabs->addTab(movesTab, tr("Moves")); + tabs->addTab(ribbonsTab, tr("Ribbons")); + + mainLayout->addWidget(tabs); + DataUI::initWidget(); + + connect(speciesFld, SIGNAL(currentIndexChanged(int)), this, SLOT(speciesChangeHandler())); + connect(resetNameButton, SIGNAL(clicked()), this, SLOT(resetName())); + connect(PIDFld, SIGNAL(valueChanged(int)), this, SLOT(PIDChangeHandler())); + connect(experienceFld, SIGNAL(valueChanged(int)), this, SLOT(updateLevelFromExperience())); + connect(levelFld, SIGNAL(valueChanged(int)), this, SLOT(updateExperienceFromLevel())); + connect(OTField, SIGNAL(TIDorSIDChanged()), this, SLOT(updatePkmAttributes())); + connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler())); + connect(copyInfoFromSaveButton, SIGNAL(clicked()), this, SLOT(copyInfoFromSave())); + connect(generateShinyIDsButton, SIGNAL(clicked()), this, SLOT(generateShinyIDs())); + connect(autoUpdateMainStatsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(autoUpdateStatsStateChangeHanler())); + connect(contestTypeSelector, SIGNAL(currentIndexChanged(int)), contestAchievementLevelFldsStack, SLOT(setCurrentIndex(int))); +} + +void PokemonUI::parseData(void){ + if (pkm == NULL) return; + copyInfoFromSaveButton->setDisabled(currentSaveSlot == NULL); + + // Blocking signals have a strange yet enormous cost on the main window when loading the save + + autoUpdateMainStatsCheckBox->setChecked(false); + syncLevelAndExpFldsCheckBox->setChecked(false); + + LanguageIndex lg = generateDumpedNamesLanguage(); + isXD = LIBPKMGC_IS_XD(Pokemon, pkm); + + + if (isXD && (speciesFld->count() == 387)) + speciesFld->addItem(Localization::getPokemonSpeciesName(lg, Bonsly)); + else if (!isXD && (speciesFld->count() == 388)) + speciesFld->removeItem(387); + heldItemFld->set(GIVABLE_ITEMS_ALLOWED, isXD); + + + nameFld->setText(pkm->name->toUTF8()); + + speciesFld->setCurrentIndex((int)Localization::pkmSpeciesIndexToNameIndex(pkm->species)); + PIDFld->setUnsignedValue(pkm->PID); + + + u32 maxExperience = Pokemon::calculateExpFromLevel(nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()), 100); + experienceFld->setUnsignedRange(0, maxExperience); + experienceFld->setUnsignedValue(pkm->experience); + levelFld->setUnsignedValue(pkm->partyData.level); + syncLevelAndExpFldsCheckBox->setChecked(true); + + + heldItemFld->setCurrentItemIndex(pkm->heldItem); + happinessFld->setUnsignedValue(pkm->happiness); + pkrsStatusFld->setUnsignedValue(pkm->pkrsStatus); + statusFld->setCurrentIndex((pkm->partyData.status == NoStatus) ? 0 : (int)pkm->partyData.status - 2); + + circleMarkingCheckBox->setChecked(pkm->markings.circle); + squareMarkingCheckBox->setChecked(pkm->markings.square); + triangleMarkingCheckBox->setChecked(pkm->markings.triangle); + heartMarkingCheckBox->setChecked(pkm->markings.heart); + + ballCaughtWithFld->setCurrentItemIndex(pkm->ballCaughtWith); + locationCaughtFld->setUnsignedValue(pkm->locationCaught); + OTField->set(pkm->OTName, pkm->TID, pkm->SID, pkm->OTGender); + + versionFld->disconnect(SIGNAL(versionChanged())); + versionFld->setInfo(pkm->version); + connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler())); + + + for (size_t i = 0; i < 6; ++i) { + PokemonStatLayout* l = mainStatsFlds[i]; + l->IVFld->setUnsignedValue(pkm->IVs[i]); + l->EVFld->setUnsignedValue(pkm->EVs[i]); + l->statFld->setUnsignedValue(pkm->partyData.stats[i]); + } + + for (size_t i = 0; i < 5; ++i) + contestAchievementFlds[i]->setCurrentIndex((int)pkm->contestAchievements[i]); + + for (size_t i = 0; i < 12; ++i) + specialRibbonsFlds[i]->setChecked(pkm->specialRibbons[i]); + + for (size_t i = 0; i < 4; ++i) + moveLayouts[i]->setMove(pkm->moves[i]); + + autoUpdateMainStatsCheckBox->setChecked(true); + versionChangeHandler(); + + abilityFld->setCurrentIndex(pkm->hasSpecialAbility()); + +} + +void PokemonUI::saveChanges(void){ + pkm->species = nameIndexToPkmSpeciesIndex(speciesFld->currentIndex()); + pkm->name->fromUTF8(nameFld->text().toUtf8().data()); + pkm->PID = PIDFld->unsignedValue(); + + pkm->setSpecialAbilityStatus(abilityFld->currentIndex() != 0); + pkm->experience = experienceFld->unsignedValue(); + pkm->partyData.level = (u8)levelFld->unsignedValue(); + + pkm->heldItem = heldItemFld->currentItemIndex(); + pkm->happiness = (u8)happinessFld->unsignedValue(); + pkm->pkrsStatus = (u8)pkrsStatusFld->unsignedValue(); + pkm->partyData.status = (statusFld->currentIndex() == 0) ? NoStatus : (PokemonStatus)(2 + statusFld->currentIndex()); + + pkm->markings.circle = circleMarkingCheckBox->isChecked(); + pkm->markings.square = squareMarkingCheckBox->isChecked(); + pkm->markings.triangle = triangleMarkingCheckBox->isChecked(); + pkm->markings.heart = heartMarkingCheckBox->isChecked(); + + pkm->ballCaughtWith = ballCaughtWithFld->currentItemIndex(); + pkm->locationCaught = (u8)locationCaughtFld->unsignedValue(); + + OTField->trainerName(pkm->OTName); + pkm->TID = OTField->TID(); + pkm->SID = OTField->SID(); + pkm->OTGender = OTField->trainerGender(); + + pkm->version = versionFld->info(); + + for (size_t i = 0; i < 6; ++i) { + PokemonStatLayout* l = mainStatsFlds[i]; + pkm->IVs[i] = (u8)l->IVFld->unsignedValue(); + pkm->EVs[i] = (u8)l->EVFld->unsignedValue(); + pkm->partyData.stats[i] = (u16)l->statFld->unsignedValue(); + } + + for (size_t i = 0; i < 4; ++i) + pkm->moves[i] = moveLayouts[i]->move(); + for (size_t i = 0; i < 5; ++i) + pkm->contestAchievements[i] = (ContestAchievementLevel) contestAchievementFlds[i]->currentIndex(); + for (size_t i = 0; i < 12; ++i) + pkm->specialRibbons[i] = specialRibbonsFlds[i]->isChecked(); +} + +QString PokemonUI::getShortPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species, LibPkmGC::u32 PID, LibPkmGC::u16 TID, LibPkmGC::u16 SID){ + QString ret; + + bool shiny = Base::Pokemon::isShiny(PID, TID,SID); + if (shiny) { + ret += "\xe2\x98\x85"; + } + + if (Base::Pokemon::getGender(species, PID) == Male) + ret += "\xe2\x99\x82"; + + else if (Base::Pokemon::getGender(species, PID) == Female) + ret += "\xe2\x99\x80"; + else { + if (!ret.isEmpty()) ret += ", "; + + ret += ""; + ret += tr("Genderless"); + ret += ""; + } + return ret; +} + +QString PokemonUI::getLongPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species, LibPkmGC::u32 PID, LibPkmGC::u16 TID, LibPkmGC::u16 SID) +{ + QString ret = getShortPkmAttributeText(species, PID, TID, SID); + LanguageIndex lg = generateDumpedNamesLanguage(); + + if (!ret.isEmpty()) ret += ", "; + + ret += getPokemonNatureName(lg, Base::Pokemon::getNature(PID)); + if (species == Unown) { + if (!ret.isEmpty()) ret += ", "; + ret += tr("Unown form: "); + ret += Base::Pokemon::getUnownForm(PID); + } + if (species == Wurmple) { + if (!ret.isEmpty()) ret += ", "; + ret += tr("will evolve into: "); + ret += getPokemonSpeciesName(lg, Base::Pokemon::getWurmpleEvolution(PID)); + } + return ret; +} + +QString PokemonUI::getShortPkmAttributeText(void){ + const QString invalid = "INVALID"; + QString ret, tt; + if (pkm == NULL || speciesFld->currentIndex() == 0) return ""; + + if (versionFld->info().isIncomplete()) + tt = tr("Invalid version info"); + if (isXD && (static_cast(pkm)->pkmFlags & 0x20) != 0) { + if (!tt.isEmpty()) tt += "\n"; + tt += tr("Bit 5 set on byte at offset 0x1d"); + } + + attributesFld->setToolTip(tt); + + if (!tt.isEmpty()) { + return invalid; + } + + u32 PID = (u32)PIDFld->value(); + PokemonSpeciesIndex species = nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()); + u16 TID = OTField->TID(), SID = OTField->SID(); + return getShortPkmAttributeText(species, PID, TID, SID); +} + +QString PokemonUI::getLongPkmAttributeText(void){ + const QString invalid = "INVALID"; + QString ret, tt; + if (pkm == NULL || speciesFld->currentIndex() == 0) return ""; + + if (versionFld->info().isIncomplete()) + tt = tr("Invalid version info"); + if (isXD && (static_cast(pkm)->pkmFlags & 0x20) != 0) { + if (!tt.isEmpty()) tt += "\n"; + tt += tr("Bit 5 set on byte at offset 0x1d"); + } + + attributesFld->setToolTip(tt); + + if (!tt.isEmpty()) { + return invalid; + } + + u32 PID = (u32)PIDFld->value(); + PokemonSpeciesIndex species = nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()); + u16 TID = OTField->TID(), SID = OTField->SID(); + + return getLongPkmAttributeText(species, PID, TID, SID); +} + +void PokemonUI::updateMainStats(void) { + if (autoUpdateMainStatsCheckBox->isChecked()) { + for (size_t i = 0; i < 6; ++i) { + PokemonSpeciesIndex id = (PokemonSpeciesIndex)Localization::nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()); + PokemonStatLayout* l = mainStatsFlds[i]; + PokemonNatureIndex natureIndex = (PokemonNatureIndex)((u32)PIDFld->value() % 25); + u16 stat = Base::Pokemon::calculateStat(i, id, natureIndex, + (u8) levelFld->value(), (u8) l->IVFld->value(), (u8) l->EVFld->value()); + l->statFld->setValue((int)stat); + } + currentHPFld->setValue(mainStatsFlds[0]->statFld->value()); + } +} + +void PokemonUI::updatePkmAttributes(void) { + attributesFld->setText(getLongPkmAttributeText()); +} + +void PokemonUI::updateAbilityList(void) { + LanguageIndex lg = generateDumpedNamesLanguage(); + PokemonSpeciesIndex id = Localization::nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()); + const PokemonAbilityIndex* ab = getSpeciesData(id).possibleAbilities; + + abilityFld->clear(); + abilityFld->addItem(Localization::getPokemonAbilityName(lg, ab[0])); + if (ab[1] != NoAbility) { + abilityFld->addItem(Localization::getPokemonAbilityName(lg, ab[1])); + abilityFld->setDisabled(false); + return; + } + else { + abilityFld->setDisabled(true); + return; + } +} + + +void PokemonUI::updateExperienceFromLevel(void) { + if (syncLevelAndExpFldsCheckBox->isChecked()) { + u8 lvl = Pokemon::calculateLevelFromExp(nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()), (u32)experienceFld->value()); + if (lvl == levelFld->unsignedValue()) return; + u32 experience = Pokemon::calculateExpFromLevel(nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()), (u8)levelFld->value()); + + experienceFld->disconnect(SIGNAL(valueChanged(int))); + experienceFld->setValue((int)experience); + connect(experienceFld, SIGNAL(valueChanged(int)), this, SLOT(updateLevelFromExperience())); + } +} + +void PokemonUI::updateLevelFromExperience(void) { + if (syncLevelAndExpFldsCheckBox->isChecked()) { + u8 lvl = Pokemon::calculateLevelFromExp(nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()), (u32)experienceFld->value()); + + levelFld->disconnect(SIGNAL(valueChanged(int))); + levelFld->setValue((int)lvl); + connect(levelFld, SIGNAL(valueChanged(int)), this, SLOT(updateExperienceFromLevel())); + } +} + +void PokemonUI::speciesChangeHandler(void) { + updatePkmAttributes(); + autoUpdateStatsStateChangeHanler(); // update stats etc... + updateAbilityList(); + u32 maxExperience = Pokemon::calculateExpFromLevel(nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex()), 100); + experienceFld->setUnsignedRange(0, maxExperience); + updateExperienceFromLevel(); +} + +void PokemonUI::PIDChangeHandler(void) { + updatePkmAttributes(); + updateMainStats(); +} + +void PokemonUI::autoUpdateStatsStateChangeHanler(void) { + bool checked = autoUpdateMainStatsCheckBox->isChecked(); + if (checked) updateMainStats(); + currentHPFld->setDisabled(checked); + for (size_t i = 0; i < 6; ++i) mainStatsFlds[i]->statFld->setDisabled(checked); +} + +void PokemonUI::versionChangeHandler(void) { + if (pkm == NULL) return; + VersionInfo v = versionFld->info(); + QLabel* l = (QLabel*) coreCaptureInfoLayout->labelForField(locationCaughtFld); + if (v.game != Colosseum_XD) + l->setText(tr("Location caught (see here)")); + else + l->setText(tr("Location caught (see here)")); + + l->setOpenExternalLinks(true); + + if (speciesFld->currentIndex() != 0 && v.isIncomplete()) + QMessageBox::warning(this, tr("Warning"), tr("The version info you specified is invalid. The game will therefore consider this Pok\xc3\xa9mon invalid.")); + + updatePkmAttributes(); +} + +void PokemonUI::resetName(void) { + nameFld->setText(getPokemonSpeciesName(versionFld->info().language, nameIndexToPkmSpeciesIndex(speciesFld->currentIndex()))); +} + +void PokemonUI::copyInfoFromSave(void) { + GC::PlayerData* pl = currentSaveSlot->player; + OTField->set(pl->trainerName, pl->TID, pl->SID, pl->trainerGender); + versionFld->setInfo(currentSaveSlot->version); +} + +void PokemonUI::generateShinyIDs(void) { + OTField->setTID((u16)(PIDFld->unsignedValue() >> 16)); + OTField->setSID((u16)PIDFld->unsignedValue()); +} + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/PokemonUI.h b/PkmGCSaveEditor/src/GCUIs/PokemonUI.h new file mode 100644 index 0000000..03b7219 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/PokemonUI.h @@ -0,0 +1,188 @@ +#ifndef _PKMGCSAVEEDITOR_POKEMON_UI_H +#define _PKMGCSAVEEDITOR_POKEMON_UI_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace GCUIs { + +class PokemonStatLayout : public QHBoxLayout { + Q_OBJECT +public: + PokemonStatLayout(LibPkmGC::u8 inIV = 0, LibPkmGC::u8 inEV = 0, LibPkmGC::u16 inStat = 0); + + UnsignedSpinbox<5> *IVFld; + UnsignedSpinbox<8> *EVFld; + UnsignedSpinbox<16> *statFld; + +public slots: + void IVOrEVChangedEmitter(void); +signals: + void IVOrEVChanged(void); +}; + +class PokemonMoveLayout : public QHBoxLayout { + Q_OBJECT +public: + PokemonMoveLayout(LibPkmGC::PokemonMove const& inMove = LibPkmGC::PokemonMove()); + + LibPkmGC::PokemonMove move(void) const; + void setMove(LibPkmGC::PokemonMove const& inMove); + +private: + + QComboBox *moveNameFld; + UnsignedSpinbox<7> *currentPPsFld; + QLabel *maxPPsFld; + UnsignedSpinbox<2> *nbPPUpsUsedFld; + QLabel* nbPPUpsUsedText; + + +public slots: + void updateFields(void); + +}; + +class PokemonUI : public DataUI { + Q_OBJECT +public: + PokemonUI(LibPkmGC::GC::Pokemon* inPkm = NULL, LibPkmGC::PokemonStorageInfo const& inLocation = LibPkmGC::emptyStorageInfo, QWidget* parent = NULL, + Qt::WindowFlags f = Qt::Window); + + + static QStringList statusNames(void); + + void parseData(void); + void saveChanges(void); + + static QString getShortPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species, LibPkmGC::u32 PID, LibPkmGC::u16 TID, LibPkmGC::u16 SID); + static QString getLongPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species, LibPkmGC::u32 PID, LibPkmGC::u16 TID, LibPkmGC::u16 SID); + QString getShortPkmAttributeText(void); + QString getLongPkmAttributeText(void); + + LibPkmGC::GC::Pokemon* pkm; + + LibPkmGC::PokemonStorageInfo location; +protected: + virtual void initWidget(void); + +private: + QTabWidget* tabs; + + QWidget *generalTab, *metTab; + QFormLayout *generalTabLayout; + QVBoxLayout *metTabLayout; + + // "General" tab: + QComboBox *speciesFld; + QHBoxLayout* nameLayout; + QLineEdit* nameFld; + QPushButton *resetNameButton; + + UnsignedSpinbox<32>* PIDFld; + QLabel *attributesFld; + + QComboBox* abilityFld; + + QHBoxLayout* experienceLevelAndSyncLayout; + QHBoxLayout* levelAndSyncLayout; + UnsignedSpinbox<32>* experienceFld; + UnsignedSpinbox<7>* levelFld; + QCheckBox* syncLevelAndExpFldsCheckBox; + + ItemComboBox* heldItemFld; + UnsignedSpinbox<8>* happinessFld; + UnsignedSpinbox<8>* pkrsStatusFld; + + QComboBox* statusFld; + + QHBoxLayout* markingsLayout; + QButtonGroup* markingsButtonGroup; + QCheckBox *circleMarkingCheckBox, *squareMarkingCheckBox, *triangleMarkingCheckBox, *heartMarkingCheckBox; + + + // "Met" tab: + QGroupBox* coreCaptureInfoBox; + QFormLayout* coreCaptureInfoLayout; + ItemComboBox* ballCaughtWithFld; + UnsignedSpinbox<8>* locationCaughtFld; + + QGroupBox* OTBox; + TrainerInfoLayout* OTField; + + QGroupBox* versionBox; + VersionInfoLayout* versionFld; + + QHBoxLayout* metActionsLayout; + QPushButton *copyInfoFromSaveButton, *generateShinyIDsButton; + + // "Stats" tab: + QWidget* statsTab; + QVBoxLayout* statsTabLayout; + QTabWidget* statsSubTabs; + QWidget* mainStatsTab; + QVBoxLayout* mainStatsLayout; + QCheckBox* autoUpdateMainStatsCheckBox; + QHBoxLayout *mainStatsTitleLayout; + QFormLayout* mainStatsFormLayout; + UnsignedSpinbox<16>* currentHPFld; + PokemonStatLayout *mainStatsFlds[6]; + + QWidget* contestStatsTab; + QFormLayout* contestStatsLayout; + UnsignedSpinbox<8>* contestStatsLusterFld; + UnsignedSpinbox<8>* contestStatsFlds[5]; + + // "Moves" tab: + QWidget* movesTab; + QVBoxLayout* movesTabLayout; + //QHBoxLayout* movesTitleLayout; + PokemonMoveLayout* moveLayouts[4]; + + // "Ribbons" tab: + QWidget* ribbonsTab; + QVBoxLayout *ribbonsTabLayout; + QGroupBox *contestAchievementsBox; + QFormLayout *contestAchievementsLayout; + QComboBox *contestTypeSelector; + QStackedWidget* contestAchievementLevelFldsStack; + QComboBox* contestAchievementFlds[5]; + QGroupBox *specialRibbonsBox; + QGridLayout *specialRibbonsLayout; + QButtonGroup *specialRibbonsFldGroup; + QCheckBox *specialRibbonsFlds[12]; + + +public slots: + void updateMainStats(void); + void updatePkmAttributes(void); + void updateAbilityList(void); + void updateExperienceFromLevel(void); + void updateLevelFromExperience(void); + void speciesChangeHandler(void); + void PIDChangeHandler(void); + void autoUpdateStatsStateChangeHanler(void); + + void versionChangeHandler(void); + + void resetName(void); + void copyInfoFromSave(void); + void generateShinyIDs(void); +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.cpp b/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.cpp new file mode 100644 index 0000000..f6dcf4f --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.cpp @@ -0,0 +1,107 @@ +#include +using namespace LibPkmGC; +using namespace Localization; + +namespace GCUIs { + +StrategyMemoEntryWidget::StrategyMemoEntryWidget(LibPkmGC::GC::StrategyMemoEntry* inEntry, int inEntryIndex, QWidget* parent) : QWidget(parent), IDataUI(), +entry(inEntry), entryIndex(inEntryIndex) { + init(); +} + + +void StrategyMemoEntryWidget::updatePIDText(void) { + if (speciesSelector->currentIndex() == 0 && firstTIDFld->unsignedValue() == 0 && firstSIDFld->unsignedValue() == 0) { + PIDText->setText(tr("(randomly generated)")); + return; + } + + if (Base::Pokemon::isShiny(firstPIDFld->unsignedValue(), (u16)firstTIDFld->unsignedValue(), (u16)firstSIDFld->unsignedValue()) && !isXD) { + PIDText->setText("\xe2\x98\x85"); + } + else { + PIDText->setText(""); + } +} + +void StrategyMemoEntryWidget::generateShinyPID(void) { + u32 PID = firstPIDFld->unsignedValue(); + PID &= 0xffff0000; + PID |= (PID >> 16) ^ firstSIDFld->unsignedValue() ^ firstTIDFld->unsignedValue(); + firstPIDFld->setUnsignedValue(PID); +} + +void StrategyMemoEntryWidget::initWidget(void) { + LanguageIndex lg = generateDumpedNamesLanguage(); + mainLayout = new QVBoxLayout; + mainLayout2 = new QFormLayout; + speciesSelector = new QComboBox; + + partialInfoCheckBox = new QCheckBox; + + firstTIDFld = new UnsignedSpinbox<16>; + firstSIDFld = new UnsignedSpinbox<16>; + PIDLayout = new QVBoxLayout; + firstPIDFld = new UnsignedSpinbox<32>; + PIDText = new QLabel; + generateShinyPIDButton = new QPushButton(tr("Generate shiny PID")); + + for (size_t i = 0; i <= 386; ++i) + speciesSelector->addItem(getPokemonSpeciesNameByPkdxIndex(lg, (u16)i)); + + PIDLayout->addWidget(firstPIDFld); + PIDLayout->addWidget(PIDText); + + mainLayout2->addRow(tr("Species"), speciesSelector); + mainLayout2->addRow(tr("First TID"), firstTIDFld); + mainLayout2->addRow(tr("First SID"), firstSIDFld); + mainLayout2->addRow(tr("First PID"), PIDLayout); + mainLayout2->addRow(tr("Partial information"), partialInfoCheckBox); + mainLayout->addLayout(mainLayout2); + mainLayout->addWidget(generateShinyPIDButton); + + mainLayout2->setHorizontalSpacing(20); + this->setLayout(mainLayout); + + + connect(speciesSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(speciesChangeHandler(int))); + connect(firstPIDFld, SIGNAL(valueChanged(int)), this, SLOT(updatePIDText())); + connect(generateShinyPIDButton, SIGNAL(clicked()), this, SLOT(generateShinyPID())); +} + +StrategyMemoEntryWidget::~StrategyMemoEntryWidget(void) { +} + +void StrategyMemoEntryWidget::parseData(void) { + if (entry == NULL) return; + isXD = LIBPKMGC_IS_XD(StrategyMemoEntry, entry); + + generateShinyPIDButton->setVisible(!isXD); + partialInfoCheckBox->setChecked(entry->isInfoPartial()); + partialInfoCheckBox->setDisabled(isXD); + + speciesSelector->setCurrentIndex(pkmSpeciesIndexToNameIndex(entry->species)); + + firstSIDFld->setUnsignedValue(entry->firstSID); + firstTIDFld->setUnsignedValue(entry->firstTID); + firstPIDFld->setUnsignedValue(entry->firstPID); + updatePIDText(); +} + +void StrategyMemoEntryWidget::saveChanges(void) { + entry->setInfoCompleteness(partialInfoCheckBox->isChecked()); + entry->species = nameIndexToPkmSpeciesIndex(speciesSelector->currentIndex()); + entry->firstSID = (u16)firstSIDFld->unsignedValue(); + entry->firstTID = (u16)firstTIDFld->unsignedValue(); + entry->firstPID = firstPIDFld->unsignedValue(); +} + + +void StrategyMemoEntryWidget::speciesChangeHandler(int nameIndex) { + generateShinyPIDButton->setDisabled(nameIndex == 0); + updatePIDText(); + emit speciesChanged(entryIndex, nameIndex); +} + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.h b/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.h new file mode 100644 index 0000000..fbdbbc0 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/StrategyMemoEntryWidget.h @@ -0,0 +1,57 @@ +#ifndef _PKMGCSAVEEDITOR_STRATEGY_MEMO_ENTRY_WIDGET_H +#define _PKMGCSAVEEDITOR_STRATEGY_MEMO_ENTRY_WIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace GCUIs { + +class StrategyMemoEntryWidget : public QWidget, public IDataUI { + Q_OBJECT +public: + StrategyMemoEntryWidget(LibPkmGC::GC::StrategyMemoEntry* inEntry = NULL, int inEntryIndex = 0, QWidget* parent = NULL); + ~StrategyMemoEntryWidget(void); + + LibPkmGC::GC::StrategyMemoEntry *entry, *entryBackup; + int entryIndex; + + void parseData(void); + void saveChanges(void); + +signals: + void speciesChanged(int index, size_t nameIndex); + public slots: + void speciesChangeHandler(int nameIndex); + void updatePIDText(void); + void generateShinyPID(void); +protected: + void initWidget(void); + +private: + bool isXD; + QVBoxLayout *mainLayout; + QFormLayout *mainLayout2; + QComboBox *speciesSelector; + + QCheckBox *partialInfoCheckBox; + + UnsignedSpinbox<16> *firstTIDFld, *firstSIDFld; + QVBoxLayout* PIDLayout; + UnsignedSpinbox<32> *firstPIDFld; + QLabel* PIDText; + QPushButton* generateShinyPIDButton; +}; + + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.cpp b/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.cpp new file mode 100644 index 0000000..fbd142c --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.cpp @@ -0,0 +1,87 @@ +#include +using namespace LibPkmGC; +using namespace Localization; + +namespace GCUIs { + + +StrategyMemoUI::StrategyMemoUI(GC::StrategyMemoData* inStrategyMemo, QWidget* parent, Qt::WindowFlags f) : DataUI(parent, f), strategyMemo(inStrategyMemo), +strategyMemoBackup(NULL){ + init(); +} + +StrategyMemoUI::~StrategyMemoUI(void) { + delete strategyMemoBackup; +} + +void StrategyMemoUI::initWidget(void) { + LanguageIndex lg = generateDumpedNamesLanguage(); + entrySelectorLayout = new QFormLayout; + entrySelector = new QComboBox; + + nbEntriesFld = new UnsignedSpinbox<16>; + currentEntry = new StrategyMemoEntryWidget; + connect(currentEntry, SIGNAL(speciesChanged(int, size_t)), this, SLOT(updateEntryNameAndNbEntries(int, size_t))); + + QString tmpl(tr("#%1: %2")); + + for (size_t i = 0; i < 500; ++i) + entrySelector->addItem(tmpl.arg((int)i).arg(getPokemonSpeciesName(lg, NoSpecies))); + + entrySelectorLayout->addRow(tr("Number of entries"), nbEntriesFld); + entrySelectorLayout->addRow(tr("Entry"), entrySelector); + mainLayout->addLayout(entrySelectorLayout); + mainLayout->addStretch(); + mainLayout->addWidget(currentEntry); + mainLayout->addStretch(); + DataUI::initWidget(); + + connect(entrySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentEntry(int))); +} + +void StrategyMemoUI::updateEntryName(int index, size_t nameIndex) { + LanguageIndex lg = generateDumpedNamesLanguage(); + QString tmpl(tr("#%1: %2")); + + entrySelector->setItemText(index, tmpl.arg(index+1).arg(getPokemonSpeciesName(lg, nameIndexToPkmSpeciesIndex(nameIndex)))); +} + + + +void StrategyMemoUI::parseData(void) { + if (strategyMemo == NULL) return; + if (strategyMemoBackup == NULL) strategyMemoBackup = strategyMemo->clone(); + isXD = strategyMemo->isXD(); + for (int i = 0; i < 500; ++i) { + updateEntryName(i, pkmSpeciesIndexToNameIndex(strategyMemo->entries[i]->species)); + } + updateEntryNameAndNbEntries(0, pkmSpeciesIndexToNameIndex(strategyMemo->entries[0]->species)); + setCurrentEntry(0); +} + +void StrategyMemoUI::saveChanges(void) { + currentEntry->saveChanges(); + delete strategyMemoBackup; + strategyMemoBackup = strategyMemo->clone(); +} + +void StrategyMemoUI::cancelChanges(void) { + *strategyMemo = *strategyMemoBackup; +} + +void StrategyMemoUI::setCurrentEntry(int index) { + if (currentEntry->entry != NULL) currentEntry->saveChanges(); + currentEntry->entry = strategyMemo->entries[index]; + currentEntry->entryIndex = index; + currentEntry->parseData(); +} + + +void StrategyMemoUI::updateEntryNameAndNbEntries(int index, size_t nameIndex) { + updateEntryName(index, nameIndex); + strategyMemo->entries[index]->species = nameIndexToPkmSpeciesIndex(nameIndex); + strategyMemo->nbEntries = strategyMemo->recount(); + nbEntriesFld->setUnsignedValue(strategyMemo->nbEntries); +} + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.h b/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.h new file mode 100644 index 0000000..2f008e9 --- /dev/null +++ b/PkmGCSaveEditor/src/GCUIs/StrategyMemoUI.h @@ -0,0 +1,36 @@ +#ifndef _PKMGCSAVEEDITOR_STRATEGY_MEMO_UI_H +#define _PKMGCSAVEEDITOR_STRATEGY_MEMO_UI_H + +#include + +namespace GCUIs { + +class StrategyMemoUI : public DataUI { + Q_OBJECT +public: + StrategyMemoUI(LibPkmGC::GC::StrategyMemoData* inStrategyMemo = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + ~StrategyMemoUI(void); + + LibPkmGC::GC::StrategyMemoData* strategyMemo; + LibPkmGC::GC::StrategyMemoData* strategyMemoBackup; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); +public slots: + void updateEntryNameAndNbEntries(int index, size_t nameIndex); + void setCurrentEntry(int index); +protected: + void initWidget(void); +private: + void updateEntryName(int index, size_t nameIndex); + QFormLayout *entrySelectorLayout; + UnsignedSpinbox<16>* nbEntriesFld; + QComboBox *entrySelector; + + StrategyMemoEntryWidget* currentEntry; // we cannot use a QStackedWidget here +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/MainWindow.cpp b/PkmGCSaveEditor/src/MainWindow.cpp new file mode 100644 index 0000000..28ad4aa --- /dev/null +++ b/PkmGCSaveEditor/src/MainWindow.cpp @@ -0,0 +1,458 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace GCUIs; +using namespace XDUIs; +using namespace LibPkmGC; + + +MWCentralWidget::MWCentralWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), mainLayout(new QVBoxLayout) { + gameConfigButton = new QPushButton; + playerButton = new QPushButton; + PCButton = new QPushButton; + daycareButton = new QPushButton; + strategyMemoButton = new QPushButton; + purifierButton = new QPushButton; + + updateText(); + QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, purifierButton }; + + for (int i = 0; i < 6; ++i) + mainLayout->addWidget(lst[i]); + + this->setLayout(mainLayout); + connect(gameConfigButton, SIGNAL(clicked()), this, SLOT(openGameConfigUI())); + connect(playerButton, SIGNAL(clicked()), this, SLOT(openPlayerUI())); + connect(PCButton, SIGNAL(clicked()), this, SLOT(openPCUI())); + connect(daycareButton, SIGNAL(clicked()), this, SLOT(openDaycareUI())); + connect(strategyMemoButton, SIGNAL(clicked()), this, SLOT(openStrategyMemoUI())); + connect(purifierButton, SIGNAL(clicked()), this, SLOT(openPurifierUI())); + + currentSaveSlotChangeHandler(); +} + +void MWCentralWidget::updateText(void) { + gameConfigButton->setText(tr("Game configuration")); + playerButton->setText(tr("Trainer info, Party and Bag")); + PCButton->setText(tr("PC")); + daycareButton->setText(tr("Daycare")); + strategyMemoButton->setText(tr("Strategy memo")); + purifierButton->setText(tr("Purifier")); +} + +void MWCentralWidget::currentSaveSlotChangeHandler(void) { + QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, purifierButton }; + for (size_t i = 0; i < 6; ++i) + lst[i]->setDisabled(currentSaveSlot == NULL); + purifierButton->setVisible(currentSaveSlot != NULL && LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot)); +} + +#define GEN_GCUI_SLT(cls, obj)\ +void MWCentralWidget::open##cls(void){\ +cls dlg(obj, this); \ +dlg.exec();\ +} + +GEN_GCUI_SLT(GameConfigUI, currentSaveSlot) +GEN_GCUI_SLT(PlayerUI, currentSaveSlot->player) +GEN_GCUI_SLT(PCUI, currentSaveSlot->PC) +GEN_GCUI_SLT(DaycareUI, currentSaveSlot->daycare) +GEN_GCUI_SLT(StrategyMemoUI, currentSaveSlot->strategyMemo) + +void MWCentralWidget::openPurifierUI(void) { + if (!LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot)) return; + PurifierUI dlg(static_cast(currentSaveSlot)->purifier, this); + dlg.exec(); +} + + +MainWindow::MainWindow() : QMainWindow(), centralWidget(new MWCentralWidget) { + fileMenu = menuBar()->addMenu(tr("&File")); + + openFileAction = new QAction(this); + openFileAction->setShortcut(QKeySequence::Open); + saveFileAction = new QAction(this); + saveFileAction->setShortcut(QKeySequence::Save); + saveFileAsAction = new QAction(this); + saveFileAsAction->setShortcut(QKeySequence::SaveAs); + exitAction = new QAction(this); + exitAction->setShortcut(QKeySequence::Quit); + + fileMenu->addAction(openFileAction); + fileMenu->addAction(saveFileAction); + fileMenu->addAction(saveFileAsAction); + fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + optionsMenu = menuBar()->addMenu(tr("&Options")); + interfaceLangSubMenu = optionsMenu->addMenu(tr("&Interface language")); + dumpedNamesLangSubMenu = optionsMenu->addMenu(tr("&Dumped names language")); + + + setCentralWidget(centralWidget); + + connect(openFileAction, SIGNAL(triggered()), this, SLOT(openSaveFile())); + connect(saveFileAction, SIGNAL(triggered()), this, SLOT(saveSaveFile())); + connect(saveFileAsAction, SIGNAL(triggered()), this, SLOT(saveSaveFileAs())); + connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); + + loadSettings(); + createInterfaceLanguageMenu(); + createDumpedNamesLanguageMenu(); + interfaceLanguageChanged(interfaceLangGroup->checkedAction()); + dumpedNamesLanguageChanged(dumpedNamesLangGroup->actions()[(size_t)dumpedNamesLanguage]); + + updateStatusBar(); +} + +void MainWindow::createDumpedNamesLanguageMenu(void) { + dumpedNamesLangGroup = new QActionGroup(dumpedNamesLangSubMenu); + dumpedNamesLangGroup->setExclusive(true); + + QAction* select_auto = new QAction(this); + select_auto->setCheckable(true); + select_auto->setData(0); + + connect(dumpedNamesLangGroup, SIGNAL(triggered(QAction*)), this, SLOT(dumpedNamesLanguageChanged(QAction*))); + + dumpedNamesLangGroup->addAction(select_auto); + dumpedNamesLangSubMenu->addAction(select_auto); + + for (int i = 1; i < 7; ++i) { + QAction* action = new QAction(this); + action->setCheckable(true); + action->setData(i); + dumpedNamesLangGroup->addAction(action); + dumpedNamesLangSubMenu->addAction(action); + } + + dumpedNamesLangGroup->actions()[(size_t)dumpedNamesLanguage]->setChecked(true); +} + +void MainWindow::createInterfaceLanguageMenu(void) { + // Adapted from : https://wiki.qt.io/How_to_create_a_multi_language_application + interfaceLangGroup = new QActionGroup(interfaceLangSubMenu); + interfaceLangGroup->setExclusive(true); + + QAction* select_auto = new QAction(this); + select_auto->setCheckable(true); + select_auto->setData("auto"); + + interfaceLangSubMenu->addAction(select_auto); + interfaceLangGroup->addAction(select_auto); + + connect(interfaceLangGroup, SIGNAL(triggered(QAction*)), this, SLOT(interfaceLanguageChanged(QAction*))); + + + langPath = QApplication::applicationDirPath().append("/languages/"); + QStringList fileNames = QDir(langPath).entryList(QStringList("PkmGCSaveEditor_*.qm")); + + QAction *actionToCheck = select_auto; + + for (int i = 0; i < fileNames.size(); ++i) { + QString locale; + locale = fileNames[i]; + locale.truncate(locale.lastIndexOf('.')); + locale.remove(0, locale.indexOf('_') + 1); + + QAction *action = new QAction(this); + if (locale == interfaceLanguage) actionToCheck = action; + + action->setCheckable(true); + action->setData(locale); + + interfaceLangGroup->addAction(action); + interfaceLangSubMenu->addAction(action); + } + + actionToCheck->setChecked(true); +} + +void MainWindow::updateText(void) { + centralWidget->updateText(); + fileMenu->setTitle(tr("&File")); + + openFileAction->setText(tr("&Open...")); + saveFileAction->setText(tr("&Save")); + saveFileAsAction->setText(tr("Save &as...")); + exitAction->setText(tr("&Exit")); + + optionsMenu->setTitle(tr("&Options")); + interfaceLangSubMenu->setTitle(tr("&Interface language")); + dumpedNamesLangSubMenu->setTitle(tr("&Dumped names language")); + + QList actions = interfaceLangGroup->actions(), actions2 = dumpedNamesLangGroup->actions(); + + actions[0]->setText(tr("Select &automatically")); + actions2[0]->setText(tr("Select &automatically")); + + for (QList::iterator it = actions.begin() + 1; it != actions.end(); ++it) + (*it)->setText(VersionInfoLayout::languageNames()[languageCodeToIndexMap[(*it)->data().toString()]]); + + for (QList::iterator it = actions2.begin() + 1; it != actions2.end(); ++it) + (*it)->setText(VersionInfoLayout::languageNames()[(*it)->data().toInt()]); +} + + +void MainWindow::switchTranslator(QTranslator& translator, QString const& filename) { + // remove the old translator + qApp->removeTranslator(&translator); + + // load the new translator + if (translator.load(filename)) + qApp->installTranslator(&translator); +} + +QString MainWindow::loadInterfaceLanguage(QString const& language) { + if (!openFileAction->text().isEmpty() && interfaceLanguage != "auto" && interfaceLanguage == language) return language; + QString sys_language = QLocale::system().name(); + sys_language.truncate(sys_language.lastIndexOf('_')); + + QString langPath = QApplication::applicationDirPath().append("/languages/"); + QString lg = (language == "auto") ? sys_language : language; + QString fileName = langPath +QString("PkmGCSaveEditor_%1.qm").arg(lg); + if (!QFile(fileName).exists()) { + fileName = langPath + QString("PkmGCSaveEditor_en.qm"); + lg = "en"; + } + if (!QFile(fileName).exists()) { + updateText(); + return lg; + } + + QLocale locale = QLocale(lg); + QLocale::setDefault(locale); + + switchTranslator(translator, fileName); + switchTranslator(translatorQt, langPath + QString("qt_%1.qm").arg(lg)); // Note that qt_en.qm does not exist, which is normal :) + switchTranslator(translatorQt, langPath + QString("qtbase_%1.qm").arg(lg)); // For Qt > 5.3 + + + updateText(); + return lg; +} + +void MainWindow::interfaceLanguageChanged(QAction* action) { + if (action != NULL) interfaceLanguage = loadInterfaceLanguage(action->data().toString()); +} + +void MainWindow::dumpedNamesLanguageChanged(QAction* action) { + if (action != NULL) dumpedNamesLanguage = (LanguageIndex)action->data().toInt(); +} + +void MainWindow::changeEvent(QEvent* ev) { + if (ev == NULL) return; + switch (ev->type()) { + case QEvent::LanguageChange: updateText(); break; + case QEvent::LocaleChange: if (interfaceLangGroup->actions()[0]->isChecked()) loadInterfaceLanguage("auto"); break; + default: break; + } + QMainWindow::changeEvent(ev); +} + +void MainWindow::closeEvent(QCloseEvent* ev) { + if (!changesMade) { + saveSettings(); + ev->accept(); + } + else { + switch (openSaveChangesPrompt()) { + case QMessageBox::Save: saveSaveFile(); + case QMessageBox::Discard: saveSettings(); ev->accept(); break; + case QMessageBox::Cancel: default: ev->ignore(); break; + } + } +} + + +int MainWindow::openSaveChangesPrompt(void) { + const QString gcifilter = tr("GCI save files (*.gci)"); + const QString rawfilter = tr("Raw save files (*.bin)"); + QMessageBox msgBox; + msgBox.setText(tr("The save file has been modified.")); + msgBox.setInformativeText(tr("Do you want to save your changes?")); + msgBox.setStandardButtons((QFlags)((int)QMessageBox::Save | (int)QMessageBox::Discard | (int)QMessageBox::Cancel)); + msgBox.setDefaultButton(QMessageBox::Save); + + int ret = msgBox.exec(); + switch (ret){ + case QMessageBox::Save: + saveSaveFile(); + changesMade = false; + break; + case QMessageBox::Discard: + saveFile.reset(); + changesMade = false; + break; + case QMessageBox::Cancel: + default: + break; + } + return ret; +} + +void MainWindow::openSaveFile(void) { + const QString gcifilter = tr("GCI save files (*.gci)"); + const QString rawfilter = tr("Raw save files (*.bin)"); + + const QString errmsg = tr("Could not open file."); + const QString errmsg2 = tr("An error occured while reading the specified save file."); + + if (changesMade && (openSaveChangesPrompt() == QMessageBox::Cancel)) return; + QString fileName = QFileDialog::getOpenFileName(this, tr("Open save file"), lastSaveDirectory, gcifilter + ";;" + rawfilter + ";;"+tr("All Files (*)")); + if (fileName.isEmpty()) return; + + QFileInfo fileInfo(fileName); + size_t fileSize = (size_t)fileInfo.size(); + + bool hasGCIData = false, isColosseum = false; + + switch (fileSize) { + case 0x60040: hasGCIData = true; + case 0x60000: isColosseum = true; break; + + case 0x56040: hasGCIData = true; + case 0x56000: isColosseum = false; break; + + default: + QMessageBox::critical(this, tr("Error"), tr("Invalid file size.")); return; + } + + // Reading the save file contents ... + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Error"), errmsg); + return; + } + QByteArray ba = file.readAll(); + if (ba.size() != fileSize) { + QMessageBox::critical(this, tr("Error"), errmsg2); + return; + } + + lastSaveDirectory = fileInfo.canonicalPath(); + currentSaveFileName = fileName; + + if (isColosseum) + saveFile.reset(new Colosseum::SaveEditing::Save((const u8*)ba.data(), hasGCIData)); + else + saveFile.reset(new XD::SaveEditing::Save((const u8*)ba.data(), hasGCIData)); + + size_t slIndex = 0; + if (ignoreDataCorruption) { + currentSaveSlot = saveFile->getMostRecentSlot(0); + } + else { + currentSaveSlot = saveFile->getMostRecentValidSlot(0, &slIndex); + if (slIndex == 1) + QMessageBox::warning(this, tr("Warning"), tr("The backup save slot was loaded because the most recent save slot is corrupt.")); + else if (slIndex == 2) // Colosseum only + QMessageBox::warning(this, tr("Warning"), tr("The second backup save slot was loaded because the other ones are corrupt.")); + + if (currentSaveSlot == NULL) + QMessageBox::critical(this, tr("Error"), tr("All save slots are corrupt.")); + + } + + if (currentSaveSlot == NULL) { + currentSaveFileName = ""; + this->setWindowTitle("PkmGCSaveEditor"); + } + else { + this->setWindowTitle("PkmGCSaveEditor - " + currentSaveFileName); + } + + centralWidget->currentSaveSlotChangeHandler(); + updateStatusBar(); +} + +void MainWindow::updateStatusBar(void) { + if (currentSaveSlot == NULL) { + statusBar()->showMessage(tr("No save file loaded")); + } + else { + QString msg = tr("%1, %n save(s)", "", currentSaveSlot->saveCount); + msg = msg.arg(LIBPKMGC_IS_COLOSSEUM(SaveEditing::SaveSlot, currentSaveSlot) ? tr("Colosseum") : tr("XD")); + statusBar()->showMessage(msg); + } +} +bool MainWindow::saveSaveFile(void) { + const QString errmsg = tr("Could not write to file."); + const QString errmsg2 = tr("An error occured while writing to the specified save file."); + + QString fileName = currentSaveFileName; + if (fileName.isEmpty()) return false; + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::critical(this, tr("Error"), errmsg); + return false; + } + + bool writeGCIData = (fileName.section(".", -1) == "gci") && saveFile->hasGCIData; + int sz = saveFile->fixedSize + ((writeGCIData) ? 0x40 : 0); + + QByteArray ba(sz, '\0'); + saveFile->saveEncrypted((u8*)ba.data(), writeGCIData); + + if (file.write(ba) != (qint64)sz) { + QMessageBox::critical(this, tr("Error"), errmsg2); + return false; + } + + changesMade = false; + return true; +} + +void MainWindow::saveSaveFileAs(void) { + const QString gcifilter = tr("GCI save files (*.gci)"); + const QString rawfilter = tr("Raw save files (*.bin)"); + QString previousFileName = currentSaveFileName; + + QString filters = ((saveFile->hasGCIData) ? gcifilter + ";;" : "") + rawfilter + ";;" + tr("All files (*)"); + currentSaveFileName = QFileDialog::getSaveFileName(this, tr("Save save file"), lastPkmDirectory, filters); + + if (!saveSaveFile()) { + currentSaveFileName = previousFileName; + } + else { + lastSaveDirectory = QFileInfo(currentSaveFileName).canonicalPath(); + } + +} + +void MainWindow::loadSettings(void) { + settings = new QSettings("PkmGCTools", "PkmGCSaveEditor", this); + ignoreDataCorruption = settings->value("IgnoreDataCorruption").toBool(); + interfaceLanguage = settings->value("InterfaceLanguage").toString(); + dumpedNamesLanguage = (LanguageIndex) settings->value("DumpedNamesLanguage").toInt(); + + lastPkmDirectory = settings->value("LastPkmDirectory").toString(); + lastSaveDirectory = settings->value("LastSaveDirectory").toString(); + + if (interfaceLanguage.isEmpty()) interfaceLanguage = "auto"; + if (dumpedNamesLanguage > Spanish) dumpedNamesLanguage = NoLanguage; + +} + +void MainWindow::saveSettings(void) { + settings->setValue("Version", PKMGCSAVEEDITOR_VERSION); + settings->setValue("LibPkmGCVersion", LIBPKMGC_VERSION); + + settings->setValue("IgnoreDataCorruption", ignoreDataCorruption); + settings->setValue("InterfaceLanguage", interfaceLangGroup->checkedAction()->data()); + if (dumpedNamesLanguage > Spanish) dumpedNamesLanguage = NoLanguage; + settings->setValue("DumpedNamesLanguage", dumpedNamesLanguage); + + settings->setValue("LastPkmDirectory", lastPkmDirectory); + settings->setValue("LastSaveDirectory", lastSaveDirectory); +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/MainWindow.h b/PkmGCSaveEditor/src/MainWindow.h new file mode 100644 index 0000000..e6cf7b1 --- /dev/null +++ b/PkmGCSaveEditor/src/MainWindow.h @@ -0,0 +1,90 @@ +#ifndef _PKMGCSAVEEDITOR_MAIN_WINDOW_H +#define _PKMGCSAVEEDITOR_MAIN_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MWCentralWidget : public QWidget { + Q_OBJECT +public: + MWCentralWidget(QWidget* parent = NULL, Qt::WindowFlags f = 0); + + void updateText(void); + +public slots: + void currentSaveSlotChangeHandler(void); + void openGameConfigUI(void); + void openPlayerUI(void); + void openPCUI(void); + void openDaycareUI(void); + void openStrategyMemoUI(void); + void openPurifierUI(void); + +private: + QVBoxLayout *mainLayout; + QPushButton *gameConfigButton, *playerButton, *PCButton, *daycareButton, *strategyMemoButton, *purifierButton ; +}; + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + MainWindow(); + + void updateText(void); + void updateStatusBar(void); + int openSaveChangesPrompt(void); +public slots: + void openSaveFile(void); + bool saveSaveFile(void); + void saveSaveFileAs(void); + + void loadSettings(void); + void saveSettings(void); + + void interfaceLanguageChanged(QAction* action); + void dumpedNamesLanguageChanged(QAction* action); + + + +protected: + void closeEvent(QCloseEvent* ev); + void changeEvent(QEvent* ev); + +private: + QString loadInterfaceLanguage(QString const& language); + + void createInterfaceLanguageMenu(void); + void createDumpedNamesLanguageMenu(void); + void switchTranslator(QTranslator& translator, QString const& filename); + QScopedPointer saveFile; // global public access is done through ::currentSave + MWCentralWidget *centralWidget; + + QMenu *fileMenu; + QAction *openFileAction, *saveFileAction, *saveFileAsAction, *exitAction; + + QMenu *optionsMenu; + QAction* ignoreDataCorruptionAction; + QMenu* interfaceLangSubMenu; + QActionGroup *interfaceLangGroup; + QMenu* dumpedNamesLangSubMenu; + QActionGroup *dumpedNamesLangGroup; + QSettings *settings; + + QTranslator translator, translatorQt; + + QString langPath; + +}; + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/XDUIs/PurifierUI.cpp b/PkmGCSaveEditor/src/XDUIs/PurifierUI.cpp new file mode 100644 index 0000000..1c3751e --- /dev/null +++ b/PkmGCSaveEditor/src/XDUIs/PurifierUI.cpp @@ -0,0 +1,89 @@ +#include + +using namespace LibPkmGC; + +namespace XDUIs { + +PurificationChamberWidget::PurificationChamberWidget(XD::PurificationChamber* inChamber, size_t inChamberIndex, QWidget* parent) : QWidget(parent), +chamber(inChamber), chamberIndex(inChamberIndex) { + init(); +} + +void PurificationChamberWidget::initWidget(void) { + mainLayout = new QVBoxLayout; + + for (size_t i = 0; i < 3; ++i) { + normalPkmFlds[i] = new GCUIs::PokemonDisplayWidget; + mainLayout->addWidget(normalPkmFlds[i]); + } + mainLayout->addStretch(); + shadowPkmFld = new GCUIs::PokemonDisplayWidget; + mainLayout->addWidget(shadowPkmFld); + this->setLayout(mainLayout); +} + +void PurificationChamberWidget::parseData(void) { + if (chamber == NULL) return; + + PokemonStorageInfo loc = { StoredInPurifier, chamberIndex, 0 }; + + shadowPkmFld->pkm = chamber->shadowPkm; + shadowPkmFld->location = loc; + shadowPkmFld->parseData(); + for (size_t i = 0; i < 3; ++i) { + ++(loc.subIndex); + normalPkmFlds[i]->pkm = chamber->normalPkm[i]; + normalPkmFlds[i]->location = loc; + normalPkmFlds[i]->parseData(); + } +} + +void PurificationChamberWidget::saveChanges(void) { + for (size_t i = 0; i < 3; ++i) normalPkmFlds[i]->saveChanges(); + shadowPkmFld->saveChanges(); +} + +void PurificationChamberWidget::cancelChanges(void) { + for (size_t i = 0; i < 3; ++i) normalPkmFlds[i]->cancelChanges(); + shadowPkmFld->cancelChanges(); +} + + +PurifierUI::PurifierUI(XD::PurifierData* inPurifier, QWidget* parent, Qt::WindowFlags f) : DataUI(parent, f), purifier(inPurifier) { + init(); +} + +void PurifierUI::initWidget(void) { + tabs = new QTabWidget; + for (size_t i = 0; i < 9; ++i) { + chamberFlds[i] = new PurificationChamberWidget(NULL, i); + tabs->addTab(chamberFlds[i], tr("Chamber %n", "Purifier", 1 + (int)i)); + } + tabs->setUsesScrollButtons(false); + + mainLayout->addWidget(tabs); + DataUI::initWidget(); +} + +void PurifierUI::parseData(void) { + if (purifier == NULL) return; + for (size_t i = 0; i < 9; ++i) { + chamberFlds[i]->chamber = purifier->chambers[i]; + chamberFlds[i]->chamberIndex = i; + chamberFlds[i]->parseData(); + } +} + +void PurifierUI::saveChanges(void) { + for (size_t i = 0; i < 9; ++i) + chamberFlds[i]->saveChanges(); +} + +void PurifierUI::cancelChanges(void) { + for (size_t i = 0; i < 9; ++i) + chamberFlds[i]->saveChanges(); +} + + + +} \ No newline at end of file diff --git a/PkmGCSaveEditor/src/XDUIs/PurifierUI.h b/PkmGCSaveEditor/src/XDUIs/PurifierUI.h new file mode 100644 index 0000000..c9cc99e --- /dev/null +++ b/PkmGCSaveEditor/src/XDUIs/PurifierUI.h @@ -0,0 +1,54 @@ +#ifndef _PKMGCSAVEEDITOR_PURIFIER_UI_H +#define _PKMGCSAVEEDITOR_PURIFIER_UI_H + +#include + +namespace XDUIs { + +class PurificationChamberWidget : public QWidget, public IDataUI { + Q_OBJECT +public: + PurificationChamberWidget(LibPkmGC::XD::PurificationChamber* inChamber = NULL, size_t inChamberIndex = 0, QWidget* parent = NULL); + + LibPkmGC::XD::PurificationChamber* chamber; + size_t chamberIndex; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); + +protected: + void initWidget(void); + +private: + QVBoxLayout* mainLayout; + + GCUIs::PokemonDisplayWidget* normalPkmFlds[3]; + + GCUIs::PokemonDisplayWidget* shadowPkmFld; + +}; + +class PurifierUI : public DataUI { + Q_OBJECT +public: + PurifierUI(LibPkmGC::XD::PurifierData* inPurifier = NULL, QWidget* parent = NULL, Qt::WindowFlags f = Qt::Window); + + LibPkmGC::XD::PurifierData* purifier; + + void parseData(void); + void saveChanges(void); + void cancelChanges(void); + +protected: + void initWidget(void); + +private: + QTabWidget* tabs; + PurificationChamberWidget *chamberFlds[9]; + +}; + +} + +#endif \ No newline at end of file diff --git a/PkmGCSaveEditor/src/main.cpp b/PkmGCSaveEditor/src/main.cpp new file mode 100644 index 0000000..e3aa7d3 --- /dev/null +++ b/PkmGCSaveEditor/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include + + +#include +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + MainWindow iface; + iface.show(); + + return app.exec(); +} diff --git a/PkmGCSaveEditor/translations/PkmGCSaveEditor_en.ts b/PkmGCSaveEditor/translations/PkmGCSaveEditor_en.ts new file mode 100644 index 0000000..8d72e8e --- /dev/null +++ b/PkmGCSaveEditor/translations/PkmGCSaveEditor_en.ts @@ -0,0 +1,1445 @@ + + + + + GCUIs::BagEditor + + + Regular items + Regular items + + + + Key items + Key items + + + + Pokúlls + Pokéballs + + + + TMs + TMs + + + + Berries + Berries + + + + Colognes + Colognes + + + + Battle CDs + Battle CDs + + + + GCUIs::DaycareUI + + Not visited + Not visited + + + + Not visited yet + Not visited yet + + + + Empty + Empty + + + + Pokémon deposited + Pokémon deposited + + + + Daycare status + Daycare status + + + + Initial Pokémon level + Initial Pokémon level + + + + Initial Pokémon purification counter + Initial Pokémon purification counter + + + + GCUIs::GameConfigUI + + + Game version + Game version + + + + Title screen options + Title screen options + + + + Miscellaneous + Miscellaneous + + + + Rumble function disabled + Rumble function disabled + + + + Language + Language + + + + Story mode save count + Story mode save count + + + + Warning + Warning + + + + The version info you specified is invalid, and will make the game unplayable. + The version info you specified is invalid, and will make the game unplayable. + + + + GCUIs::PCUI + + Current box + Current box + + + + Selected box + Selected box + + + + Pokémon + Pokémon + + + + Items + Items + + + + GCUIs::PlayerUI + + + Trainer information + Trainer information + + + + Currencies + Currencies + + + + Money + Money + + + + PokÜoupons + Pokécoupons + + + + General + General + + + + Bag + Bag + + + + Party + Party + + + + GCUIs::PokemonBoxEditor + + + %1 to %2 + %1 to %2 + + + + Box name + Box name + + + + GCUIs::PokemonDisplayWidget + + + Edit + Edit + + + + Delete + Delete + + + + Import + Import + + + + Export + Export + + + + Invalid species + Invalid species + + + + Invalid version info + Invalid version info + + + + Bit 5 set on byte at offset 0x1d + Bit 5 set on byte at offset 0x1d + + + + Lv. %n + + Lv. %n + Lv. %n + + + + + Colosseum Pokémon files (*.colopkm) + Colosseum Pokémon files (*.colopkm) + + + + XD Pokémon files (*.xdpkm) + XD Pokémon files (*.xdpkm) + + + + All files (*) + All files (*) + + + + Could not open file. + Could not open file. + + + + An error occured while reading the specified Pokémon file. + An error occured while reading the specified Pokémon file. + + + + Open Pokémon file + Open Pokémon file + + + + + + + + + + Error + Error + + + + Invalid file size. + Invalid file size. + + + + Could not write to file. + Could not write to file. + + + + An error occured while writing to the specified Pokémon file. + An error occured while writing to the specified Pokémon file. + + + + Save Pokémon file + Save Pokémon file + + + + GCUIs::PokemonMoveLayout + + + + (max. %n) + + (max. %n) + (max. %n) + + + + + PP Up(s) used + PP Up(s) used + + + + GCUIs::PokemonUI + + + + None + Status + None + + + + Poisoned + Poisoned + + + + Badly poisoned + Badly poisoned + + + + Paralyzed + Paralyzed + + + + Burnt + Burnt + + + + Frozen + Frozen + + + + Asleep + Asleep + + + + Coolness + Coolness + + + + Beauty + Beauty + + + + Cuteness + Cuteness + + + + Cleverness + Cleverness + + + + Toughness + Toughness + + + + None + Contest + None + + + + Normal + Contest + Normal + + + + Super + Contest + Super + + + + Hyper + Contest + Hyper + + + + Master + Contest + Master + + + + HP + HP + + + + Attack + Attack + + + + Defense + Defense + + + + S. Attack + S. Attack + + + + S. Defense + S. Defense + + + + Speed + Speed + + + + Champion + Champion + + + + Winning + Winning + + + + Victory + Victory + + + + Artist + Artist + + + + Effort + Effort + + + + Marine + Marine + + + + Land + Land + + + + Sky + Sky + + + + Country + Country + + + + National + National + + + + Earth + Earth + + + + World + World + + + + Reset + Reset + + + + Species + Species + + + + Name or nickname + Name or nickname + + + + PID + PID + + + + Attributes + Attributes + + + + Ability + Ability + + + + Experience and level + Experience and level + + + + Held item + Held item + + + + Happiness + Happiness + + + + Pokérus + Pokérus + + + + Status + Status + + + + Markings + Markings + + + + Core information + Core information + + + + Original trainer + Original trainer + + + + Game version + Game version + + + + Copy info from save + Copy info from save + + + + Generate shiny IDs + Generate shiny IDs + + + + Ball caught with + Ball caught with + + + + Location caught + Location caught + + + + IV + IV + + + + EV + EV + + + + Stat + Stat + + + + Current HP + Current HP + + + + Update stats automatically + Update stats automatically + + + + Luster + Luster + + + + Main stats + Main stats + + + + Contest stats + Contest stats + + + + Contest ribbons + Contest ribbons + + + + Contest type + Contest type + + + + Achievement + Achievement + + + + Special ribbons + Special ribbons + + + + General + General + + + + Met/OT + Met/OT + + + + Stats + Stats + + + + Moves + Moves + + + + Ribbons + Ribbons + + + + Genderless + Genderless + + + + Unown form: + Unown form: + + + + will evolve into: + will evolve into: + + + + + Invalid version info + Invalid version info + + + + + Bit 5 set on byte at offset 0x1d + Bit 5 set on byte at offset 0x1d + + + + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)'>here</a>) + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)'>here</a>) + + + + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)'>here</a>) + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)'>here</a>) + + + + Warning + Warning + + + + The version info you specified is invalid. The game will therefore consider this Pokémon invalid. + The version info you specified is invalid. The game will therefore consider this Pokémon invalid. + + + The version info you specified is invalid. The game will therefore consider the Pokémon invalid. + The version info you specified is invalid. The game will therefore consider the Pokémon invalid. + + + + GCUIs::StrategyMemoEntryWidget + + + (randomly generated) + (randomly generated) + + + + Generate shiny PID + Generate shiny PID + + + + Species + Species + + + + First TID + First TID + + + + First SID + First SID + + + + First PID + First PID + + + + Partial information + Partial information + + + + GCUIs::StrategyMemoUI + + + + #%1: %2 + #%1: %2 + + + + Number of entries + Number of entries + + + + Entry + Entry + + + + ItemPocketEditor + + + + Item + Item + + + + + Quantity + Quantity + + + + Modify + Modify + + + + Delete + Delete + + + + MWCentralWidget + + + Game configuration + Game configuration + + + + Trainer info, Party and Bag + Trainer info, Party and Bag + + + + PC + PC + + + + Daycare + Daycare + + + + Strategy memo + Strategy memo + + + + Purifier + Purifier + + + + MainWindow + + + + &File + &File + + + + + &Options + &Options + + + + + &Interface language + &Interface language + + + + + &Dumped names language + &Dumped names language + + + + &Open... + &Open... + + + + &Save + &Save + + + + Save &as... + Save &as... + + + + &Exit + &Exit + + + Choose &automatically + Choose &automatically + + + + + Select &automatically + Select &automatically + + + + + + GCI save files (*.gci) + GCI save files (*.gci) + + + + + + Raw save files (*.bin) + Raw save files (*.bin) + + + + The save file has been modified. + The save file has been modified. + + + + Do you want to save your changes? + Do you want to save your changes? + + + + Could not open file. + Could not open file. + + + + An error occured while reading the specified save file. + An error occured while reading the specified save file. + + + + Open save file + Open save file + + + + All Files (*) + All Files (*) + + + + + + + + + Error + Error + + + + Invalid file size. + Invalid file size. + + + + + Warning + Warning + + + + The backup save slot was loaded because the most recent save slot is corrupt. + The backup save slot was loaded because the most recent save slot is corrupt. + + + + The second backup save slot was loaded because the other ones are corrupt. + The second backup save slot was loaded because the other ones are corrupt. + + + + All save slots are corrupt. + All save slots are corrupt. + + + + No save file loaded + No save file loaded + + + + %1, %n save(s) + + %1, %n save + %1, %n saves + + + + %1 save file (save count: %2) + %1 save file (save count: %2) + + + + Colosseum + Colosseum + + + + XD + XD + + + + Could not write to file. + Could not write to file. + + + + An error occured while writing to the specified save file. + An error occured while writing to the specified save file. + + + + All files (*) + All files (*) + + + + Save save file + Save save file + + + + QObject + + GCI save files (*.gci) + GCI save files (*.gci) + + + Raw save files (*.bin) + Raw save files (*.bin) + + + Coolness + Coolness + + + Beauty + Beauty + + + Cuteness + Cuteness + + + Cleverness + Cleverness + + + Toughness + Toughness + + + None + Contest + None + + + Normal + Contest + Normal + + + Super + Contest + Super + + + Hyper + Contest + Hyper + + + Master + Contest + Master + + + None + Status + None + + + Poisoned + Poisoned + + + Badly poisoned + Badly poisoned + + + Paralyzed + Paralyzed + + + Burnt + Burnt + + + Frozen + Frozen + + + Asleep + Asleep + + + HP + HP + + + Attack + Attack + + + Defense + Defense + + + S. Attack + S. Attack + + + S. Defense + S. Defense + + + Speed + Speed + + + Champion + Champion + + + Winning + Winning + + + Victory + Victory + + + Artist + Artist + + + Effort + Effort + + + Marine + Marine + + + Land + Land + + + Sky + Sky + + + Country + Country + + + National + National + + + Earth + Earth + + + World + World + + + Colosseum Pokémon (*.colopkm) + Colosseum Pokémon (*.colopkm) + + + XD Pokémon (*.xdpkm) + XD Pokémon (*.xdpkm) + + + Colosseum Pokémon files (*.colopkm) + Colosseum Pokémon files (*.colopkm) + + + XD Pokémon files (*.xdpkm) + XD Pokémon files (*.xdpkm) + + + All files (*) + All files (*) + + + None + Game name + None + + + Fire Red + Fire Red + + + Leaf Green + Leaf Green + + + Ruby + Ruby + + + Sapphire + Sapphire + + + Emerald + Emerald + + + Colosseum/XD + Colosseum/XD + + + None + Region name + None + + + NTSC-J + NTSC-J + + + NTSC-U + NTSC-U + + + PAL + PAL + + + None + Language name + None + + + Japanese + Japanese + + + English + English + + + German + German + + + French + French + + + Italian + Italian + + + Spanish + Spanish + + + + TrainerInfoLayout + + + Male + Trainer + Male + + + + Female + Trainer + Female + + + + Gender + Trainer + Gender + + + + Name + Name + + + + TID/SID + TID/SID + + + + VersionInfoLayout + + + None + Language name + None + + + + Japanese + Japanese + + + + English + English + + + + French + French + + + + Italian + Italian + + + + Spanish + Spanish + + + + German + German + + + + None + Game name + None + + + + Fire Red + Fire Red + + + + Leaf Green + Leaf Green + + + + Ruby + Ruby + + + + Sapphire + Sapphire + + + + Emerald + Emerald + + + + Colosseum/XD + Colosseum/XD + + + + None + Region name + None + + + + NTSC-J + NTSC-J + + + + NTSC-U + NTSC-U + + + + PAL + PAL + + + + Game + Game + + + + Current region + Current region + + + + Original region + Original region + + + + Language + Language + + + + XDUIs::PurifierUI + + + Chamber %n + Purifier + + Chamber %n + Chamber %n + + + + diff --git a/PkmGCSaveEditor/translations/PkmGCSaveEditor_fr.ts b/PkmGCSaveEditor/translations/PkmGCSaveEditor_fr.ts new file mode 100644 index 0000000..edc5dea --- /dev/null +++ b/PkmGCSaveEditor/translations/PkmGCSaveEditor_fr.ts @@ -0,0 +1,1421 @@ + + + + + GCUIs::BagEditor + + + Regular items + Objets communs + + + + Key items + Objets rares + + + + Pokúlls + Pokéballs + + + + TMs + CTs + + + + Berries + Baies + + + + Colognes + Parfums + + + + Battle CDs + Holodisques + + + + GCUIs::DaycareUI + + + Not visited yet + Pas encore visitée + + + + Empty + Vide + + + + Pokémon deposited + Pokémon déposé + + + + Daycare status + Etat de la pension + + + + Initial Pokémon level + Niveau de départ du Pokémon + + + + Initial Pokémon purification counter + Etat initial de purification du Pokémon + + + + GCUIs::GameConfigUI + + + Game version + Version du jeu + + + + Title screen options + Options de l'écran titre + + + + Miscellaneous + Divers + + + + Rumble function disabled + Fonction vibration désactivée + + + + Language + Langue + + + + Story mode save count + Nombre de sauvegardes en mode scénario + + + + Warning + Avertissement + + + + The version info you specified is invalid, and will make the game unplayable. + Les informations sur la version du jeu que vous avez entrées sont invalides, et rendront le jeu injouable. + + + + GCUIs::PCUI + + + Selected box + Boîte sélectionnée + + + + Pokémon + Pokémon + + + + Items + Objets + + + + GCUIs::PlayerUI + + + Trainer information + Infos dresseur + + + + Currencies + Devises + + + + Money + Argent + + + + PokÜoupons + Pokécoupons + + + + General + Général + + + + Bag + Sac + + + + Party + Equipe + + + + GCUIs::PokemonBoxEditor + + + %1 to %2 + %1 à %2 + + + + Box name + Nom de la boîte + + + + GCUIs::PokemonDisplayWidget + + + Edit + Modifier + + + + Delete + Supprimer + + + + Import + Importer + + + + Export + Exporter + + + + Invalid species + Espèce invalide + + + + Invalid version info + Informations de version invalide + + + + Bit 5 set on byte at offset 0x1d + Bit 5 de l'octet à l'adresse 0x1d valant 1 + + + + Lv. %n + + Nv. %n + Nv. %n + + + + + Colosseum Pokémon files (*.colopkm) + Fichiers Pokémon de Colosseum (*.colopkm) + + + + XD Pokémon files (*.xdpkm) + Fichier Pokémon d'XD (*.xdpkm) + + + + All files (*) + Tous les fichiers (*) + + + + Could not open file. + Impossible d'ouvrir le fichier. + + + + An error occured while reading the specified Pokémon file. + Une erreur s'est produite durant la lecture du fichier Pokémon. + + + + Open Pokémon file + Ouvrir fichier Pokémon + + + + + + + + + + Error + Erreur + + + + Invalid file size. + Taille de fichier invalide. + + + + Could not write to file. + Impossible d'écrire dans le fichier. + + + + An error occured while writing to the specified Pokémon file. + Une erreur s'est produite pendant l'écriture des données sur le fichier Pokémon. + + + + Save Pokémon file + Sauvegarder fichier Pokémon + + + + GCUIs::PokemonMoveLayout + + + + (max. %n) + + (max. %n) + (max. %n) + + + + + PP Up(s) used + PP Up(s) utilisés + + + + GCUIs::PokemonUI + + + + None + Status + Aucun + + + + Poisoned + Empoisonné + + + + Badly poisoned + Gravement empoisonné + + + + Paralyzed + Paralysé + + + + Burnt + Brûlé + + + + Frozen + Gelé + + + + Asleep + Endormi + + + + Coolness + Sang-froid + + + + Beauty + Beauté + + + + Cuteness + Grâce + + + + Cleverness + Intelligence + + + + Toughness + Robustesse + + + + None + Contest + Aucun + + + + Normal + Contest + Normal + + + + Super + Contest + Super + + + + Hyper + Contest + Hyper + + + + Master + Contest + Master + + + + HP + PV + + + + Attack + Attaque + + + + Defense + Défense + + + + S. Attack + Attaque Spé. + + + + S. Defense + Défense spé. + + + + Speed + Vitesse + + + + Champion + Maître + + + + Winning + Victoire 1 + + + + Victory + Victoire 2 + + + + Artist + Artiste + + + + Effort + + + + + Marine + Marin + + + + Land + Terrestre + + + + Sky + Céleste + + + + Country + Régional + + + + National + National + + + + Earth + Terre + + + + World + Monde + + + + Reset + RaZ + + + + Species + Espèce + + + + Name or nickname + Nom ou surnom + + + + PID + PID + + + + Attributes + Caractéristiques + + + + Ability + Talent + + + + Experience and level + Expérience et niveau + + + + Held item + Objet tenu + + + + Happiness + Bonheur + + + + Pokérus + Pokérus + + + + Status + Statut + + + + Markings + Marques + + + + Core information + Informations essentielles + + + + Original trainer + Dresseur d'origine + + + + Game version + Version du jeu + + + + Copy info from save + Recopier les infos à partir de la sauvegarde + + + + Generate shiny IDs + Générer des IDs rendant ce Pokémon shiny + + + + Ball caught with + Pokéball utilisée + + + + Location caught + Lieu de capture + + + + IV + IV + + + + EV + EV + + + + Stat + Statistique + + + + Current HP + PVs actuels + + + + Update stats automatically + Mettre à jour les statistiques automatiquement + + + + Luster + Lustre + + + + Main stats + Statistiques principales + + + + Contest stats + Statistiques de concours + + + + Contest ribbons + Rubans de concours + + + + Contest type + Type de concours + + + + Achievement + Avancement + + + + Special ribbons + Rubans spéciaux + + + + General + Général + + + + Met/OT + Infos de rencontre/D.O + + + + Stats + Statistiques + + + + Moves + Attaques + + + + Ribbons + Rubans + + + + Genderless + Asexué + + + + Unown form: + Forme Zarbi : + + + + will evolve into: + évoluera en : + + + + + Invalid version info + Infos de version invalides + + + + + Bit 5 set on byte at offset 0x1d + Bit 5 de l'octet à l'adresse 0x1d valant 1 + + + + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)'>here</a>) + Lieu de capture (cf. <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(Generation_III)'>Bulbapedia</a>) + + + + Location caught (see <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)'>here</a>) + Lieu de capture (cf. <a href='http://bulbapedia.bulbagarden.net/wiki/List_of_locations_by_index_number_(GCN)'>Bulbapedia</a>) + + + + Warning + Avertissement + + + + The version info you specified is invalid. The game will therefore consider this Pokémon invalid. + Les informations sur la version du jeu que vous avez entrées sont invalides. Le jeu considérera de ce fait ce Pokémon invalide. + + + The version info you specified is invalid. The game will therefore consider the Pokémon invalid. + Les informations sur la version du jeu que vous avez entrées sont invalides. Le jeu considérera de ce fait ce Pokémon invalide. + + + + GCUIs::StrategyMemoEntryWidget + + + (randomly generated) + (géneré aléatoirement) + + + + Generate shiny PID + Générer un PID rendant le Pokémon shiny + + + + Species + Espèce + + + + First TID + Premier TID + + + + First SID + Premier SID + + + + First PID + Premier PID + + + + Partial information + Informations partielles + + + + GCUIs::StrategyMemoUI + + + + #%1: %2 + #%1 : %2 + + + + Number of entries + Nombre d'entrées + + + + Entry + Entrée + + + + ItemPocketEditor + + + + Item + Objet + + + + + Quantity + Quantité + + + + Modify + Modifier + + + + Delete + Supprimer + + + + MWCentralWidget + + + Game configuration + Configuration du jeu + + + + Trainer info, Party and Bag + Infos dresseur, Equipe et Sac + + + + PC + PC + + + + Daycare + Pension + + + + Strategy memo + Mémo + + + + Purifier + Purificateur + + + + MainWindow + + + + &File + &Fichier + + + + + &Options + &Options + + + + + &Interface language + Langue de l'&interface + + + + + &Dumped names language + Langue des noms &extraits + + + + &Open... + &Ouvrir... + + + + &Save + &Enregistrer + + + + Save &as... + Enregistrer &sous... + + + + &Exit + &Quitter + + + + + Select &automatically + Sélectionner &automatiquement + + + + + + GCI save files (*.gci) + Fichiers de sauvegarde GCI (*.gci) + + + + + + Raw save files (*.bin) + Fichiers de sauvegarde bruts (*.bin) + + + + The save file has been modified. + Le fichier de sauvegarde a été modifié. + + + + Do you want to save your changes? + Voulez-vous enregistrer vos modifications ? + + + + Could not open file. + Impossible d'ouvrir le fichier. + + + + An error occured while reading the specified save file. + Une erreur s'est produite durant la lecture du fichier de sauvegarde. + + + + Open save file + Ouvrir fichier de sauvegarde + + + + All Files (*) + Tous les fichiers (*) + + + + + + + + + Error + Erreur + + + + Invalid file size. + Taille de fichier invalide + + + + + Warning + Avertissement + + + + The backup save slot was loaded because the most recent save slot is corrupt. + L'emplacement de sauvegarde de secours a été chargé car l'emplacement le plus récent est corrompu + + + + The second backup save slot was loaded because the other ones are corrupt. + Le deuxième emplacement de sauvegarde de secours a été chargé car l'emplacement le plus récent est corrompu + + + + All save slots are corrupt. + Tous les emplacements de sauvegarde sont corrompus. + + + + No save file loaded + Aucune sauvegarde chargée + + + + %1, %n save(s) + + %1, %n sauvegarde + %1, %n sauvegardes + + + + %1 save file (save count: %2) + %1 (%2 sauvegardes) + + + + Colosseum + Colosseum + + + + XD + XD + + + + Could not write to file. + Impossible d'écrire dans le fichier. + + + + An error occured while writing to the specified save file. + Une erreur s'est produite pendant l'écriture des données sur le fichier de sauvegarde. + + + + All files (*) + Tous les fichiers (*) + + + + Save save file + Sauvegarder fichier de sauvegarde + + + + QObject + + GCI save files (*.gci) + Fichiers de sauvegarde GCI (*.gci) + + + Raw save files (*.bin) + Fichiers de sauvegarde bruts (*.bin) + + + Coolness + Sang-froid + + + Beauty + Beauté + + + Cuteness + Grâce + + + Cleverness + Intelligence + + + Toughness + Robustesse + + + None + Contest + Aucun + + + Normal + Contest + Normal + + + Super + Contest + Super + + + Hyper + Contest + Hyper + + + Master + Contest + Master + + + None + Status + Aucun + + + Poisoned + Empoisonné + + + Badly poisoned + Gravement empoisonné + + + Paralyzed + Paralysé + + + Burnt + Brûlé + + + Frozen + Gelé + + + Asleep + Endormi + + + HP + PV + + + Attack + Attaque + + + Defense + Défense + + + S. Attack + Attaque Spé. + + + S. Defense + Défense spé. + + + Speed + Vitesse + + + Champion + Maître + + + Winning + Victoire 1 + + + Victory + Victoire 2 + + + Artist + Artiste + + + Marine + Marin + + + Land + Terrestre + + + Sky + Céleste + + + Country + Régional + + + National + National + + + Earth + Terre + + + World + Monde + + + Colosseum Pokémon files (*.colopkm) + Fichiers Pokémon de Colosseum (*.colopkm) + + + XD Pokémon files (*.xdpkm) + Fichier Pokémon d'XD (*.xdpkm) + + + All files (*) + Tous les fichiers (*) + + + None + Game name + Aucun + + + Fire Red + Rouge Feu + + + Leaf Green + Vert Feuille + + + Ruby + Rubis + + + Sapphire + Saphir + + + Emerald + Emeraude + + + Colosseum/XD + Colosseum/XD + + + None + Region name + Aucun + + + NTSC-J + NTSC-J + + + NTSC-U + NTSC-U + + + PAL + PAL + + + None + Language name + Aucune + + + Japanese + Japonais + + + English + Anglais + + + German + Allemand + + + French + Français + + + Italian + Italien + + + Spanish + Espagnol + + + + TrainerInfoLayout + + + Male + Trainer + Masculin + + + + Female + Trainer + Féminin + + + + Gender + Trainer + Sexe + + + + Name + Nom + + + + TID/SID + TID/SID + + + + VersionInfoLayout + + + None + Language name + Aucune + + + + Japanese + Japonais + + + + English + Anglais + + + + French + Français + + + + Italian + Italien + + + + Spanish + Espagnol + + + + German + Allemand + + + + None + Game name + Aucun + + + + Fire Red + Rouge Feu + + + + Leaf Green + Vert Feuille + + + + Ruby + Rubis + + + + Sapphire + Saphir + + + + Emerald + Emeraude + + + + Colosseum/XD + Colosseum/XD + + + + None + Region name + Aucun + + + + NTSC-J + NTSC-J + + + + NTSC-U + NTSC-U + + + + PAL + PAL + + + + Game + Jeu + + + + Current region + Continent actuel + + + + Original region + Continent d'origine + + + + Language + Langue + + + + XDUIs::PurifierUI + + + Chamber %n + Purifier + + Chambre %n + Chambre %n + + + +