mirror of
https://github.com/TuxSH/PkmGCTools.git
synced 2026-03-21 17:45:19 -05:00
* The interface can now be displayed in **German** (thanks [peterpansexuell](http://www.smogon.com/forums/members/peterpansexuell.158307/) !)
* Updates can now be automatically checked for at startup (this is the default) * **New features**: * Ribbon descriptions can now be modified (7 ribbons are concerned) * Pokémon can now be imported/exported from/to Base64 strings * On Colosseum, you can now change Rui's name * Minor changes and bugfixes
This commit is contained in:
parent
3173566018
commit
58599addfc
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -1,9 +1,18 @@
|
|||
###PkmGCToos v1.2:
|
||||
* The interface can now be displayed in **German** (thanks [peterpansexuell](http://www.smogon.com/forums/members/peterpansexuell.158307/) !)
|
||||
* Updates can now be automatically checked for at startup (this is the default)
|
||||
* **New features**:
|
||||
* Ribbon descriptions can now be modified (7 ribbons are concerned)
|
||||
* Pokémon can now be imported/exported from/to Base64 strings
|
||||
* On Colosseum, you can now change Rui's name
|
||||
* Minor changes and bugfixes
|
||||
|
||||
###PkmGCTools v1.1.2:
|
||||
Fixed a bug in XD: the map+script data was being wiped out.
|
||||
Some refactoring in LibPkmGC.
|
||||
|
||||
###PkmGCTools v1.1.1:
|
||||
Fixed a lot of critical bugs (affecting IVs, etc...). Money and Pokécoupons are now limited to 9,999,999. Bag items are limited to 99 again in Pokémon Colosseum Fixed a lot of critical bugs (affecting IVs, etc...)
|
||||
Fixed a lot of critical bugs (affecting IVs, etc...). Pokedollars and PokéCoupons are now limited to 9,999,999. Bag items are limited to 99 again in Pokémon Colosseum Fixed a lot of critical bugs (affecting IVs, etc...)
|
||||
(use the PC storage system to fix bag entries with more than 99 items).
|
||||
|
||||
To users of previous versions:
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public:
|
|||
ItemIndex heldItem;
|
||||
|
||||
|
||||
u8 happiness;
|
||||
u8 friendship;
|
||||
u8 locationCaught; // u16 on Colo/XD
|
||||
ItemIndex ballCaughtWith;
|
||||
u8 levelMet;
|
||||
|
|
@ -91,7 +91,7 @@ public:
|
|||
PokemonString* OTName;
|
||||
PokemonString* name;
|
||||
u8 contestLuster;
|
||||
u8 pkrsStatus;
|
||||
u8 pokerusStatus;
|
||||
PokemonMarkings markings;
|
||||
|
||||
u32 experience;
|
||||
|
|
@ -127,7 +127,7 @@ public:
|
|||
virtual void setInvalidPokemonFlag(bool flag) = 0;
|
||||
|
||||
struct PokemonComputedPartyData {
|
||||
s8 pkrsDaysRemaining;
|
||||
s8 pokerusDaysRemaining;
|
||||
u16 currentHP;
|
||||
u8 level;
|
||||
PokemonStatus status;
|
||||
|
|
@ -137,7 +137,7 @@ public:
|
|||
|
||||
PokemonComputedPartyData partyData;
|
||||
|
||||
void normalizePkrs(void);
|
||||
void normalizepokerus(void);
|
||||
void normalizeStatus(void);
|
||||
|
||||
void resetPartyData(void);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
DaycareData* clone(void) const;
|
||||
DaycareData* create(void) const;
|
||||
|
||||
DaycareData(GC::DaycareData const& other);
|
||||
DaycareData(XD::DaycareData const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ namespace Colosseum {
|
|||
0x780: bag
|
||||
|
||||
0xa80: u8 trainerGender
|
||||
0xa84: u32 money
|
||||
0xa88: u32 pkCoupons + copy
|
||||
0xa84: u32 pokeDollars
|
||||
0xa88: u32 pokeCoupons + copy
|
||||
|
||||
0xac2: Rui's name
|
||||
*/
|
||||
|
||||
class LIBPKMGC_DECL PlayerData :
|
||||
|
|
@ -43,9 +45,14 @@ public:
|
|||
static const size_t size = 0xb18;
|
||||
PlayerData(void);
|
||||
PlayerData(PlayerData const& other);
|
||||
PlayerData& operator=(GC::PlayerData const& other);
|
||||
PlayerData& operator=(PlayerData const& other);
|
||||
void swap(GC::PlayerData& other);
|
||||
void swap(PlayerData& other);
|
||||
|
||||
PlayerData(const u8* inData);
|
||||
|
||||
GC::PokemonString* ruisName;
|
||||
|
||||
~PlayerData(void);
|
||||
PlayerData* clone(void) const;
|
||||
|
|
@ -54,8 +61,10 @@ public:
|
|||
void save(void);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
void deleteFields(void);
|
||||
private:
|
||||
PlayerData(XD::PlayerData const& other);
|
||||
void _deleteFields_extension(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ namespace Colosseum {
|
|||
0xbc : u8 contestLuster
|
||||
0xbd : u8 specialRibbons[12]
|
||||
0xc9 : u8 unimplentedRibbons (max. 15)
|
||||
0xca : u8 pkrsStatus
|
||||
0xca : u8 pokerusStatus
|
||||
0xcb : u8 flags[3] : egg, special ability, invalid pkm
|
||||
0xce : u8 GCUnk
|
||||
0xcf : u8 marks
|
||||
// shadow pkm data ?
|
||||
0xd0: s8 pkrsRemainingDays
|
||||
0xd0: s8 pokerusRemainingDays
|
||||
0xd1--0xd7 : ? ?
|
||||
0xd2: u16 unk2
|
||||
0xd4: u16 unk1
|
||||
|
|
@ -95,6 +95,8 @@ public:
|
|||
void swap(Pokemon& other);
|
||||
Pokemon& operator=(Pokemon const& other);
|
||||
|
||||
Pokemon(GC::Pokemon const& other);
|
||||
Pokemon(Base::Pokemon const& other);
|
||||
Pokemon(XD::Pokemon const& other);
|
||||
Pokemon(GBA::Pokemon const& other);
|
||||
Pokemon& operator=(GC::Pokemon const& other);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ public:
|
|||
|
||||
void save(void);
|
||||
|
||||
PokemonBox(Base::PokemonBox const& other);
|
||||
PokemonBox(GC::PokemonBox const& other);
|
||||
PokemonBox(XD::PokemonBox const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
|
||||
void save(void);
|
||||
|
||||
StrategyMemoData(GC::StrategyMemoData const& other);
|
||||
StrategyMemoData(XD::StrategyMemoData const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ public:
|
|||
StrategyMemoEntry* clone(void) const;
|
||||
StrategyMemoEntry* create(void) const;
|
||||
|
||||
bool isInfoPartial(void) const;
|
||||
void setInfoCompleteness(bool partial);
|
||||
bool isInfoIncomplete(void) const;
|
||||
void setInfoCompleteness(bool incomplete);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
TrainerData* clone(void) const;
|
||||
TrainerData* create(void) const;
|
||||
|
||||
TrainerData(GC::TrainerData const& other);
|
||||
TrainerData(XD::TrainerData const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include <boost/config/warning_disable.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#define LIBPKMGC_VERSION 1001002
|
||||
#define LIBPKMGC_VERSION 1002000
|
||||
#define LIBPKMGC_VERSION_MAJOR ((LIBPKMGC_VERSION / 1000000) % 1000)
|
||||
#define LIBPKMGC_VERSION_MINOR ((LIBPKMGC_VERSION / 1000) % 1000)
|
||||
#define LIBPKMGC_VERSION_BUILD (LIBPKMGC_VERSION % 1000)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fromArrayOfIntegers<type*, u8*>(BUFFER_NAME+off, ar##_tmp, ar##_tmp+sz)
|
|||
#define SV_ARRAY_E(type,ar,sz,off,etype) fromArrayOfEnumIntegers<type,etype*, u8*>(BUFFER_NAME+off, ar, ar+sz)
|
||||
#define SV_ARRAY_E_MAX(type,ar,sz,off,etype,mx) for(size_t i__ = 0; i__ < sz; ++i__) ar[i__] = ((u32)ar[i__] > (u32)mx) ? (etype)0 : ar[i__];\
|
||||
fromArrayOfEnumIntegers<type,etype*, u8*>(BUFFER_NAME+off, ar, ar+sz)
|
||||
#define SV_ARRAY_B(type,ar,sz,off) toArrayOfBoolIntegers<type, bool*, u8*>(BUFFER_NAME+off, ar, ar+sz)
|
||||
#define SV_ARRAY_B(type,ar,sz,off) fromArrayOfBoolIntegers<type, bool*, u8*>(BUFFER_NAME+off, ar, ar+sz)
|
||||
#define SV_BIT_ARRAY2(type, ar, sz, off, st) type ar##_tmp; LD_FIELD(type, ar##_tmp, off); ar##_tmp &= ~(((1U << sz) - 1) << (8*sizeof(type) - 1 - st - sz));\
|
||||
for(int i__ = 0; i__ < sz; ++i__) ar##_tmp |= ((ar[i__]) ? 1U : 0U) << (8*sizeof(type) - 1 - st - i__); SV_FIELD(type, ar##_tmp, off);
|
||||
#define SV_BIT_ARRAY(type, ar, sz, off) SV_BIT_ARRAY2(type,ar,sz,off,0)
|
||||
|
|
@ -112,25 +112,49 @@ for(int i__ = 0; i__ < sz; ++i__) ar##_tmp |= ((ar[i__]) ? 1U : 0U) << (8*sizeof
|
|||
#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){\
|
||||
namespace Colosseum {\
|
||||
cls::cls(XD::cls const& other) : GC::cls(cls::size){\
|
||||
initWithEmptyData(flgs);\
|
||||
GC::cls::operator=(other);\
|
||||
}\
|
||||
XD::cls::cls(Colosseum::cls const& other) : GC::cls(XD::cls::size){\
|
||||
cls::cls(GC::cls const& other) : GC::cls(cls::size) {\
|
||||
initWithEmptyData(flgs); \
|
||||
GC::cls::operator=(other); \
|
||||
}\
|
||||
}\
|
||||
namespace XD {\
|
||||
cls::cls(Colosseum::cls const& other) : GC::cls(cls::size){\
|
||||
initWithEmptyData(flgs);\
|
||||
GC::cls::operator=(other);\
|
||||
}\
|
||||
cls::cls(GC::cls const& other) : GC::cls(cls::size) {\
|
||||
initWithEmptyData(flgs); \
|
||||
GC::cls::operator=(other); \
|
||||
}\
|
||||
}
|
||||
|
||||
#define LIBPKMGC_GEN_CONVERTER_CTOR(cls) LIBPKMGC_GEN_CONVERTER_CTOR2(cls, 0)
|
||||
|
||||
#define LIBPKMGC_GEN_CONVERTER_CTOR_W_GBA(cls) LIBPKMGC_GEN_CONVERTER_CTOR(cls)\
|
||||
XD::cls::cls(GBA::cls const& other) : GC::cls(XD::cls::size){\
|
||||
namespace XD {\
|
||||
cls::cls(GBA::cls const& other) : GC::cls(cls::size){\
|
||||
initWithEmptyData(0);\
|
||||
GC::cls::operator=(other);\
|
||||
}\
|
||||
Colosseum::cls::cls(GBA::cls const& other) : GC::cls(XD::cls::size){\
|
||||
cls::cls(Base::cls const& other) : GC::cls(cls::size) {\
|
||||
initWithEmptyData(0); \
|
||||
GC::cls::operator=(other); \
|
||||
}\
|
||||
}\
|
||||
namespace Colosseum {\
|
||||
cls::cls(GBA::cls const& other) : GC::cls(cls::size){\
|
||||
initWithEmptyData(0);\
|
||||
GC::cls::operator=(other);\
|
||||
}\
|
||||
cls::cls(Base::cls const& other) : GC::cls(cls::size) {\
|
||||
initWithEmptyData(0); \
|
||||
GC::cls::operator=(other); \
|
||||
}\
|
||||
}
|
||||
|
||||
#define LIBPKMGC_GC_GEN_XD_VTF2(cls, flgs) \
|
||||
|
|
@ -155,6 +179,29 @@ 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)
|
||||
|
||||
#define LIBPKMGC_GC_GEN_NON_CONVERTIBLE_XD_VTF(cls) \
|
||||
cls& cls::operator=(GC::cls const& other){\
|
||||
if(LIBPKMGC_IS_XD(cls,&other)) operator=((cls const&)other);\
|
||||
else GC::cls::operator=(other);\
|
||||
return *this;\
|
||||
}\
|
||||
void cls::swap(GC::cls & other){\
|
||||
if(LIBPKMGC_IS_XD(cls,&other)) swap((cls&)other);\
|
||||
else GC::cls::swap(other);\
|
||||
}
|
||||
|
||||
#define LIBPKMGC_GC_GEN_NON_CONVERTIBLE_COL_VTF(cls) \
|
||||
cls& cls::operator=(GC::cls const& other){\
|
||||
if(LIBPKMGC_IS_COLOSSEUM(cls,&other)) operator=((cls const&)other);\
|
||||
else GC::cls::operator=(other);\
|
||||
return *this;\
|
||||
}\
|
||||
void cls::swap(GC::cls & other){\
|
||||
if(LIBPKMGC_IS_COLOSSEUM(cls,&other)) swap((cls&)other);\
|
||||
else GC::cls::swap(other);\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
void swap(Base::Pokemon& other);
|
||||
Pokemon& operator=(Base::Pokemon const& other);
|
||||
Pokemon(GC::Pokemon const& other);
|
||||
Pokemon(Base::Pokemon const& other);
|
||||
|
||||
void reload(const u8* data = NULL, u32 inFlags = 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ public:
|
|||
|
||||
virtual ~GroupBattleRule(void);
|
||||
|
||||
GroupBattleRule& operator=(GroupBattleRule const& other);
|
||||
virtual GroupBattleRule& operator=(GroupBattleRule const& other);
|
||||
virtual GroupBattleRule* clone(void) const = 0;
|
||||
virtual GroupBattleRule* create(void) const = 0;
|
||||
|
||||
void swap(GroupBattleRule& other);
|
||||
virtual void swap(GroupBattleRule& other);
|
||||
virtual void save(void);
|
||||
|
||||
u16 minLevel, maxLevel;
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ class LIBPKMGC_DECL PlayerData :
|
|||
{
|
||||
public:
|
||||
PlayerData(size_t inSize, const u8* inData = NULL);
|
||||
PlayerData& operator=(PlayerData const& other);
|
||||
virtual PlayerData& operator=(PlayerData const& other);
|
||||
|
||||
virtual PlayerData* clone(void) const = 0;
|
||||
virtual PlayerData* create(void) const = 0;
|
||||
|
||||
virtual ~PlayerData(void);
|
||||
|
||||
void swap(PlayerData& other);
|
||||
virtual void swap(PlayerData& other);
|
||||
|
||||
virtual void save(void);
|
||||
|
||||
|
|
@ -48,8 +48,8 @@ public:
|
|||
BagData* bag;
|
||||
|
||||
Gender trainerGender;
|
||||
u32 money;
|
||||
u32 pkCoupons;
|
||||
u32 pokeDollars;
|
||||
u32 pokeCoupons;
|
||||
|
||||
protected:
|
||||
PlayerData(PlayerData const& other);
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ public:
|
|||
|
||||
bool isEmpty(void) const;
|
||||
|
||||
virtual bool isInfoPartial(void) const = 0;
|
||||
virtual void setInfoCompleteness(bool partial) = 0;
|
||||
virtual bool isInfoIncomplete(void) const = 0;
|
||||
virtual void setInfoCompleteness(bool incomplete) = 0;
|
||||
|
||||
u16 flags;
|
||||
PokemonSpeciesIndex species;
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ public:
|
|||
virtual ~SaveSlot(void);
|
||||
|
||||
|
||||
void swap(SaveSlot& other);
|
||||
virtual void swap(SaveSlot& other);
|
||||
|
||||
SaveSlot& operator=(SaveSlot const& other);
|
||||
virtual SaveSlot& operator=(SaveSlot const& other);
|
||||
|
||||
virtual SaveSlot* clone(void) const = 0;
|
||||
virtual SaveSlot* create(void) const = 0;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
DaycareData* clone(void) const;
|
||||
DaycareData* create(void) const;
|
||||
|
||||
DaycareData(GC::DaycareData const& other);
|
||||
DaycareData(Colosseum::DaycareData const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ public:
|
|||
|
||||
~GroupBattleRule();
|
||||
|
||||
|
||||
GroupBattleRule& operator=(GC::GroupBattleRule const& other);
|
||||
GroupBattleRule& operator=(GroupBattleRule const& other);
|
||||
void swap(GC::GroupBattleRule& other);
|
||||
void swap(GroupBattleRule& other);
|
||||
GroupBattleRule* clone(void) const;
|
||||
GroupBattleRule* create(void) const;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ namespace XD {
|
|||
0x4c8: bag
|
||||
|
||||
0x8e0: u8 trainerGender
|
||||
0x8e4: u32 money
|
||||
0x8e8: u32 pkCoupons + copy
|
||||
0x8e4: u32 pokeDollars
|
||||
0x8e8: u32 pokeCoupons + copy
|
||||
*/
|
||||
|
||||
class LIBPKMGC_DECL PlayerData :
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ XD::Pokemon
|
|||
0x00: u16 species (cf PokemonInfo.h)
|
||||
0x03: u8 itemHeld (ItemInfo.h)
|
||||
0x04: u16 currentHP
|
||||
0x06: u16 happiness
|
||||
0x06: u16 friendship
|
||||
0x08: u16 locationCaught
|
||||
// 0x09 -- 0xd :: ??
|
||||
0x0a: u16 unk1
|
||||
|
|
@ -39,9 +39,9 @@ XD::Pokemon
|
|||
0x10: u8 OTGender (00 male 01 female 02 genderless=none)
|
||||
0x11: u8 currentLevel
|
||||
0x12: u8 Contest Luster
|
||||
0x13: u8 pkrsStatus
|
||||
0x13: u8 pokerusStatus
|
||||
0x14: u8 marks (bitfield)
|
||||
0x15: s8 pkrsRemainingDays
|
||||
0x15: s8 pokerusRemainingDays
|
||||
0x16: u16 status (3 psn, 4 psn (toxic ?), 5 par, 6 brn, 7 frzn, 8 slp)
|
||||
0x17: s8 turnsOfBadPoison (max 15.)
|
||||
0x18: s8 turnsOfSleepRemaining (max. 8)
|
||||
|
|
@ -97,6 +97,8 @@ public:
|
|||
void swap(Pokemon& other);
|
||||
Pokemon& operator=(Pokemon const& other);
|
||||
|
||||
Pokemon(GC::Pokemon const& other);
|
||||
Pokemon(Base::Pokemon const& other);
|
||||
Pokemon(Colosseum::Pokemon const& other);
|
||||
Pokemon(GBA::Pokemon const& other);
|
||||
Pokemon& operator=(GC::Pokemon const& other);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ public:
|
|||
|
||||
void save(void);
|
||||
|
||||
PokemonBox(Base::PokemonBox const& other);
|
||||
PokemonBox(GC::PokemonBox const& other);
|
||||
PokemonBox(Colosseum::PokemonBox const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ public:
|
|||
void save(void);
|
||||
|
||||
StrategyMemoData(Colosseum::StrategyMemoData const& other);
|
||||
StrategyMemoData(GC::StrategyMemoData const& other);
|
||||
|
||||
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ public:
|
|||
StrategyMemoEntry* clone(void) const;
|
||||
StrategyMemoEntry* create(void) const;
|
||||
|
||||
bool isInfoPartial(void) const;
|
||||
void setInfoCompleteness(bool partial);
|
||||
bool isInfoIncomplete(void) const;
|
||||
void setInfoCompleteness(bool incomplete);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
TrainerData* clone(void) const;
|
||||
TrainerData* create(void) const;
|
||||
|
||||
TrainerData(GC::TrainerData const& other);
|
||||
TrainerData(Colosseum::TrainerData const& other);
|
||||
protected:
|
||||
void loadFields(void);
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ public:
|
|||
void swap(SaveSlot& other);
|
||||
SaveSlot& operator=(SaveSlot const& other);
|
||||
|
||||
void swap(GC::SaveEditing::SaveSlot& other);
|
||||
SaveSlot& operator=(GC::SaveEditing::SaveSlot const& other);
|
||||
|
||||
void save(void);
|
||||
|
||||
bool checkChecksum(bool fix = false);
|
||||
|
|
|
|||
|
|
@ -155,19 +155,19 @@ char Pokemon::getUnownForm(void) const {
|
|||
return getUnownForm(PID);
|
||||
}
|
||||
|
||||
void Pokemon::normalizePkrs(void) {
|
||||
u8 st = pkrsStatus & 0xf, dr = pkrsStatus >> 4;
|
||||
void Pokemon::normalizepokerus(void) {
|
||||
u8 st = pokerusStatus & 0xf, dr = pokerusStatus >> 4;
|
||||
if (st == 0) {
|
||||
dr = 0;
|
||||
partyData.pkrsDaysRemaining = -1;
|
||||
partyData.pokerusDaysRemaining = -1;
|
||||
}
|
||||
else {
|
||||
u8 mx = 1 + (st & 0x3);
|
||||
dr = (dr > mx) ? mx : dr;
|
||||
partyData.pkrsDaysRemaining = (partyData.pkrsDaysRemaining > mx) ? mx : partyData.pkrsDaysRemaining;
|
||||
partyData.pokerusDaysRemaining = (partyData.pokerusDaysRemaining > mx) ? mx : partyData.pokerusDaysRemaining;
|
||||
}
|
||||
|
||||
pkrsStatus = (dr << 4) | st;
|
||||
pokerusStatus = (dr << 4) | st;
|
||||
}
|
||||
|
||||
void Pokemon::normalizeStatus(void) {
|
||||
|
|
@ -183,7 +183,7 @@ void Pokemon::resetPartyData(void) {
|
|||
updateLevelFromExp();
|
||||
partyData.status = NoStatus;
|
||||
partyData.currentHP = partyData.stats[0];
|
||||
partyData.pkrsDaysRemaining = ((pkrsStatus & 0xf0) != 0) ? pkrsStatus & 0xf : -1;
|
||||
partyData.pokerusDaysRemaining = ((pokerusStatus & 0xf0) != 0) ? pokerusStatus & 0xf : -1;
|
||||
}
|
||||
Pokemon::Pokemon(Pokemon const & other) : Base::DataStruct(other), OTName(NULL), name(NULL){
|
||||
copyNonVirtual(other);
|
||||
|
|
@ -211,7 +211,7 @@ void Pokemon::swap(Pokemon& other) {
|
|||
SW(species);
|
||||
SW(heldItem);
|
||||
|
||||
SW(happiness);
|
||||
SW(friendship);
|
||||
SW(locationCaught);
|
||||
SW(ballCaughtWith);
|
||||
SW(levelMet);
|
||||
|
|
@ -231,7 +231,7 @@ void Pokemon::swap(Pokemon& other) {
|
|||
other.name->fromUTF8(s1.c_str());
|
||||
}
|
||||
SW(contestLuster);
|
||||
SW(pkrsStatus);
|
||||
SW(pokerusStatus);
|
||||
SW(markings);
|
||||
|
||||
SW(experience);
|
||||
|
|
@ -273,13 +273,13 @@ void Pokemon::copyNonVirtual(Pokemon const& other) {
|
|||
CP(species);
|
||||
CP(heldItem);
|
||||
|
||||
CP(happiness);
|
||||
CP(friendship);
|
||||
CP(locationCaught);
|
||||
CP(ballCaughtWith);
|
||||
CP(levelMet);
|
||||
CP(OTGender);
|
||||
CP(contestLuster);
|
||||
CP(pkrsStatus);
|
||||
CP(pokerusStatus);
|
||||
CP(markings);
|
||||
|
||||
CP(experience);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <LibPkmGC/Base/PokemonBox.h>
|
||||
|
||||
#include <string>
|
||||
namespace LibPkmGC {
|
||||
namespace Base {
|
||||
|
||||
|
|
@ -42,7 +42,12 @@ PokemonBox::~PokemonBox(void) {
|
|||
|
||||
void PokemonBox::swap(PokemonBox& other) {
|
||||
DataStruct::swap(other);
|
||||
SW(name);
|
||||
if(name->isGBA() == other.name->isGBA()) SW(name);
|
||||
else {
|
||||
std::string s(name->toUTF8());
|
||||
name->fromUTF8(other.name->toUTF8());
|
||||
other.name->fromUTF8(s.c_str());
|
||||
}
|
||||
for (size_t i = 0; i < 30; ++i) pkm[i]->swap(*other.pkm[i]);
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +56,7 @@ PokemonBox& PokemonBox::operator=(PokemonBox const& other) {
|
|||
if (this != &other) {
|
||||
PokemonBox::deleteFields();
|
||||
for (size_t i = 0; i < 30; ++i) *pkm[i] = *(other.pkm[i]);
|
||||
CL(name);
|
||||
*name = *(other.name);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,36 @@ PlayerData::PlayerData(const u8* inData) : GC::PlayerData(0xb18, inData) {
|
|||
load();
|
||||
}
|
||||
|
||||
PlayerData::PlayerData(PlayerData const& other) : GC::PlayerData(other) {}
|
||||
PlayerData::PlayerData(PlayerData const& other) : GC::PlayerData(other) {
|
||||
CL(ruisName);
|
||||
}
|
||||
|
||||
PlayerData& PlayerData::operator=(PlayerData const& other) {
|
||||
if (this != &other) {
|
||||
GC::PlayerData::operator=(other);
|
||||
CL(ruisName);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PlayerData::swap(PlayerData & other) {
|
||||
GC::PlayerData::swap(other);
|
||||
SW(ruisName);
|
||||
}
|
||||
|
||||
LIBPKMGC_GC_GEN_NON_CONVERTIBLE_COL_VTF(PlayerData)
|
||||
|
||||
void PlayerData::_deleteFields_extension(void) {
|
||||
delete ruisName;
|
||||
}
|
||||
|
||||
void PlayerData::deleteFields(void) {
|
||||
GC::PlayerData::deleteFields();
|
||||
_deleteFields_extension();
|
||||
}
|
||||
|
||||
PlayerData::~PlayerData(void){
|
||||
_deleteFields_extension();
|
||||
}
|
||||
|
||||
PlayerData* PlayerData::clone(void) const {
|
||||
|
|
@ -47,8 +74,10 @@ void PlayerData::loadFields(void) {
|
|||
LD_FIELD_E(u8, trainerGender, 0xa80, Gender);
|
||||
if (trainerGender > Female) trainerGender = Male;
|
||||
|
||||
LD_FIELD_MAX(u32, money, 0xa84, 9999999);
|
||||
LD_FIELD_MAX(u32, pkCoupons, 0xa88, 9999999);
|
||||
LD_FIELD_MAX(u32, pokeDollars, 0xa84, 9999999);
|
||||
LD_FIELD_MAX(u32, pokeCoupons, 0xa88, 9999999);
|
||||
|
||||
ruisName = new GC::PokemonString(data + 0xac2, 10);
|
||||
|
||||
LD_SUBSTRUCTURE(BagData, bag, 0x780);
|
||||
}
|
||||
|
|
@ -57,9 +86,10 @@ void PlayerData::save(void) {
|
|||
GC::PlayerData::save();
|
||||
if (trainerGender > Female) trainerGender = Male;
|
||||
SV_FIELD_E(u8, trainerGender, 0xa80, Gender);
|
||||
SV_FIELD_MAX(u32, money, 0xa84, 9999999);
|
||||
SV_FIELD_MAX(u32, pkCoupons, 0xa88, 9999999);
|
||||
SV_FIELD(u32, pkCoupons, 0xa8c);
|
||||
SV_FIELD_MAX(u32, pokeDollars, 0xa84, 9999999);
|
||||
SV_FIELD_MAX(u32, pokeCoupons, 0xa88, 9999999);
|
||||
SV_FIELD(u32, pokeCoupons, 0xa8c);
|
||||
ruisName->save(data + 0xac2, 10);
|
||||
|
||||
SV_SUBSTRUCTURE(BagData, bag, 0x780);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void Pokemon::loadFields(void) {
|
|||
LD_ARRAY(u16, IVs_tmp, 6, 0xa4);
|
||||
for (size_t i = 0; i < 6; ++i) IVs[i] = (u8)((IVs_tmp[i] > 31) ? 31 : IVs_tmp[i]);
|
||||
|
||||
LD_FIELD_CONV(u16, happiness, 0xb0, u8);
|
||||
LD_FIELD_CONV(u16, friendship, 0xb0, u8);
|
||||
|
||||
LD_ARRAY(u8, contestStats, 5, 0xb2);
|
||||
LD_ARRAY_E_MAX(u8, contestAchievements, 5, 0xb7, ContestAchievementLevel, MasterContestWon);
|
||||
|
|
@ -94,11 +94,11 @@ void Pokemon::loadFields(void) {
|
|||
LD_ARRAY_B(u8, specialRibbons, 12, 0xbd);
|
||||
LD_FIELD_MAX(u8, unimplementedRibbons, 0xc9, 15);
|
||||
|
||||
LD_FIELD(u8, pkrsStatus, 0xca);
|
||||
LD_FIELD(u8, pokerusStatus, 0xca);
|
||||
LD_ARRAY_B(u8, pkmFlags, 3, 0xcb);
|
||||
LD_FIELD(u8, GCUnk, 0xce);
|
||||
LD_FIELD(u8, marksTmp, 0xcf);
|
||||
LD_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 0xd0, 4);
|
||||
LD_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 0xd0, 4);
|
||||
LD_FIELD(u16, unk2, 0xd2);
|
||||
LD_FIELD(u16, unk1, 0xd4);
|
||||
LD_FIELD(u16, shadowPkmID, 0xd8);
|
||||
|
|
@ -110,12 +110,12 @@ void Pokemon::loadFields(void) {
|
|||
moves[i].load(data + 0x78 + 4 * i);
|
||||
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
|
||||
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
normalizeStatus();
|
||||
}
|
||||
|
||||
void Pokemon::save(void) {
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
normalizeStatus();
|
||||
|
||||
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
|
||||
|
|
@ -154,7 +154,7 @@ void Pokemon::save(void) {
|
|||
}
|
||||
SV_ARRAY(u16, IVs_tmp, 6, 0xa4);
|
||||
|
||||
SV_FIELD(u16, (u16)happiness, 0xb0);
|
||||
SV_FIELD(u16, (u16)friendship, 0xb0);
|
||||
SV_ARRAY(u8, contestStats, 5, 0xb2);
|
||||
SV_ARRAY_E(u8, contestAchievements, 5, 0xb7, ContestAchievementLevel);
|
||||
SV_FIELD(u8, contestLuster, 0xbc);
|
||||
|
|
@ -163,11 +163,11 @@ void Pokemon::save(void) {
|
|||
SV_FIELD_MAX(u8, unimplementedRibbons, 0xc9, 15);
|
||||
|
||||
|
||||
SV_FIELD(u8, pkrsStatus, 0xca);
|
||||
SV_FIELD(u8, pokerusStatus, 0xca);
|
||||
SV_ARRAY_B(u8, pkmFlags, 3, 0xcb);
|
||||
SV_FIELD_MAX(u8, GCUnk, 0xce, 31);
|
||||
SV_FIELD(u8, markings.save(), 0xcf);
|
||||
SV_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 0xd0, 4);
|
||||
SV_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 0xd0, 4);
|
||||
SV_FIELD(u16, unk2, 0xd2);
|
||||
SV_FIELD(u16, unk1, 0xd4);
|
||||
SV_FIELD(u16, shadowPkmID, 0xd8);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ PokemonBox* PokemonBox::create(void) const {
|
|||
return new PokemonBox;
|
||||
}
|
||||
|
||||
|
||||
PokemonBox::PokemonBox(Base::PokemonBox const& other) : GC::PokemonBox(0x24a4) {
|
||||
initWithEmptyData();
|
||||
Base::PokemonBox::operator=(other);
|
||||
}
|
||||
|
||||
void PokemonBox::loadFields(void) {
|
||||
GC::PokemonBox::loadFields();
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ StrategyMemoEntry* StrategyMemoEntry::create(void) const {
|
|||
return new StrategyMemoEntry;
|
||||
}
|
||||
|
||||
bool StrategyMemoEntry::isInfoPartial(void) const {
|
||||
bool StrategyMemoEntry::isInfoIncomplete(void) const {
|
||||
return (flags == 2);
|
||||
}
|
||||
|
||||
void StrategyMemoEntry::setInfoCompleteness(bool partial) {
|
||||
flags = (partial) ? 2 : 0;
|
||||
void StrategyMemoEntry::setInfoCompleteness(bool incomplete) {
|
||||
flags = (incomplete) ? 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -258,10 +258,8 @@ void SaveSlot::loadFields(void) {
|
|||
LD_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox);
|
||||
LD_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare);
|
||||
LD_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo);
|
||||
//offset += 0x523c;
|
||||
offset = 0xe3e8;
|
||||
LD_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode);
|
||||
//offset += 0x1448;
|
||||
offset = 0x1c45c;
|
||||
LD_IMPLEMENTED_SUBSTRUCTURE(RibbonDescriptionsData, ribbonDescriptions);
|
||||
// unknown substructures following
|
||||
|
|
@ -285,17 +283,15 @@ void SaveSlot::save(void) {
|
|||
SV_IMPLEMENTED_SUBSTRUCTURE(MailboxData, mailbox);
|
||||
SV_IMPLEMENTED_SUBSTRUCTURE(DaycareData, daycare);
|
||||
SV_IMPLEMENTED_SUBSTRUCTURE(StrategyMemoData, strategyMemo);
|
||||
//offset += 0x523c;
|
||||
offset = 0xe3e8;
|
||||
SV_IMPLEMENTED_SUBSTRUCTURE(BattleModeData, battleMode);
|
||||
//offset += 0x1448;
|
||||
offset = 0x1c45c;
|
||||
SV_IMPLEMENTED_SUBSTRUCTURE(RibbonDescriptionsData, ribbonDescriptions);
|
||||
// unknown substructures following
|
||||
|
||||
|
||||
checkBothChecksums(true, true); // update checksums
|
||||
offset = 8;
|
||||
offset = 0;
|
||||
SV_IMPLEMENTED_SUBSTRUCTURE(GameConfigData, gameConfig);
|
||||
|
||||
std::copy(randomBytes, randomBytes + 20, data + 0x1dfd8);
|
||||
|
|
|
|||
|
|
@ -212,14 +212,14 @@ void Pokemon::loadFields(void) {
|
|||
LD_FIELD_E(u16, species, 32, PokemonSpeciesIndex);
|
||||
LD_FIELD_E(u16, heldItem, 34, ItemIndex);
|
||||
LD_FIELD_MAX(u32, experience, 36, getSpeciesExpTable(species)[100]);
|
||||
LD_FIELD(u8, happiness, 41);
|
||||
LD_FIELD(u8, friendship, 41);
|
||||
LD_FIELD(u16, unk2, 42);
|
||||
for (size_t i = 0; i < 6; ++i) EVs[statsOrder[i]] = data[56 + i];
|
||||
|
||||
LD_ARRAY(u8, contestStats, 5, 62);
|
||||
LD_FIELD(u8, contestLuster, 67);
|
||||
|
||||
LD_FIELD(u8, pkrsStatus, 68);
|
||||
LD_FIELD(u8, pokerusStatus, 68);
|
||||
LD_FIELD(u8, locationCaught, 69);
|
||||
|
||||
u16 origins;
|
||||
|
|
@ -275,7 +275,7 @@ void Pokemon::loadFields(void) {
|
|||
partyData.status = pokemonStatusFromBitField((u16)st, &(partyData.turnsOfBadPoison), &(partyData.turnsOfSleepRemaining));
|
||||
|
||||
LD_FIELD_MAX(u8, partyData.level, 84, 100);
|
||||
LD_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 85, 4);
|
||||
LD_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 85, 4);
|
||||
LD_FIELD(u16, partyData.currentHP, 86);
|
||||
u16 sta[6];
|
||||
LD_ARRAY(u16, sta, 6, 88);
|
||||
|
|
@ -292,7 +292,7 @@ void Pokemon::loadFields(void) {
|
|||
name = new PokemonString(data + 8, 10, version.language == Japanese);
|
||||
OTName = new PokemonString(data + 20, 7, version.language == Japanese);
|
||||
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
normalizeStatus();
|
||||
|
||||
if (!checkChecksum(false)) setInvalidPokemonFlag(true);
|
||||
|
|
@ -319,7 +319,7 @@ void Pokemon::save(void) {
|
|||
data[27] = markings.save();
|
||||
version.save(lg, gm);
|
||||
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
|
||||
name->save(data + 8, 10);
|
||||
OTName->save(data + 20, 7);
|
||||
|
|
@ -341,14 +341,14 @@ void Pokemon::save(void) {
|
|||
SV_FIELD_E(u16, species, 32, PokemonSpeciesIndex);
|
||||
SV_FIELD_E(u16, heldItem, 34, ItemIndex);
|
||||
SV_FIELD_MAX(u32, experience, 36, getSpeciesExpTable(species)[100]);
|
||||
SV_FIELD(u8, happiness, 41);
|
||||
SV_FIELD(u8, friendship, 41);
|
||||
SV_FIELD(u16, unk2, 42);
|
||||
|
||||
for (size_t i = 0; i < 6; ++i) data[56 + i] = EVs[statsOrder[i]];
|
||||
SV_ARRAY(u8, contestStats, 5, 62);
|
||||
SV_FIELD(u8, contestLuster, 67);
|
||||
|
||||
SV_FIELD(u8, pkrsStatus, 68);
|
||||
SV_FIELD(u8, pokerusStatus, 68);
|
||||
SV_FIELD(u8, locationCaught, 69);
|
||||
|
||||
u16 origins = 0;
|
||||
|
|
@ -399,8 +399,8 @@ void Pokemon::save(void) {
|
|||
SV_FIELD(u32, st, 80);
|
||||
|
||||
SV_FIELD_MAX(u8, partyData.level, 84, 100);
|
||||
SV_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 85, 4);
|
||||
if (partyData.pkrsDaysRemaining < -1) partyData.pkrsDaysRemaining = -1;
|
||||
SV_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 85, 4);
|
||||
if (partyData.pokerusDaysRemaining < -1) partyData.pokerusDaysRemaining = -1;
|
||||
SV_FIELD_MAX(u16, partyData.currentHP, 86, partyData.stats[0]);
|
||||
u16 sta[6];
|
||||
for (size_t i = 0; i < 6; ++i) sta[i] = partyData.stats[statsOrder[i]];
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ 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);
|
||||
deleteFields();
|
||||
CP(minLevel);
|
||||
CP(maxLevel);
|
||||
CP(maxLevelSum);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ PlayerData::~PlayerData(void) {
|
|||
PlayerData::deleteFields();
|
||||
}
|
||||
|
||||
PlayerData::PlayerData(PlayerData const& other) : Base::DataStruct(other), money(other.money), pkCoupons(other.pkCoupons),
|
||||
PlayerData::PlayerData(PlayerData const& other) : Base::DataStruct(other), pokeDollars(other.pokeDollars), pokeCoupons(other.pokeCoupons),
|
||||
trainerGender(other.trainerGender){
|
||||
CL(trainer);
|
||||
CL(bag);
|
||||
|
|
@ -45,7 +45,7 @@ PlayerData& PlayerData::operator=(PlayerData const& other) {
|
|||
Base::DataStruct::operator=(other);
|
||||
if (this != &other) {
|
||||
PlayerData::deleteFields();
|
||||
CP(money); CP(pkCoupons);
|
||||
CP(pokeDollars); CP(pokeCoupons);
|
||||
CL(trainer);
|
||||
CL(bag);
|
||||
CP(trainerGender);
|
||||
|
|
@ -56,7 +56,7 @@ PlayerData& PlayerData::operator=(PlayerData const& other) {
|
|||
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(money); SW(pkCoupons);
|
||||
SW(pokeDollars); SW(pokeCoupons);
|
||||
CL(trainer);
|
||||
SW(bag);
|
||||
SW(trainerGender);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ SaveSlot& SaveSlot::operator=(SaveSlot const& other) {
|
|||
|
||||
Base::DataStruct::operator=(other);
|
||||
if (this != &other) {
|
||||
SaveSlot::deleteFields();
|
||||
deleteFields();
|
||||
randomBytes = new u8[nbRandomBytes];
|
||||
CP_ARRAY(randomBytes, nbRandomBytes);
|
||||
CP(magic);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,20 @@ void GroupBattleRule::swap(GroupBattleRule & other) {
|
|||
SW(customName);
|
||||
}
|
||||
|
||||
GroupBattleRule& GroupBattleRule::operator=(GroupBattleRule const& other) {
|
||||
if (this != &other) {
|
||||
GC::GroupBattleRule::operator=(other);
|
||||
CL(customName);
|
||||
CP(nbPkm);
|
||||
CP(isBattleOpen);
|
||||
CP(revealDeoxysForm);
|
||||
CP(customName);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
LIBPKMGC_GC_GEN_NON_CONVERTIBLE_XD_VTF(GroupBattleRule)
|
||||
|
||||
GroupBattleRule* GroupBattleRule::clone(void) const {
|
||||
return new GroupBattleRule(*this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ void PlayerData::loadFields(void) {
|
|||
LD_FIELD_E(u8, trainerGender, 0x8e0, Gender);
|
||||
if (trainerGender > Female) trainerGender = Male;
|
||||
|
||||
LD_FIELD_MAX(u32, money, 0x8e4, 9999999);
|
||||
LD_FIELD_MAX(u32, pkCoupons, 0x8e8, 9999999);
|
||||
LD_FIELD_MAX(u32, pokeDollars, 0x8e4, 9999999);
|
||||
LD_FIELD_MAX(u32, pokeCoupons, 0x8e8, 9999999);
|
||||
|
||||
LD_SUBSTRUCTURE(BagData, bag, 0x4c8);
|
||||
}
|
||||
|
|
@ -59,9 +59,9 @@ void PlayerData::save(void) {
|
|||
if (trainerGender > Female) trainerGender = Male;
|
||||
SV_FIELD_E(u8, trainerGender, 0x8e0, Gender);
|
||||
|
||||
SV_FIELD_MAX(u32, money, 0x8e4, 9999999);
|
||||
SV_FIELD_MAX(u32, pkCoupons, 0x8e8, 9999999);
|
||||
SV_FIELD(u32, pkCoupons, 0x8ec);
|
||||
SV_FIELD_MAX(u32, pokeDollars, 0x8e4, 9999999);
|
||||
SV_FIELD_MAX(u32, pokeCoupons, 0x8e8, 9999999);
|
||||
SV_FIELD(u32, pokeCoupons, 0x8ec);
|
||||
|
||||
SV_SUBSTRUCTURE(BagData, bag, 0x4c8);
|
||||
//0x94a: total step counter
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ void Pokemon::loadFields(void) {
|
|||
LD_FIELD_E(u8, heldItem, 0x03, ItemIndex);
|
||||
LD_FIELD(u16, partyData.currentHP, 0x04);
|
||||
|
||||
LD_FIELD_CONV(u16, happiness, 0x06, u8);
|
||||
LD_FIELD_CONV(u16, friendship, 0x06, u8);
|
||||
|
||||
LD_FIELD_CONV(u16, locationCaught, 0x08, u8);
|
||||
|
||||
|
|
@ -78,10 +78,10 @@ void Pokemon::loadFields(void) {
|
|||
if (partyData.level > 100) partyData.level = 100;
|
||||
|
||||
LD_FIELD(u8, contestLuster, 0x12);
|
||||
LD_FIELD(u8, pkrsStatus, 0x13);
|
||||
LD_FIELD(u8, pokerusStatus, 0x13);
|
||||
LD_FIELD(u8, marksTmp, 0x14);
|
||||
|
||||
LD_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 0x15, 4);
|
||||
LD_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 0x15, 4);
|
||||
LD_FIELD_E(u8, partyData.status, 0x16, PokemonStatus);
|
||||
LD_FIELD(s8, partyData.turnsOfBadPoison, 0x17);
|
||||
LD_FIELD(s8, partyData.turnsOfSleepRemaining, 0x18);
|
||||
|
|
@ -122,13 +122,13 @@ void Pokemon::loadFields(void) {
|
|||
|
||||
if (partyData.currentHP > partyData.stats[0]) partyData.currentHP = partyData.stats[0];
|
||||
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
normalizeStatus();
|
||||
|
||||
}
|
||||
|
||||
void Pokemon::save(void) {
|
||||
normalizePkrs();
|
||||
normalizepokerus();
|
||||
normalizeStatus();
|
||||
|
||||
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
|
||||
|
|
@ -138,7 +138,7 @@ void Pokemon::save(void) {
|
|||
SV_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex);
|
||||
SV_FIELD_E(u8, heldItem, 0x03, ItemIndex);
|
||||
SV_FIELD(u16, partyData.currentHP, 0x04);
|
||||
SV_FIELD_CONV(u16, happiness, 0x06, u8);
|
||||
SV_FIELD_CONV(u16, friendship, 0x06, u8);
|
||||
SV_FIELD_CONV(u16, locationCaught, 0x08, u8);
|
||||
|
||||
SV_FIELD(u16, unk1, 0xa);
|
||||
|
|
@ -152,10 +152,10 @@ void Pokemon::save(void) {
|
|||
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, pokerusStatus, 0x13);
|
||||
SV_FIELD(u8, markings.save(), 0x14);
|
||||
|
||||
SV_FIELD_MAX(s8, partyData.pkrsDaysRemaining, 0x15, 4);
|
||||
SV_FIELD_MAX(s8, partyData.pokerusDaysRemaining, 0x15, 4);
|
||||
SV_FIELD_E(u8, partyData.status, 0x16, PokemonStatus);
|
||||
SV_FIELD(s8, partyData.turnsOfBadPoison, 0x17);
|
||||
SV_FIELD(s8, partyData.turnsOfSleepRemaining, 0x18);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,12 @@ PokemonBox* PokemonBox::create(void) const {
|
|||
return new PokemonBox;
|
||||
}
|
||||
|
||||
PokemonBox::PokemonBox(Base::PokemonBox const& other) : GC::PokemonBox(0x170c) {
|
||||
initWithEmptyData();
|
||||
Base::PokemonBox::operator=(other);
|
||||
}
|
||||
|
||||
|
||||
void PokemonBox::loadFields(void) {
|
||||
GC::PokemonBox::loadFields();
|
||||
LD_SUBSTRUCTURE_ARRAY(Pokemon, pkm, 30, 0x14);
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ StrategyMemoEntry* StrategyMemoEntry::create(void) const {
|
|||
return new StrategyMemoEntry;
|
||||
}
|
||||
|
||||
bool StrategyMemoEntry::isInfoPartial(void) const{
|
||||
bool StrategyMemoEntry::isInfoIncomplete(void) const{
|
||||
return false;
|
||||
}
|
||||
|
||||
void StrategyMemoEntry::setInfoCompleteness(bool partial){
|
||||
void StrategyMemoEntry::setInfoCompleteness(bool incomplete){
|
||||
flags = (species == NoSpecies) ? 0 : 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,6 +158,21 @@ SaveSlot& SaveSlot::operator=(SaveSlot const & other) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
void SaveSlot::swap(GC::SaveEditing::SaveSlot& other) {
|
||||
if (LIBPKMGC_IS_XD(SaveEditing::SaveSlot, &other))
|
||||
swap((SaveSlot&)other);
|
||||
else
|
||||
GC::SaveEditing::SaveSlot::swap(other);
|
||||
}
|
||||
|
||||
SaveSlot& SaveSlot::operator=(GC::SaveEditing::SaveSlot const& other) {
|
||||
if (LIBPKMGC_IS_XD(SaveEditing::SaveSlot, &other))
|
||||
operator=((SaveSlot const&)other);
|
||||
else
|
||||
GC::SaveEditing::SaveSlot::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SaveSlot::loadData(u32 flags) {
|
||||
bool decrypted = (flags & 1) == 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5LinguistTools)
|
||||
|
||||
file(GLOB_RECURSE source_files src/*)
|
||||
|
|
@ -14,9 +15,9 @@ LIST(APPEND source_files resources/PkmGCSaveEditor.rc)
|
|||
include_directories(${LIBPKMGC_INCLUDE_DIRS} src/)
|
||||
|
||||
add_executable(PkmGCSaveEditor WIN32 ${source_files})
|
||||
target_link_libraries(PkmGCSaveEditor LibPkmGC Qt5::Widgets)
|
||||
target_link_libraries(PkmGCSaveEditor LibPkmGC Qt5::Widgets Qt5::Network)
|
||||
|
||||
set(PKMGCSAVEEDITOR_SUPPORTED_LANGUAGES en fr CACHE INTERNAL "PkmGCSaveEditor's supported languages" FORCE)
|
||||
set(PKMGCSAVEEDITOR_SUPPORTED_LANGUAGES en fr de CACHE INTERNAL "PkmGCSaveEditor's supported languages" FORCE)
|
||||
|
||||
get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
|
||||
execute_process(COMMAND ${QT5_QMAKE_EXECUTABLE} -query QT_INSTALL_BINS OUTPUT_VARIABLE QT5_BINARY_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ PkmGCSaveEditor is a cross-platform, open source (GPLv3) Pokémon Colosseum and
|
|||
|
||||
##Current features:
|
||||
* You can edit all of your Pokémon, import and export them. You can NOT edit the information specific to Shadow Pokémon, though.
|
||||
* You can import/export Pokémon from/to Base64 strings
|
||||
* GBA Pokémon are **fully** supported as well.
|
||||
* As a consequence conversion between Colosseum, XD and GBA Pokémon is **fully** supported.
|
||||
* It is done (almost) exactly like it is in Colosseum/XD during a GC<->GBA trade (meaning, for example, that the data specific to shadow Pokémon is lost).
|
||||
|
|
@ -12,6 +13,7 @@ PkmGCSaveEditor is a cross-platform, open source (GPLv3) Pokémon Colosseum and
|
|||
* You can edit your PC (both Pokémon and items).
|
||||
* You can edit your Daycare.
|
||||
* You can edit your Strategy Memo.
|
||||
* You can edit the description of some ribbons
|
||||
* On XD, you can edit your Purifier.
|
||||
|
||||
###Additional features *partially* supported by the backend library **only**:
|
||||
|
|
@ -22,7 +24,7 @@ Editing your Mailbox and your Battle Mode data.
|
|||
* Dumped names (thanks [Tiddlywinks](http://projectpokemon.org/forums/showthread.php?46253-Stars-Pokemon-colosseum-and-XD-hacking-tutorial-part-2-Text-editing&p=205271&viewfull=1#post205271)!): English, French, German, Spanish, Italian, Japanese
|
||||
|
||||
##Special thanks to:
|
||||
Ralf (for his "offset tables"), StarsMMD, Tiddlywinks.
|
||||
peterpansexuall (German translation), Yago (testing), Ralf (for his "offset tables"), StarsMMD, Tiddlywinks.
|
||||
|
||||
_Tips_: The most recent versions of Dolphin (e.g. 5.0-rc) can directly read and write to GCI files, making testing your changes much easier.
|
||||
You can dump/restore your physical memory card contents using Ctr-Gcs-DacoTaco-Edition.
|
||||
|
|
|
|||
|
|
@ -50,4 +50,19 @@ LibPkmGC::LanguageIndex generateDumpedNamesLanguage(void) {
|
|||
LibPkmGC::LanguageIndex ret = (LibPkmGC::LanguageIndex) languageCodeToIndexMap.value(lg, (size_t)LibPkmGC::English);
|
||||
if (ret > LibPkmGC::Spanish) ret = LibPkmGC::English;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void addToolTipTo(QLabel* lbl, QString const& toolTipTxt) {
|
||||
lbl->setText(lbl->text() + "*");
|
||||
lbl->setToolTip(toolTipTxt);
|
||||
}
|
||||
|
||||
QString replaceSpecialNameCharsIn(QString inStr) {
|
||||
// U+2030 -> U+2025
|
||||
return inStr.replace(QChar(0x2030), QChar(0x2025));
|
||||
}
|
||||
|
||||
QString replaceSpecialNameCharsOut(QString outStr) {
|
||||
// U+2025 -> U+2030
|
||||
return outStr.replace(QChar(0x2025), QChar(0x2030));
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef _PKMGCSAVEEDITOR_GLOBALS_H
|
||||
#define _PKMGCSAVEEDITOR_GLOBALS_H
|
||||
|
||||
#define PKMGCSAVEEDITOR_VERSION 1001002
|
||||
#define PKMGCSAVEEDITOR_VERSION 1002000
|
||||
#define PKMGCSAVEEDITOR_VERSION_MAJOR ((PKMGCSAVEEDITOR_VERSION / 1000000) % 1000)
|
||||
#define PKMGCSAVEEDITOR_VERSION_MINOR ((PKMGCSAVEEDITOR_VERSION / 1000) % 1000)
|
||||
#define PKMGCSAVEEDITOR_VERSION_BUILD (PKMGCSAVEEDITOR_VERSION % 1000)
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#include <LibPkmGC/GBA/Pokemon.h>
|
||||
#include <QLocale>
|
||||
#include <QMap>
|
||||
#include <QLabel>
|
||||
|
||||
const QString appName = QString("PkmGCSaveEditor v%1.%2.%3").arg(PKMGCSAVEEDITOR_VERSION_MAJOR).arg(PKMGCSAVEEDITOR_VERSION_MINOR).arg(PKMGCSAVEEDITOR_VERSION_BUILD);
|
||||
|
||||
|
|
@ -48,4 +49,9 @@ extern QString lastSaveDirectory;
|
|||
|
||||
LibPkmGC::LanguageIndex generateDumpedNamesLanguage(void);
|
||||
|
||||
void addToolTipTo(QLabel* lbl, QString const& toolTipTxt);
|
||||
|
||||
QString replaceSpecialNameCharsIn(QString inStr);
|
||||
QString replaceSpecialNameCharsOut(QString outStr);
|
||||
|
||||
#endif
|
||||
|
|
@ -62,6 +62,7 @@ void ItemComboBox::resetItemList(void){
|
|||
}
|
||||
|
||||
ItemIndex ItemComboBox::currentItemIndex(void) const{
|
||||
int index = currentIndex();
|
||||
return _indices[this->currentIndex()];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include <Core/IDataUI.h>
|
||||
#include <QPushButton>
|
||||
#include <QTableWidget>
|
||||
#include <QLabel>
|
||||
#include <QHeaderView>
|
||||
#include <QComboBox>
|
||||
#include <QShortcut>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ QFormLayout(){
|
|||
}
|
||||
|
||||
void TrainerInfoLayout::trainerName(LibPkmGC::Base::PokemonString * outName) {
|
||||
outName->fromUTF8(nameFld->text().toUtf8().data());
|
||||
outName->fromUTF8(replaceSpecialNameCharsOut(nameFld->text()).toUtf8().data());
|
||||
}
|
||||
|
||||
u16 TrainerInfoLayout::TID(void) const {
|
||||
|
|
@ -63,7 +63,7 @@ Gender TrainerInfoLayout::trainerGender(void) const {
|
|||
}
|
||||
|
||||
void TrainerInfoLayout::setTrainerName(LibPkmGC::Base::PokemonString* inName) {
|
||||
if(inName != NULL) nameFld->setText(inName->toUTF8());
|
||||
if(inName != NULL) nameFld->setText(replaceSpecialNameCharsIn(inName->toUTF8()));
|
||||
}
|
||||
|
||||
void TrainerInfoLayout::setTID(LibPkmGC::u16 inTID) {
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@
|
|||
#include <QButtonGroup>
|
||||
#include <QRadioButton>
|
||||
#include <QLineEdit>
|
||||
#include <algorithm>
|
||||
#include <Core/UnsignedSpinbox.h>
|
||||
#include <LibPkmGC/Core/PokemonInfo.h>
|
||||
#include <LibPkmGC/Base/PokemonString.h>
|
||||
#include <Core/Globals.h>
|
||||
|
||||
class TrainerInfoLayout : public QFormLayout{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -33,16 +33,21 @@ void PlayerUI::initWidget(void){
|
|||
generalTabLayout = new QVBoxLayout;
|
||||
trainerInfoBox = new QGroupBox(tr("Trainer information"));
|
||||
trainerInfoFld = new TrainerInfoLayout;
|
||||
ruisNameFld = new QLineEdit;
|
||||
|
||||
ruisNameFld->setMaxLength(10);
|
||||
trainerInfoFld->addRow(tr("Rui's name"), ruisNameFld);
|
||||
|
||||
trainerInfoBox->setLayout(trainerInfoFld);
|
||||
|
||||
|
||||
currenciesBox = new QGroupBox(tr("Currencies"));
|
||||
currenciesLayout = new QFormLayout;
|
||||
moneyFld = new UnsignedSpinbox<32>;
|
||||
pkCouponsFld = new UnsignedSpinbox<32>;
|
||||
pokeDollarsFld = new UnsignedSpinbox<32>;
|
||||
pokeCouponsFld = new UnsignedSpinbox<32>;
|
||||
|
||||
currenciesLayout->addRow(tr("Money"), moneyFld);
|
||||
currenciesLayout->addRow(tr("Pok""\xc3\xa9""coupons"), pkCouponsFld); // Pokécoupons
|
||||
currenciesLayout->addRow(tr("Pok\xc3\xa9""dollars"), pokeDollarsFld);
|
||||
currenciesLayout->addRow(tr("Pok""\xc3\xa9""Coupons"), pokeCouponsFld); // Pokécoupons
|
||||
|
||||
currenciesBox->setLayout(currenciesLayout);
|
||||
|
||||
|
|
@ -72,16 +77,22 @@ void PlayerUI::initWidget(void){
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
ruisNameFld->setVisible(!isXD);
|
||||
trainerInfoFld->labelForField(ruisNameFld)->setVisible(!isXD);
|
||||
|
||||
if (!isXD) {
|
||||
ruisNameFld->setText(replaceSpecialNameCharsIn(static_cast<Colosseum::PlayerData*>(player)->ruisName->toUTF8()));
|
||||
}
|
||||
|
||||
trainerInfoFld->set(player->trainer->trainerName, player->trainer->TID, player->trainer->SID, player->trainerGender);
|
||||
moneyFld->setValue((int)player->money);
|
||||
pkCouponsFld->setValue((int)player->pkCoupons);
|
||||
pokeDollarsFld->setValue((int)player->pokeDollars);
|
||||
pokeCouponsFld->setValue((int)player->pokeCoupons);
|
||||
|
||||
bagTab->bag = player->bag;
|
||||
bagTab->parseData();
|
||||
|
|
@ -96,12 +107,14 @@ void PlayerUI::parseData(void){
|
|||
}
|
||||
|
||||
void PlayerUI::saveChanges(void) {
|
||||
if (!isXD)
|
||||
static_cast<Colosseum::PlayerData*>(player)->ruisName->fromUTF8(replaceSpecialNameCharsOut(ruisNameFld->text()).toUtf8().data());
|
||||
trainerInfoFld->trainerName(player->trainer->trainerName);
|
||||
player->trainer->TID = trainerInfoFld->TID();
|
||||
player->trainer->SID = trainerInfoFld->SID();
|
||||
player->trainerGender = trainerInfoFld->trainerGender();
|
||||
player->money = moneyFld->unsignedValue();
|
||||
player->pkCoupons = pkCouponsFld->unsignedValue();
|
||||
player->pokeDollars = pokeDollarsFld->unsignedValue();
|
||||
player->pokeCoupons = pokeCouponsFld->unsignedValue();
|
||||
|
||||
for (size_t i = 0; i < 6; ++i) pkmFlds[i]->saveChanges();
|
||||
bagTab->saveChanges();
|
||||
|
|
|
|||
|
|
@ -51,12 +51,15 @@ private:
|
|||
|
||||
QWidget* generalTab;
|
||||
QVBoxLayout* generalTabLayout;
|
||||
|
||||
QGroupBox* trainerInfoBox;
|
||||
TrainerInfoLayout* trainerInfoFld;
|
||||
QLineEdit* ruisNameFld;
|
||||
|
||||
|
||||
QGroupBox* currenciesBox;
|
||||
QFormLayout* currenciesLayout;
|
||||
UnsignedSpinbox<32> *moneyFld, *pkCouponsFld;
|
||||
UnsignedSpinbox<32> *pokeDollarsFld, *pokeCouponsFld;
|
||||
|
||||
BagEditor* bagTab;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,106 @@
|
|||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
using namespace LibPkmGC;
|
||||
using namespace Localization;
|
||||
|
||||
namespace GCUIs {
|
||||
|
||||
QStringList PokemonBase64InputDialog::formats(void) {
|
||||
return QStringList() << tr("Colosseum") << tr("XD") << tr("GBA (100 bytes)") << tr("GBA (80 bytes)");
|
||||
}
|
||||
|
||||
PokemonBase64InputDialog::PokemonBase64InputDialog(QWidget* parent) : QDialog(parent), mainLayout(new QVBoxLayout), inputLayout(new QFormLayout),
|
||||
format(new QLabel(tr("N/A"))), contents(new QPlainTextEdit), buttons(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)){
|
||||
this->setWindowTitle(tr("Base64 input"));
|
||||
contents->setWordWrapMode(QTextOption::WrapAnywhere);
|
||||
|
||||
inputLayout->addRow(tr("Format"), format);
|
||||
inputLayout->addRow(tr("Contents"), contents);
|
||||
mainLayout->addLayout(inputLayout);
|
||||
mainLayout->addWidget(buttons);
|
||||
setLayout(mainLayout);
|
||||
connect(contents, SIGNAL(textChanged()), this, SLOT(update()));
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
QByteArray const & PokemonBase64InputDialog::result(void) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void PokemonBase64InputDialog::accept(void) {
|
||||
if (!valid) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid content size."));
|
||||
return;
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void PokemonBase64InputDialog::update(void) {
|
||||
const QStringList fmts = formats();
|
||||
QString str(contents->toPlainText());
|
||||
data = QByteArray::fromBase64(str.toLocal8Bit());
|
||||
valid = true;
|
||||
switch (data.size()) {
|
||||
case 0: format->setText(tr("N/A")); break;
|
||||
case 0x138: format->setText(fmts[0]); break;
|
||||
case 0xc4: format->setText(fmts[1]); break;
|
||||
case 100: format->setText(fmts[2]); break;
|
||||
case 80: format->setText(fmts[3]); break;
|
||||
default: format->setText(tr("Invalid")); valid = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PokemonBase64OutputDialog::PokemonBase64OutputDialog(GC::Pokemon* inPkm, QWidget * parent) : QDialog(parent), pkm(inPkm), mainLayout(new QVBoxLayout),
|
||||
outputLayout(new QFormLayout), format(new QComboBox), contents(new QPlainTextEdit), buttons(new QDialogButtonBox(QDialogButtonBox::Ok)) {
|
||||
this->setWindowTitle(tr("Base64 output"));
|
||||
|
||||
format->addItems(PokemonBase64InputDialog::formats());
|
||||
contents->setReadOnly(true);
|
||||
contents->setWordWrapMode(QTextOption::WrapAnywhere);
|
||||
outputLayout->addRow(tr("Format"), format);
|
||||
outputLayout->addRow(tr("Contents"), contents);
|
||||
|
||||
mainLayout->addLayout(outputLayout);
|
||||
mainLayout->addWidget(buttons);
|
||||
setLayout(mainLayout);
|
||||
|
||||
format->setCurrentIndex((LIBPKMGC_IS_XD(Pokemon, pkm)) ? 1 : 0);
|
||||
|
||||
connect(format, SIGNAL(currentIndexChanged(int)), this, SLOT(update()));
|
||||
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PokemonBase64OutputDialog::update(void) {
|
||||
Base::Pokemon* exportedPkm = NULL;
|
||||
bool gba80 = false;
|
||||
|
||||
switch (format->currentIndex()) {
|
||||
case 0: exportedPkm = new Colosseum::Pokemon(*pkm); break;
|
||||
case 1: exportedPkm = new XD::Pokemon(*pkm); break;
|
||||
case 2: exportedPkm = new GBA::Pokemon(*pkm); break;
|
||||
case 3: exportedPkm = new GBA::Pokemon(*pkm); gba80 = true; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (exportedPkm == NULL) return;
|
||||
|
||||
exportedPkm->save();
|
||||
QByteArray data((const char*)exportedPkm->data, (int) ((gba80) ? 80 : exportedPkm->fixedSize));
|
||||
|
||||
QByteArray b64 = data.toBase64();
|
||||
contents->setPlainText(QString(b64.constData()));
|
||||
}
|
||||
|
||||
PokemonDisplayWidget::PokemonDisplayWidget(GC::Pokemon* inPkm, LibPkmGC::PokemonStorageInfo const& inLocation, QWidget* parent) :
|
||||
QWidget(parent), pkm(inPkm), location(inLocation), pkmBackup(NULL) {
|
||||
init();
|
||||
|
|
@ -44,9 +139,24 @@ void PokemonDisplayWidget::initWidget(void) {
|
|||
summary = new QLabel;
|
||||
editButton = new QPushButton(tr("Edit"));
|
||||
deleteButton = new QPushButton(tr("Delete"));
|
||||
|
||||
importButton = new QPushButton(tr("Import"));
|
||||
exportButton = new QPushButton(tr("Export"));
|
||||
|
||||
importMenu = new QMenu;
|
||||
importFileAction = new QAction(tr("&File..."), this);
|
||||
importBase64Action = new QAction(tr("&Base64..."), this);
|
||||
importMenu->addAction(importFileAction);
|
||||
importMenu->addAction(importBase64Action);
|
||||
exportMenu = new QMenu;
|
||||
exportFileAction = new QAction(tr("&File..."), this);
|
||||
exportBase64Action = new QAction(tr("&Base64..."), this);
|
||||
exportMenu->addAction(exportFileAction);
|
||||
exportMenu->addAction(exportBase64Action);
|
||||
|
||||
importButton->setMenu(importMenu);
|
||||
exportButton->setMenu(exportMenu);
|
||||
|
||||
mainLayout->addWidget(nameFld);
|
||||
mainLayout->addWidget(summary);
|
||||
buttonsLayout->addWidget(editButton);
|
||||
|
|
@ -58,8 +168,10 @@ void PokemonDisplayWidget::initWidget(void) {
|
|||
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()));
|
||||
connect(importFileAction, SIGNAL(triggered()), this, SLOT(openImportPkmFileDialog()));
|
||||
connect(importBase64Action, SIGNAL(triggered()), this, SLOT(openImportBase64Dialog()));
|
||||
connect(exportFileAction, SIGNAL(triggered()), this, SLOT(openExportPkmFileDialog()));
|
||||
connect(exportBase64Action, SIGNAL(triggered()), this, SLOT(openExportBase64Dialog()));
|
||||
this->setLayout(mainLayout);
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +192,7 @@ void PokemonDisplayWidget::cancelChanges(void) {
|
|||
}
|
||||
|
||||
void PokemonDisplayWidget::updatePkmNameAndSummary(void) {
|
||||
const QStringList invalidStrs = PokemonUI::invalidPkmStrs();
|
||||
LanguageIndex lg = generateDumpedNamesLanguage();
|
||||
QString s, tt;
|
||||
|
||||
|
|
@ -89,25 +202,25 @@ void PokemonDisplayWidget::updatePkmNameAndSummary(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
nameFld->setText(pkm->name->toUTF8());
|
||||
nameFld->setText(replaceSpecialNameCharsIn(pkm->name->toUTF8()));
|
||||
|
||||
s = "(";
|
||||
if (!getSpeciesData(pkm->species).isValid || (pkm->species == Bonsly && !LIBPKMGC_IS_XD(Pokemon,pkm))) {
|
||||
tt = tr("Invalid species");
|
||||
tt = invalidStrs[1];
|
||||
}
|
||||
if (pkm->version.isIncomplete()) {
|
||||
if (!tt.isEmpty()) tt += "\n";
|
||||
tt = tr("Invalid version info");
|
||||
tt = invalidStrs[2];
|
||||
}
|
||||
if (pkm->pkmFlags[LIBPKMGC_GC_INVALID_POKEMON_FLAG]) {
|
||||
if (pkm->isMarkedAsInvalid()) {
|
||||
if (!tt.isEmpty()) tt += "\n";
|
||||
tt += tr("\"Invalid Pok\xc3\xa9mon\" flag set");
|
||||
tt += invalidStrs[3];
|
||||
}
|
||||
|
||||
summary->setToolTip(tt);
|
||||
|
||||
if (!tt.isEmpty()) {
|
||||
s += "<span style='color:red;'>INVALID</span>";
|
||||
s += "<span style = 'color:red;'>" + invalidStrs[0] + "*</span>";
|
||||
}
|
||||
else {
|
||||
s += tr("Lv. %n ", "", (pkm->partyData.level > 100) ? 100 : pkm->partyData.level);
|
||||
|
|
@ -152,7 +265,7 @@ QString PokemonDisplayWidget::selectFilters(bool op) {
|
|||
(F[0] + ";;" + F[1] + ";;" + F[2] + ";;" + gbaencfilter);
|
||||
}
|
||||
|
||||
void PokemonDisplayWidget::openImportPkmDialog(void) {
|
||||
void PokemonDisplayWidget::openImportPkmFileDialog(void) {
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Pok\xc3\xa9mon file"), lastPkmDirectory, selectFilters(true));
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
|
|
@ -168,7 +281,21 @@ void PokemonDisplayWidget::openImportPkmDialog(void) {
|
|||
|
||||
}
|
||||
|
||||
void PokemonDisplayWidget::openExportPkmDialog(void) {
|
||||
void PokemonDisplayWidget::openImportBase64Dialog(void) {
|
||||
PokemonBase64InputDialog dlg(this);
|
||||
if(dlg.exec() == QDialog::Rejected) return;
|
||||
QByteArray const& data = dlg.result();
|
||||
if (data.isEmpty()) return;
|
||||
|
||||
switch (data.size()) {
|
||||
case 0x138: importPkmFromData<Colosseum::Pokemon>(data); break;
|
||||
case 0xc4: importPkmFromData<XD::Pokemon>(data); break;
|
||||
case 100: case 80: importPkmFromData<GBA::Pokemon>(data, data.size()); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void PokemonDisplayWidget::openExportPkmFileDialog(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.");
|
||||
const QString gbaencfilter = tr("Encrypted GBA Pok\xc3\xa9mon files (*.pkm *.3gpkm)");
|
||||
|
|
@ -221,4 +348,8 @@ void PokemonDisplayWidget::openExportPkmDialog(void) {
|
|||
|
||||
}
|
||||
|
||||
void PokemonDisplayWidget::openExportBase64Dialog(void) {
|
||||
PokemonBase64OutputDialog(pkm, this).exec();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,9 +20,48 @@
|
|||
#define _PKMGCSAVEEDITOR_POKEMON_DISPLAY_WIDGET_H
|
||||
|
||||
#include <GCUIs/PokemonUI.h>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
namespace GCUIs {
|
||||
|
||||
class PokemonBase64InputDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QStringList formats(void);
|
||||
PokemonBase64InputDialog(QWidget* parent = NULL);
|
||||
|
||||
QByteArray const& result(void);
|
||||
|
||||
private:
|
||||
bool valid;
|
||||
QByteArray data;
|
||||
QFormLayout* inputLayout;
|
||||
QVBoxLayout* mainLayout;
|
||||
QLabel* format;
|
||||
QPlainTextEdit* contents;
|
||||
QDialogButtonBox* buttons;
|
||||
public slots:
|
||||
void accept(void);
|
||||
void update(void);
|
||||
};
|
||||
|
||||
class PokemonBase64OutputDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PokemonBase64OutputDialog(LibPkmGC::GC::Pokemon* inPkm, QWidget* parent = NULL);
|
||||
|
||||
LibPkmGC::GC::Pokemon* pkm;
|
||||
|
||||
private:
|
||||
QFormLayout* outputLayout;
|
||||
QVBoxLayout* mainLayout;
|
||||
QComboBox* format;
|
||||
QPlainTextEdit* contents;
|
||||
QDialogButtonBox* buttons;
|
||||
public slots:
|
||||
void update(void);
|
||||
};
|
||||
|
||||
class PokemonDisplayWidget : public QWidget, IDataUI {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
@ -45,8 +84,10 @@ signals:
|
|||
|
||||
public slots:
|
||||
void updatePkmNameAndSummary(void);
|
||||
void openImportPkmDialog(void);
|
||||
void openExportPkmDialog(void);
|
||||
void openImportPkmFileDialog(void);
|
||||
void openImportBase64Dialog(void);
|
||||
void openExportPkmFileDialog(void);
|
||||
void openExportBase64Dialog(void);
|
||||
void deletePkm(void);
|
||||
void openPkmUI(void);
|
||||
|
||||
|
|
@ -60,10 +101,42 @@ private:
|
|||
QPushButton *importButton;
|
||||
QPushButton *exportButton;
|
||||
|
||||
QMenu* importMenu;
|
||||
QAction *importFileAction, *importBase64Action;
|
||||
QMenu* exportMenu;
|
||||
QAction *exportFileAction, *exportBase64Action;
|
||||
|
||||
|
||||
QString selectFilters(bool op = true);
|
||||
|
||||
template<typename P>
|
||||
void readExpected(QString fileName, size_t sz = P::size) {
|
||||
void importPkmFromData(QByteArray const& ba, size_t sz = P::size) {
|
||||
P* importedPkm = NULL;
|
||||
if (sz != 80)
|
||||
importedPkm = new P((const u8*)ba.constData());
|
||||
else {
|
||||
GBA::Pokemon* pk2 = GBA::Pokemon::load80((const u8*)ba.constData());
|
||||
importedPkm = new P(*pk2);
|
||||
delete pk2;
|
||||
}
|
||||
|
||||
if (pkm == NULL) {
|
||||
if (LIBPKMGC_IS_XD(Pokemon, importedPkm) || (currentSaveSlot != NULL && LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot)))
|
||||
pkm = new XD::Pokemon(*importedPkm);
|
||||
else
|
||||
pkm = new Colosseum::Pokemon(*importedPkm);
|
||||
}
|
||||
else *pkm = *importedPkm;
|
||||
|
||||
if (P::size == 100 && currentSaveSlot != NULL)
|
||||
pkm->version.currentRegion = currentSaveSlot->gameConfig->version.currentRegion;
|
||||
|
||||
delete importedPkm;
|
||||
parseData();
|
||||
}
|
||||
|
||||
template<typename P>
|
||||
void readExpected(QString const& fileName, size_t sz = P::size) {
|
||||
const QString errmsg = tr("Could not open file.");
|
||||
const QString errmsg2 = tr("An error occured while reading the specified Pok\xc3\xa9mon file.");
|
||||
QFile file(fileName);
|
||||
|
|
@ -78,30 +151,8 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
P* importedPkm = NULL;
|
||||
if (sz != 80)
|
||||
importedPkm = new P((const u8*)ba.data());
|
||||
else {
|
||||
GBA::Pokemon* pk2 = GBA::Pokemon::load80((const u8*)ba.data());
|
||||
importedPkm = new P(*pk2);
|
||||
delete pk2;
|
||||
}
|
||||
|
||||
|
||||
if (pkm == NULL) {
|
||||
if (LIBPKMGC_IS_XD(Pokemon, importedPkm) || (currentSaveSlot != NULL && LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot)))
|
||||
pkm = new XD::Pokemon(*importedPkm);
|
||||
else
|
||||
pkm = new Colosseum::Pokemon(*importedPkm);
|
||||
}
|
||||
else *pkm = *importedPkm;
|
||||
|
||||
if (P::size == 100 && currentSaveSlot != NULL)
|
||||
pkm->version.currentRegion = currentSaveSlot->gameConfig->version.currentRegion;
|
||||
|
||||
parseData();
|
||||
importPkmFromData<P>(ba, sz);
|
||||
lastPkmDirectory = QFileInfo(fileName).canonicalPath();
|
||||
delete importedPkm;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,21 @@ QStringList PokemonUI::statusNames(void) {
|
|||
tr("Paralyzed") << tr("Burnt") << tr("Frozen") << tr("Asleep");
|
||||
}
|
||||
|
||||
QStringList PokemonUI::ribbonNames(void) {
|
||||
return 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") <<
|
||||
tr("Unimplemented 1") << tr("Unimplemented 2") << tr("Unimplemented 3") << tr("Unimplemented 4");
|
||||
}
|
||||
|
||||
QString PokemonUI::ribbonHasNeverBeenMadeAvailableStr(void) {
|
||||
return tr("This ribbon has never been made available");
|
||||
}
|
||||
|
||||
QStringList PokemonUI::invalidPkmStrs(void) {
|
||||
return QStringList() << tr("INVALID") << tr("Invalid species") << tr("Invalid version info") << tr("\"Invalid Pok\xc3\xa9mon\" flag set");
|
||||
}
|
||||
|
||||
void PokemonUI::initWidget(void){
|
||||
const QStringList contestStatNames = QStringList() << tr("Coolness") << tr("Beauty") << tr("Cuteness")
|
||||
<< tr("Cleverness") << tr("Toughness");
|
||||
|
|
@ -124,9 +139,7 @@ void PokemonUI::initWidget(void){
|
|||
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");
|
||||
const QStringList srNames = ribbonNames();
|
||||
|
||||
LanguageIndex lg = generateDumpedNamesLanguage();
|
||||
|
||||
|
|
@ -168,10 +181,10 @@ void PokemonUI::initWidget(void){
|
|||
syncLevelAndExpFldsCheckBox = new QCheckBox;
|
||||
|
||||
heldItemFld = new ItemComboBox;
|
||||
happinessFld = new UnsignedSpinbox<8>;
|
||||
pkrsStatusLayout = new QHBoxLayout;
|
||||
pkrsDaysRemainingFld = new UnsignedSpinbox<3>;
|
||||
pkrsStrainFld = new UnsignedSpinbox<4>;
|
||||
friendshipFld = new UnsignedSpinbox<8>;
|
||||
pokerusStatusLayout = new QHBoxLayout;
|
||||
pokerusDaysRemainingFld = new UnsignedSpinbox<3>;
|
||||
pokerusStrainFld = new UnsignedSpinbox<4>;
|
||||
flagsLayout = new QGridLayout;
|
||||
flagsButtonGroup = new QButtonGroup;
|
||||
markingsLayout = new QHBoxLayout;
|
||||
|
|
@ -190,7 +203,7 @@ void PokemonUI::initWidget(void){
|
|||
levelFld->setRange(1, 100);
|
||||
syncLevelAndExpFldsCheckBox->setChecked(true);
|
||||
|
||||
pkrsDaysRemainingFld->setUnsignedRange(0, 4);
|
||||
pokerusDaysRemainingFld->setUnsignedRange(0, 4);
|
||||
|
||||
|
||||
experienceLevelAndSyncLayout->addWidget(experienceFld,2);
|
||||
|
|
@ -199,8 +212,8 @@ void PokemonUI::initWidget(void){
|
|||
levelAndSyncLayout->setAlignment(Qt::AlignRight);
|
||||
experienceLevelAndSyncLayout->addLayout(levelAndSyncLayout);
|
||||
|
||||
pkrsStatusLayout->addWidget(pkrsDaysRemainingFld);
|
||||
pkrsStatusLayout->addWidget(pkrsStrainFld);
|
||||
pokerusStatusLayout->addWidget(pokerusDaysRemainingFld);
|
||||
pokerusStatusLayout->addWidget(pokerusStrainFld);
|
||||
|
||||
eggFlagCheckBox = new QCheckBox(tr("Egg")); secondAbilityFlagCheckBox = new QCheckBox(tr("Second ability"));
|
||||
invalidPokemonCheckBox = new QCheckBox(tr("Invalid Pok\xc3\xa9mon"));
|
||||
|
|
@ -237,8 +250,8 @@ void PokemonUI::initWidget(void){
|
|||
generalCoreSubTabLayout->addRow(tr("Ability"), abilityFld);
|
||||
generalCoreSubTabLayout->addRow(tr("Experience and level"), experienceLevelAndSyncLayout);
|
||||
generalCoreSubTabLayout->addRow(tr("Held item"), heldItemFld);
|
||||
generalCoreSubTabLayout->addRow(tr("Happiness"), happinessFld);
|
||||
generalCoreSubTabLayout->addRow(tr("Pok\xc3\xa9rus (days remaing and strain)"), pkrsStatusLayout);
|
||||
generalCoreSubTabLayout->addRow(tr("Friendship"), friendshipFld);
|
||||
generalCoreSubTabLayout->addRow(tr("Pok\xc3\xa9rus (days remaing and strain)"), pokerusStatusLayout);
|
||||
generalCoreSubTabLayout->addRow(tr("Flags"), flagsLayout);
|
||||
generalCoreSubTabLayout->addRow(tr("Markings"), markingsLayout);
|
||||
|
||||
|
|
@ -296,8 +309,8 @@ void PokemonUI::initWidget(void){
|
|||
coreCaptureInfoLayout->addRow(tr("Fateful encounter (obedient)"), obedientFld);
|
||||
coreCaptureInfoLayout->addRow(tr("Ball caught with"), ballCaughtWithFld);
|
||||
|
||||
coreCaptureInfoLayout->labelForField(obedientFld)->setToolTip(tr("Mew and Deoxys need this field to be checked so they can obey.\n"
|
||||
"Pok\xc3\xa9mon caught in XD always have this field checked."));
|
||||
addToolTipTo((QLabel*) coreCaptureInfoLayout->labelForField(obedientFld), tr("Mew and Deoxys need this field to be checked so they can obey.\n"
|
||||
"Pok\xc3\xa9mon caught in XD always have this field checked"));
|
||||
coreCaptureInfoBox->setLayout(coreCaptureInfoLayout);
|
||||
OTBox->setLayout(OTField);
|
||||
versionBox->setLayout(versionFld);
|
||||
|
|
@ -399,8 +412,14 @@ void PokemonUI::initWidget(void){
|
|||
specialRibbonsFldGroup = new QButtonGroup;
|
||||
specialRibbonsFldGroup->setExclusive(false);
|
||||
|
||||
const QString rna = ribbonHasNeverBeenMadeAvailableStr();
|
||||
for (size_t i = 0; i < 12; ++i) {
|
||||
specialRibbonsFlds[i] = new QCheckBox(srNames[i]);
|
||||
if (i >= 5 && i <= 11 && i != 9 && i != 10) {
|
||||
specialRibbonsFlds[i] = new QCheckBox(srNames[i] + "*");
|
||||
specialRibbonsFlds[i]->setToolTip(rna);
|
||||
}
|
||||
else
|
||||
specialRibbonsFlds[i] = new QCheckBox(srNames[i]);
|
||||
specialRibbonsFldGroup->addButton(specialRibbonsFlds[i], (int)i);
|
||||
specialRibbonsLayout->addWidget(specialRibbonsFlds[i], (int)(i % 4), (int)(i / 4));
|
||||
}
|
||||
|
|
@ -435,7 +454,7 @@ void PokemonUI::initWidget(void){
|
|||
connect(experienceFld, SIGNAL(valueChanged(int)), this, SLOT(updateLevelFromExperience()));
|
||||
connect(levelFld, SIGNAL(valueChanged(int)), this, SLOT(updateExperienceFromLevel()));
|
||||
connect(statusFld, SIGNAL(currentIndexChanged(int)), SLOT(statusChangeHandler()));
|
||||
connect(pkrsStrainFld, SIGNAL(valueChanged(int)), this, SLOT(updatePkrsDaysRemaining()));
|
||||
connect(pokerusStrainFld, SIGNAL(valueChanged(int)), this, SLOT(updatePokerusDaysRemaining()));
|
||||
connect(OTField, SIGNAL(TIDorSIDChanged()), this, SLOT(updatePkmAttributes()));
|
||||
connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler()));
|
||||
connect(copyInfoFromSaveButton, SIGNAL(clicked()), this, SLOT(copyInfoFromSave()));
|
||||
|
|
@ -465,7 +484,7 @@ void PokemonUI::parseData(void){
|
|||
heldItemFld->set(GIVABLE_ITEMS_ALLOWED, isXD);
|
||||
|
||||
|
||||
nameFld->setText(pkm->name->toUTF8());
|
||||
nameFld->setText(replaceSpecialNameCharsIn(pkm->name->toUTF8()));
|
||||
|
||||
speciesFld->setCurrentIndex((int)Localization::pkmSpeciesIndexToNameIndex(pkm->species));
|
||||
if (pkm->species == Bonsly && !isXD) speciesFld->setCurrentIndex(0);
|
||||
|
|
@ -480,7 +499,7 @@ void PokemonUI::parseData(void){
|
|||
|
||||
|
||||
heldItemFld->setCurrentItemIndex(pkm->heldItem);
|
||||
happinessFld->setUnsignedValue(pkm->happiness);
|
||||
friendshipFld->setUnsignedValue(pkm->friendship);
|
||||
|
||||
|
||||
statusFld->disconnect(SIGNAL(currentIndexChanged(int)), this);
|
||||
|
|
@ -491,13 +510,13 @@ void PokemonUI::parseData(void){
|
|||
connect(statusFld, SIGNAL(currentIndexChanged(int)), SLOT(statusChangeHandler()));
|
||||
|
||||
|
||||
pkrsStrainFld->disconnect(SIGNAL(valueChanged(int)), this);
|
||||
pkrsStrainFld->setUnsignedValue(pkm->pkrsStatus & 0xf);
|
||||
pkrsDaysRemainingFld->setUnsignedValue(pkm->pkrsStatus >> 4);
|
||||
partyPrksDaysRemainingFld->setValue(pkm->pkrsStatus >> 4);
|
||||
updatePkrsDaysRemaining();
|
||||
pokerusStrainFld->disconnect(SIGNAL(valueChanged(int)), this);
|
||||
pokerusStrainFld->setUnsignedValue(pkm->pokerusStatus & 0xf);
|
||||
pokerusDaysRemainingFld->setUnsignedValue(pkm->pokerusStatus >> 4);
|
||||
partyPrksDaysRemainingFld->setValue(pkm->pokerusStatus >> 4);
|
||||
updatePokerusDaysRemaining();
|
||||
|
||||
connect(pkrsStrainFld, SIGNAL(valueChanged(int)), this, SLOT(updatePkrsDaysRemaining()));
|
||||
connect(pokerusStrainFld, SIGNAL(valueChanged(int)), this, SLOT(updatePokerusDaysRemaining()));
|
||||
|
||||
|
||||
|
||||
|
|
@ -555,7 +574,7 @@ void PokemonUI::parseData(void){
|
|||
|
||||
void PokemonUI::saveChanges(void){
|
||||
pkm->species = nameIndexToPkmSpeciesIndex(speciesFld->currentIndex());
|
||||
pkm->name->fromUTF8(nameFld->text().toUtf8().data());
|
||||
pkm->name->fromUTF8(replaceSpecialNameCharsOut(nameFld->text()).toUtf8().data());
|
||||
pkm->PID = PIDFld->unsignedValue();
|
||||
|
||||
pkm->setSecondAbilityFlag(abilityFld->currentIndex() != 0);
|
||||
|
|
@ -563,9 +582,9 @@ void PokemonUI::saveChanges(void){
|
|||
pkm->partyData.level = (u8)levelFld->unsignedValue();
|
||||
|
||||
pkm->heldItem = heldItemFld->currentItemIndex();
|
||||
pkm->happiness = (u8)happinessFld->unsignedValue();
|
||||
pkm->pkrsStatus = (u8)((pkrsDaysRemainingFld->unsignedValue() << 4) | pkrsStrainFld->unsignedValue());
|
||||
pkm->partyData.pkrsDaysRemaining = (s8)(partyPrksDaysRemainingFld->value());
|
||||
pkm->friendship = (u8)friendshipFld->unsignedValue();
|
||||
pkm->pokerusStatus = (u8)((pokerusDaysRemainingFld->unsignedValue() << 4) | pokerusStrainFld->unsignedValue());
|
||||
pkm->partyData.pokerusDaysRemaining = (s8)(partyPrksDaysRemainingFld->value());
|
||||
|
||||
pkm->partyData.status = (statusFld->currentIndex() == 0) ? NoStatus : (PokemonStatus)(2 + statusFld->currentIndex());
|
||||
pkm->partyData.turnsOfBadPoison = (s8)turnsOfBadPoisonFld->value();
|
||||
|
|
@ -613,6 +632,8 @@ void PokemonUI::saveChanges(void){
|
|||
pkm->specialRibbons[i] = specialRibbonsFlds[i]->isChecked();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString PokemonUI::getShortPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species, LibPkmGC::u32 PID, LibPkmGC::u16 TID, LibPkmGC::u16 SID){
|
||||
QString ret;
|
||||
|
||||
|
|
@ -658,15 +679,16 @@ QString PokemonUI::getLongPkmAttributeText(LibPkmGC::PokemonSpeciesIndex species
|
|||
}
|
||||
|
||||
QString PokemonUI::getShortPkmAttributeText(void){
|
||||
const QString invalid = "<span style='color:red;'>INVALID</span>";
|
||||
const QStringList invalidStrs = invalidPkmStrs();
|
||||
const QString invalid = "<span style='color:red;'>"+invalidStrs[0]+"*</span>";
|
||||
QString ret, tt;
|
||||
if (pkm == NULL || speciesFld->currentIndex() == 0) return "";
|
||||
|
||||
if (versionFld->info().isIncomplete())
|
||||
tt = tr("Invalid version info");
|
||||
tt = invalidStrs[2];
|
||||
if (isXD && invalidPokemonCheckBox->isChecked()) {
|
||||
if (!tt.isEmpty()) tt += "\n";
|
||||
tt += tr("\"Invalid Pok\xc3\xa9mon\" flag set");
|
||||
tt += invalidStrs[3];
|
||||
}
|
||||
|
||||
attributesFld->setToolTip(tt);
|
||||
|
|
@ -682,15 +704,16 @@ QString PokemonUI::getShortPkmAttributeText(void){
|
|||
}
|
||||
|
||||
QString PokemonUI::getLongPkmAttributeText(void){
|
||||
const QString invalid = "<span style='color:red;'>INVALID</span>";
|
||||
const QStringList invalidStrs = invalidPkmStrs();
|
||||
const QString invalid = "<span style='color:red;'>" + invalidStrs[0] + "*</span>";
|
||||
QString ret, tt;
|
||||
if (pkm == NULL || speciesFld->currentIndex() == 0) return "";
|
||||
|
||||
if (versionFld->info().isIncomplete())
|
||||
tt = tr("Invalid version info");
|
||||
tt = invalidStrs[2];
|
||||
if (isXD && invalidPokemonCheckBox->isChecked()) {
|
||||
if (!tt.isEmpty()) tt += "\n";
|
||||
tt += tr("\"Invalid Pok\xc3\xa9mon\" flag set");
|
||||
tt += invalidStrs[3];
|
||||
}
|
||||
|
||||
attributesFld->setToolTip(tt);
|
||||
|
|
@ -798,19 +821,19 @@ void PokemonUI::PIDChangeHandler(void) {
|
|||
updateMainStats();
|
||||
}
|
||||
|
||||
void PokemonUI::updatePkrsDaysRemaining(void) {
|
||||
if (pkrsStrainFld->unsignedValue() == 0) {
|
||||
pkrsDaysRemainingFld->setValue(0);
|
||||
pkrsDaysRemainingFld->setDisabled(true);
|
||||
void PokemonUI::updatePokerusDaysRemaining(void) {
|
||||
if (pokerusStrainFld->unsignedValue() == 0) {
|
||||
pokerusDaysRemainingFld->setValue(0);
|
||||
pokerusDaysRemainingFld->setDisabled(true);
|
||||
partyPrksDaysRemainingFld->setRange(-1, -1);
|
||||
partyPrksDaysRemainingFld->setValue(-1);
|
||||
partyPrksDaysRemainingFld->setDisabled(true);
|
||||
}
|
||||
else {
|
||||
pkrsDaysRemainingFld->setDisabled(false);
|
||||
pokerusDaysRemainingFld->setDisabled(false);
|
||||
partyPrksDaysRemainingFld->setDisabled(false);
|
||||
pkrsDaysRemainingFld->setUnsignedRange(0, (pkrsStrainFld->unsignedValue() & 0x3) + 1);
|
||||
partyPrksDaysRemainingFld->setRange(0, (pkrsStrainFld->unsignedValue() & 0x3) + 1);
|
||||
pokerusDaysRemainingFld->setUnsignedRange(0, (pokerusStrainFld->unsignedValue() & 0x3) + 1);
|
||||
partyPrksDaysRemainingFld->setRange(0, (pokerusStrainFld->unsignedValue() & 0x3) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include <QGroupBox>
|
||||
#include <QTabWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QStackedWidget>
|
||||
#include <Core/VersionInfoLayout.h>
|
||||
|
|
@ -82,6 +81,9 @@ public:
|
|||
|
||||
|
||||
static QStringList statusNames(void);
|
||||
static QStringList ribbonNames(void);
|
||||
static QString ribbonHasNeverBeenMadeAvailableStr(void);
|
||||
static QStringList invalidPkmStrs(void);
|
||||
|
||||
void parseData(void);
|
||||
void saveChanges(void);
|
||||
|
|
@ -128,10 +130,10 @@ private:
|
|||
QCheckBox* syncLevelAndExpFldsCheckBox;
|
||||
|
||||
ItemComboBox* heldItemFld;
|
||||
UnsignedSpinbox<8>* happinessFld;
|
||||
QHBoxLayout* pkrsStatusLayout;
|
||||
UnsignedSpinbox<3>* pkrsDaysRemainingFld;
|
||||
UnsignedSpinbox<4>* pkrsStrainFld;
|
||||
UnsignedSpinbox<8>* friendshipFld;
|
||||
QHBoxLayout* pokerusStatusLayout;
|
||||
UnsignedSpinbox<3>* pokerusDaysRemainingFld;
|
||||
UnsignedSpinbox<4>* pokerusStrainFld;
|
||||
|
||||
QComboBox* statusFld;
|
||||
QSpinBox* turnsOfBadPoisonFld;
|
||||
|
|
@ -210,7 +212,7 @@ public slots:
|
|||
void updateLevelFromExperience(void);
|
||||
void speciesChangeHandler(void);
|
||||
void PIDChangeHandler(void);
|
||||
void updatePkrsDaysRemaining(void);
|
||||
void updatePokerusDaysRemaining(void);
|
||||
void statusChangeHandler(void);
|
||||
|
||||
void updateFlags(void);
|
||||
|
|
|
|||
70
PkmGCSaveEditor/src/GCUIs/RibbonDescriptionsUI.cpp
Normal file
70
PkmGCSaveEditor/src/GCUIs/RibbonDescriptionsUI.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) TuxSH 2015
|
||||
* This file is part of PkmGCSaveEditor.
|
||||
*
|
||||
* PkmGCSaveEditor is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PkmGCSaveEditor 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with PkmGCSaveEditor. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <GCUIs/RibbonDescriptionsUI.h>
|
||||
|
||||
using namespace LibPkmGC; using namespace Localization; using namespace Base;
|
||||
|
||||
namespace GCUIs {
|
||||
|
||||
RibbonDescriptionsUI::RibbonDescriptionsUI(GC::RibbonDescriptionsData* inRibbonDescriptions, QWidget *parent, Qt::WindowFlags f) :
|
||||
DataUI(parent, f), ribbonDescriptions(inRibbonDescriptions) {
|
||||
init();
|
||||
}
|
||||
|
||||
inline QStringList getRibbonDescriptionTexts(void) {
|
||||
LanguageIndex lg = generateDumpedNamesLanguage();
|
||||
QStringList ret;
|
||||
for (size_t i = 0; i < 65; ++i)
|
||||
ret.append(Localization::getRibbonDescription(lg, i));
|
||||
return ret;
|
||||
}
|
||||
void RibbonDescriptionsUI::initWidget(void) {
|
||||
const QStringList srNames = PokemonUI::ribbonNames();
|
||||
const QString rna = PokemonUI::ribbonHasNeverBeenMadeAvailableStr();
|
||||
const QStringList descr = getRibbonDescriptionTexts();
|
||||
|
||||
descriptionsLayout = new QFormLayout;
|
||||
for (size_t i = 0; i < 11; ++i) {
|
||||
descriptionsFld[i] = new QComboBox;
|
||||
descriptionsFld[i]->addItems(descr);
|
||||
descriptionsLayout->addRow(srNames[i + 5], descriptionsFld[i]);
|
||||
if (i >= 0 && i <= 6 && i != 4 && i != 5)
|
||||
addToolTipTo((QLabel*)descriptionsLayout->labelForField(descriptionsFld[i]), rna);
|
||||
}
|
||||
descriptionsLayout->setHorizontalSpacing(20);
|
||||
mainLayout->addLayout(descriptionsLayout);
|
||||
DataUI::initWidget();
|
||||
}
|
||||
|
||||
|
||||
void RibbonDescriptionsUI::parseData(void) {
|
||||
if (ribbonDescriptions == NULL) return;
|
||||
isXD = LIBPKMGC_IS_XD(RibbonDescriptionsData, ribbonDescriptions);
|
||||
|
||||
for (size_t i = 0; i < 11; ++i)
|
||||
descriptionsFld[i]->setCurrentIndex(ribbonDescriptions->descriptions[i]);
|
||||
}
|
||||
|
||||
void RibbonDescriptionsUI::saveChanges(void) {
|
||||
for (size_t i = 0; i < 11; ++i)
|
||||
ribbonDescriptions->descriptions[i] = (u8)descriptionsFld[i]->currentIndex();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
49
PkmGCSaveEditor/src/GCUIs/RibbonDescriptionsUI.h
Normal file
49
PkmGCSaveEditor/src/GCUIs/RibbonDescriptionsUI.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) TuxSH 2015
|
||||
* This file is part of PkmGCSaveEditor.
|
||||
*
|
||||
* PkmGCSaveEditor is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PkmGCSaveEditor 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with PkmGCSaveEditor. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PKMGCSAVEEDITOR_RIBBON_DESCRIPTIONS_UI_H
|
||||
#define _PKMGCSAVEEDITOR_RIBBON_DESCRIPTIONS_UI_H
|
||||
|
||||
#include <GCUIs/PokemonUI.h>
|
||||
|
||||
|
||||
|
||||
namespace GCUIs {
|
||||
|
||||
class RibbonDescriptionsUI : public DataUI {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RibbonDescriptionsUI(LibPkmGC::GC::RibbonDescriptionsData* inRibbonDescriptions = NULL, QWidget *parent = NULL, Qt::WindowFlags f = Qt::Window);
|
||||
void parseData(void);
|
||||
void saveChanges(void);
|
||||
|
||||
|
||||
LibPkmGC::GC::RibbonDescriptionsData* ribbonDescriptions;
|
||||
|
||||
protected:
|
||||
void initWidget(void);
|
||||
private:
|
||||
QFormLayout* descriptionsLayout;
|
||||
|
||||
QComboBox* descriptionsFld[11];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -59,7 +59,7 @@ void StrategyMemoEntryWidget::initWidget(void) {
|
|||
mainLayout2 = new QFormLayout;
|
||||
speciesSelector = new QComboBox;
|
||||
|
||||
partialInfoCheckBox = new QCheckBox;
|
||||
incompleteInfoCheckBox = new QCheckBox;
|
||||
|
||||
firstTIDFld = new UnsignedSpinbox<16>;
|
||||
firstSIDFld = new UnsignedSpinbox<16>;
|
||||
|
|
@ -79,7 +79,7 @@ void StrategyMemoEntryWidget::initWidget(void) {
|
|||
mainLayout2->addRow(tr("First TID"), firstTIDFld);
|
||||
mainLayout2->addRow(tr("First SID"), firstSIDFld);
|
||||
mainLayout2->addRow(tr("First PID"), PIDLayout);
|
||||
mainLayout2->addRow(tr("Partial information"), partialInfoCheckBox);
|
||||
mainLayout2->addRow(tr("Incomplete information"), incompleteInfoCheckBox);
|
||||
mainLayout->addLayout(mainLayout2);
|
||||
mainLayout->addWidget(generateShinyIDsButton);
|
||||
mainLayout->addWidget(truncateMemoFromHereButton);
|
||||
|
|
@ -104,8 +104,8 @@ void StrategyMemoEntryWidget::parseData(void) {
|
|||
isXD = LIBPKMGC_IS_XD(StrategyMemoEntry, entry);
|
||||
|
||||
generateShinyIDsButton->setVisible(!isXD);
|
||||
partialInfoCheckBox->setChecked(entry->isInfoPartial());
|
||||
partialInfoCheckBox->setDisabled(isXD);
|
||||
incompleteInfoCheckBox->setChecked(entry->isInfoIncomplete());
|
||||
incompleteInfoCheckBox->setDisabled(isXD);
|
||||
|
||||
speciesSelector->setCurrentIndex(pkmSpeciesIndexToNameIndex(entry->species));
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ void StrategyMemoEntryWidget::parseData(void) {
|
|||
}
|
||||
|
||||
void StrategyMemoEntryWidget::saveChanges(void) {
|
||||
entry->setInfoCompleteness(partialInfoCheckBox->isChecked());
|
||||
entry->setInfoCompleteness(incompleteInfoCheckBox->isChecked());
|
||||
entry->species = nameIndexToPkmSpeciesIndex(speciesSelector->currentIndex());
|
||||
entry->firstSID = (u16)firstSIDFld->unsignedValue();
|
||||
entry->firstTID = (u16)firstTIDFld->unsignedValue();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include <Core/DataUI.h>
|
||||
#include <Core/UnsignedSpinbox.h>
|
||||
#include <QLabel>
|
||||
#include <QFormLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QButtonGroup>
|
||||
|
|
@ -61,7 +60,7 @@ private:
|
|||
QFormLayout *mainLayout2;
|
||||
QComboBox *speciesSelector;
|
||||
|
||||
QCheckBox *partialInfoCheckBox;
|
||||
QCheckBox *incompleteInfoCheckBox;
|
||||
|
||||
UnsignedSpinbox<16> *firstTIDFld, *firstSIDFld;
|
||||
QVBoxLayout* PIDLayout;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@
|
|||
#include <QApplication>
|
||||
#include <QDir>
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QEventLoop>
|
||||
#include <QTimer>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
using namespace GCUIs;
|
||||
using namespace XDUIs;
|
||||
using namespace LibPkmGC;
|
||||
|
|
@ -39,12 +45,13 @@ MWCentralWidget::MWCentralWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(p
|
|||
PCButton = new QPushButton;
|
||||
daycareButton = new QPushButton;
|
||||
strategyMemoButton = new QPushButton;
|
||||
ribbonDescriptionsButton = new QPushButton;
|
||||
purifierButton = new QPushButton;
|
||||
|
||||
updateText();
|
||||
QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, purifierButton };
|
||||
QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, ribbonDescriptionsButton, purifierButton };
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
for (int i = 0; i < 7; ++i)
|
||||
mainLayout->addWidget(lst[i]);
|
||||
|
||||
this->setLayout(mainLayout);
|
||||
|
|
@ -53,6 +60,7 @@ MWCentralWidget::MWCentralWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(p
|
|||
connect(PCButton, SIGNAL(clicked()), this, SLOT(openPCUI()));
|
||||
connect(daycareButton, SIGNAL(clicked()), this, SLOT(openDaycareUI()));
|
||||
connect(strategyMemoButton, SIGNAL(clicked()), this, SLOT(openStrategyMemoUI()));
|
||||
connect(ribbonDescriptionsButton, SIGNAL(clicked()), this, SLOT(openRibbonDescriptionsUI()));
|
||||
connect(purifierButton, SIGNAL(clicked()), this, SLOT(openPurifierUI()));
|
||||
|
||||
currentSaveSlotChangeHandler();
|
||||
|
|
@ -64,12 +72,13 @@ void MWCentralWidget::updateText(void) {
|
|||
PCButton->setText(tr("PC"));
|
||||
daycareButton->setText(tr("Daycare"));
|
||||
strategyMemoButton->setText(tr("Strategy memo"));
|
||||
ribbonDescriptionsButton->setText(tr("Ribbon descriptions"));
|
||||
purifierButton->setText(tr("Purifier"));
|
||||
}
|
||||
|
||||
void MWCentralWidget::currentSaveSlotChangeHandler(void) {
|
||||
QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, purifierButton };
|
||||
for (size_t i = 0; i < 6; ++i)
|
||||
QPushButton* lst[] = { gameConfigButton, playerButton, PCButton, daycareButton, strategyMemoButton, ribbonDescriptionsButton, purifierButton };
|
||||
for (size_t i = 0; i < 7; ++i)
|
||||
lst[i]->setDisabled(currentSaveSlot == NULL);
|
||||
purifierButton->setVisible(currentSaveSlot != NULL && LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot));
|
||||
}
|
||||
|
|
@ -86,6 +95,7 @@ GEN_GCUI_SLT(PlayerUI, currentSaveSlot->player)
|
|||
GEN_GCUI_SLT(PCUI, currentSaveSlot->PC)
|
||||
GEN_GCUI_SLT(DaycareUI, currentSaveSlot->daycare)
|
||||
GEN_GCUI_SLT(StrategyMemoUI, currentSaveSlot->strategyMemo)
|
||||
GEN_GCUI_SLT(RibbonDescriptionsUI, currentSaveSlot->ribbonDescriptions);
|
||||
|
||||
void MWCentralWidget::openPurifierUI(void) {
|
||||
if (!LIBPKMGC_IS_XD(SaveEditing::SaveSlot, currentSaveSlot)) return;
|
||||
|
|
@ -94,6 +104,51 @@ void MWCentralWidget::openPurifierUI(void) {
|
|||
}
|
||||
|
||||
|
||||
void MainWindow::checkForUpdates(void) {
|
||||
if (!checkForUpdatesAtStartupAction->isChecked()) return;
|
||||
|
||||
QEventLoop loop;
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
|
||||
QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this);
|
||||
QUrl url("https://api.github.com/repos/TuxSH/PkmGCTools/releases/latest");
|
||||
|
||||
connect(timer, SIGNAL(timeout()), networkAccessManager, SLOT(abort()));
|
||||
connect(timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
||||
connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
|
||||
timer->start(1500);
|
||||
|
||||
QNetworkReply *reply = NULL;
|
||||
reply = networkAccessManager->get(QNetworkRequest(url));
|
||||
loop.exec();
|
||||
if (reply == NULL) return;
|
||||
|
||||
QJsonParseError err;
|
||||
QByteArray result = reply->readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(result, &err);
|
||||
|
||||
if (err.error != QJsonParseError::NoError) return;
|
||||
|
||||
if (doc.isObject()) {
|
||||
QJsonObject obj = doc.object();
|
||||
QJsonValue html_url = obj.value("html_url"), tag_name = obj.value("tag_name");
|
||||
if (html_url.isUndefined() || tag_name.isUndefined()) return;
|
||||
QStringList version_numbers = tag_name.toString().mid(1).split('.');
|
||||
int ver = 0;
|
||||
const int powersOfTen[] = { 1000000, 1000, 1 };
|
||||
for (int i = 0; i < version_numbers.count(); ++i)
|
||||
ver += powersOfTen[i] * (version_numbers[i].toInt() % 1000);
|
||||
|
||||
if (ver > LIBPKMGC_VERSION) {
|
||||
QMessageBox::information(this, tr("New version available"),
|
||||
tr("PkmGCTools (PkmGCSaveEditor) %1 is now available!<br/>"
|
||||
"You can download this new version on <a href='%2'>Github</a>.")
|
||||
.arg(tag_name.toString()).arg(html_url.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::MainWindow() : QMainWindow(), centralWidget(new MWCentralWidget) {
|
||||
this->setWindowTitle(appName);
|
||||
this->setWindowIcon(QIcon(":/PkmGCSaveEditor.ico"));
|
||||
|
|
@ -117,12 +172,16 @@ MainWindow::MainWindow() : QMainWindow(), centralWidget(new MWCentralWidget) {
|
|||
optionsMenu = menuBar()->addMenu(tr("&Options"));
|
||||
interfaceLangSubMenu = optionsMenu->addMenu(tr("&Interface language"));
|
||||
dumpedNamesLangSubMenu = optionsMenu->addMenu(tr("&Dumped names language"));
|
||||
ignoreDataCorruptionAction = new QAction(this);
|
||||
ignoreDataCorruptionAction->setCheckable(true);
|
||||
optionsMenu->addAction(ignoreDataCorruptionAction);
|
||||
bugFixesSubMenu = optionsMenu->addMenu(tr("&Bug fixes"));
|
||||
colosseumBugsAffectingPokemonAction = new QAction(this);
|
||||
bugFixesSubMenu->addAction(colosseumBugsAffectingPokemonAction);
|
||||
ignoreDataCorruptionAction = new QAction(this);
|
||||
ignoreDataCorruptionAction->setCheckable(true);
|
||||
optionsMenu->addAction(ignoreDataCorruptionAction);
|
||||
checkForUpdatesAtStartupAction = new QAction(this);
|
||||
checkForUpdatesAtStartupAction->setCheckable(true);
|
||||
optionsMenu->addAction(checkForUpdatesAtStartupAction);
|
||||
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
|
||||
|
|
@ -153,6 +212,8 @@ MainWindow::MainWindow() : QMainWindow(), centralWidget(new MWCentralWidget) {
|
|||
"(in \"Options\", \"Bug fixes\"). <b>Do it only once and only once</b> (for each concerned save file).</li>"
|
||||
"<li>If you have imported or exported a Pok\xc3\xa9mon in the GBA format, please check its status alteration, its EVs, and its game of origin.</li></ul>"));
|
||||
}
|
||||
checkForUpdates();
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::createDumpedNamesLanguageMenu(void) {
|
||||
|
|
@ -245,6 +306,7 @@ void MainWindow::updateText(void) {
|
|||
bugFixesSubMenu->setTitle(tr("&Bug fixes"));
|
||||
colosseumBugsAffectingPokemonAction->setText(tr("Bugs affecting &Pok\xc3\xa9mon (Colosseum, PkmGCSaveEditor \xe2\x89\xa4 1.1.0)"));
|
||||
ignoreDataCorruptionAction->setText(tr("&Ignore data corruption"));
|
||||
checkForUpdatesAtStartupAction->setText(tr("Check for &updates at startup"));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -493,6 +555,7 @@ void MainWindow::saveSaveFileAs(void) {
|
|||
void MainWindow::loadSettings(void) {
|
||||
settings = new QSettings("PkmGCTools", "PkmGCSaveEditor", this);
|
||||
ignoreDataCorruption = settings->value("IgnoreDataCorruption").toBool();
|
||||
checkForUpdatesAtStartupAction->setChecked(settings->value("CheckForUpdatesAtStartup", true).toBool());
|
||||
interfaceLanguage = settings->value("InterfaceLanguage").toString();
|
||||
dumpedNamesLanguage = (LanguageIndex) settings->value("DumpedNamesLanguage").toInt();
|
||||
|
||||
|
|
@ -515,6 +578,7 @@ void MainWindow::saveSettings(void) {
|
|||
settings->setValue("LibPkmGCVersion", LIBPKMGC_VERSION);
|
||||
|
||||
settings->setValue("IgnoreDataCorruption", ignoreDataCorruption);
|
||||
settings->setValue("CheckForUpdatesAtStartup", checkForUpdatesAtStartupAction->isChecked());
|
||||
settings->setValue("InterfaceLanguage", interfaceLangGroup->checkedAction()->data());
|
||||
if (dumpedNamesLanguage > Spanish) dumpedNamesLanguage = NoLanguage;
|
||||
settings->setValue("DumpedNamesLanguage", dumpedNamesLanguage);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <GCUIs/PCUI.h>
|
||||
#include <GCUIs/DaycareUI.h>
|
||||
#include <GCUIs/StrategyMemoUI.h>
|
||||
#include <GCUIs/RibbonDescriptionsUI.h>
|
||||
#include <XDUIs/PurifierUI.h>
|
||||
#include <QGridLayout>
|
||||
#include <QMainWindow>
|
||||
|
|
@ -32,7 +33,7 @@
|
|||
#include <QSettings>
|
||||
#include <QTranslator>
|
||||
#include <QActionGroup>
|
||||
|
||||
#include <QNetworkReply>
|
||||
class MWCentralWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
@ -47,11 +48,12 @@ public slots:
|
|||
void openPCUI(void);
|
||||
void openDaycareUI(void);
|
||||
void openStrategyMemoUI(void);
|
||||
void openRibbonDescriptionsUI(void);
|
||||
void openPurifierUI(void);
|
||||
|
||||
private:
|
||||
QVBoxLayout *mainLayout;
|
||||
QPushButton *gameConfigButton, *playerButton, *PCButton, *daycareButton, *strategyMemoButton, *purifierButton ;
|
||||
QPushButton *gameConfigButton, *playerButton, *PCButton, *daycareButton, *strategyMemoButton, *ribbonDescriptionsButton, *purifierButton ;
|
||||
};
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
|
|
@ -62,6 +64,8 @@ public:
|
|||
void updateText(void);
|
||||
void updateStatusBar(void);
|
||||
int openSaveChangesPrompt(void);
|
||||
|
||||
void checkForUpdates(void);
|
||||
public slots:
|
||||
void openSaveFile(void);
|
||||
bool saveSaveFile(void);
|
||||
|
|
@ -102,6 +106,9 @@ private:
|
|||
QMenu* bugFixesSubMenu;
|
||||
QAction* colosseumBugsAffectingPokemonAction;
|
||||
QAction* ignoreDataCorruptionAction;
|
||||
QAction* checkForUpdatesAtStartupAction;
|
||||
|
||||
|
||||
QSettings *settings;
|
||||
|
||||
QTranslator translator, translatorQt;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,10 @@
|
|||
#include <QApplication>
|
||||
#include <MainWindow.h>
|
||||
|
||||
using namespace LibPkmGC;
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
||||
MainWindow userInterface;
|
||||
userInterface.show();
|
||||
|
||||
|
|
|
|||
1423
PkmGCSaveEditor/translations/PkmGCSaveEditor_de.ts
Normal file
1423
PkmGCSaveEditor/translations/PkmGCSaveEditor_de.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user