Fixed the CMakeLists.txt's.

Pokémon flags now correctly handled.
Replaced "Generate shiny PID" by "Generate shiny IDs" for consitency (in StrategyMemoWidget).
Fixed some bugs.
This commit is contained in:
Elouan Appéré
2015-08-31 15:15:30 +02:00
parent c586def095
commit 54918e90c5
22 changed files with 205 additions and 118 deletions

13
.gitignore vendored
View File

@@ -34,9 +34,16 @@ CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
# VS Projects
*.sln
*.vcxproj
*.vcxproj.filters
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
@@ -47,6 +54,7 @@ install_manifest.txt
*.userprefs
# Build results
Win32/
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
@@ -275,4 +283,9 @@ Makefile*
*.qmlproject.user
*.qmlproject.user.*
#CMake Automoc
*_automoc.cpp
PkmGCSaveEditor_*.qm
installdir/

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.12)
project(PkmGCTools)
set(CMAKE_INSTALL_PREFIX installdir)
option(BUILD_PKMGCSAVEEDITOR ON)
option(BUILD_PKMGCSAVEEDITOR "Build PkmGCSaveEditor" ON)
add_subdirectory(LibPkmGC)
add_definitions(${LIBPKMGC_DEFINITIONS})

View File

@@ -16,7 +16,7 @@ set(LIBPKMGC_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include
include_directories(${LIBPKMGC_INCLUDE_DIRS})
option(LIBPKMGC_DYN_LIB ON)
option(LIBPKMGC_DYN_LIB "Build LibPkmGC as a shared library" ON)
message("LIBPKMGC_DYN_LIB:\t${LIBPKMGC_DYN_LIB}")

View File

@@ -51,7 +51,7 @@ public:
PokemonSpeciesIndex getWurmpleEvolution(void) const;
char getUnownForm(void) const;
bool isSpecialAbilityDefined(void) const;
bool isSecondAbilityDefined(void) const;
virtual PokemonAbilityIndex getAbility(void) const = 0;
virtual bool isEmptyOrInvalid(void) const;
@@ -78,7 +78,7 @@ public:
// u8 encounterType;
VersionInfo version;
bool specialRibbons[12]; //special ribbons #7 only exists in XD/Col
bool specialRibbons[12];
//u32 statusFlags;

View File

@@ -43,9 +43,7 @@ pkm
0xbd : u8 specialRibbons[12]
0xc9 : u8 unused ?
0xca : u8 pkrsStatus
0xcb : u8 ?
0xcc : u8 abilityUsed
0xcd : u16 ? ?
0xcb : u8 flags[3] : egg, special ability, invalid pkm
0xcf : u8 marks
// shadow pkm data ?
0xd0--0xd7 : ? ?
@@ -68,15 +66,13 @@ public:
Pokemon* clone(void) const;
Pokemon* create(void) const;
bool isEmptyOrInvalid(void) const;
void save(void);
void swap(Pokemon& other);
Pokemon& operator=(Pokemon const& other);
bool hasSpecialAbility(void) const;
void setSpecialAbilityStatus(bool status);
bool specialAbilityStatus;
Pokemon(XD::Pokemon const& other);
Pokemon& operator=(GC::Pokemon const& other);
void swap(GC::Pokemon & other);

View File

@@ -27,6 +27,8 @@
#define LD_ARRAY(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfIntegers<u8*,type*>(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz))
#define LD_ARRAY_E(type,ar,sz,off,etype) SM_H_TMP_NS()::toArrayOfEnumIntegers<type,u8*,etype*>(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz))
#define LD_ARRAY_B(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfBoolIntegers<type,u8*,bool*>(ar, BUFFER_NAME+off, BUFFER_NAME+off+(sizeof(type)*sz))
#define LD_BIT_ARRAY2(type,ar,sz,off,st) type ar##_tmp; LD_FIELD(type, ar##_tmp, off); for(int i__ = 0; i__ < sz; ++i__) ar[i__] = (ar##_tmp & (1U << (8*sizeof(type) - 1 - st - i__))) != 0;
#define LD_BIT_ARRAY(type, ar, sz, off) LD_BIT_ARRAY2(type,ar,sz,off,0)
#define SV_FIELD(type,fld,off) SM_H_TMP_NS()::fromInteger<type, u8*>(BUFFER_NAME+off, fld)
#define SV_FIELD_E(type,fld,off,etype) SM_H_TMP_NS()::fromEnumInteger<type, etype, u8*>(BUFFER_NAME+off, fld)
@@ -34,6 +36,10 @@
#define SV_ARRAY(type,ar,sz,off) SM_H_TMP_NS()::fromArrayOfIntegers<type*, u8*>(BUFFER_NAME+off, ar, ar+sz)
#define SV_ARRAY_E(type,ar,sz,off,etype) SM_H_TMP_NS()::fromArrayOfEnumIntegers<type,etype*, u8*>(BUFFER_NAME+off, ar, ar+sz)
#define SV_ARRAY_B(type,ar,sz,off) SM_H_TMP_NS()::toArrayOfBoolIntegers<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)
#define LD_SUBSTRUCTURE(type, fld, off) fld = new type(data + off)
#define LD_SUBSTRUCTURE_ARRAY(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) LD_SUBSTRUCTURE(type, ar[i__], off+type::size*i__);
@@ -42,7 +48,6 @@
#define SV_SUBSTRUCTURE(type, fld, off) fld->save(); std::copy(fld->data, fld->data + type::size, data + off);
#define SV_SUBSTRUCTURE2(type, fld, off) fld->save(); std::copy(fld->data, fld->data + fld->getSize(), data + off);
#define SV_SUBSTRUCTURE_ARRAY(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE(type, ar[i__], off+type::size*i__); }
//#define SV_SUBSTRUCTURE_ARRAY2(type, ar, sz, off) for(size_t i__ = 0; i__ < sz; ++i__) { SV_SUBSTRUCTURE2(type, ar[i__], off+ar[i__]->getSize()*i__); }

View File

@@ -3,6 +3,11 @@
#include <LibPkmGC/Base/Pokemon.h>
#include <LibPkmGC/GC/Common/PokemonString.h>
#define LIBPKMGC_GC_EGG_FLAG 0
#define LIBPKMGC_GC_SECOND_ABILITY_FLAG 1
#define LIBPKMGC_GC_INVALID_POKEMON_FLAG 2
namespace LibPkmGC {
namespace GC {
class LIBPKMGC_DECL Pokemon :
@@ -15,10 +20,12 @@ public:
virtual void swap(Pokemon& other);
virtual Pokemon& operator=(Pokemon const& other);
virtual bool hasSpecialAbility(void) const = 0;
virtual void setSpecialAbilityStatus(bool status) = 0;
/*bool hasSecondAbility(void) const;
void setSpecialAbilityStatus(bool status);*/
virtual PokemonAbilityIndex getAbility(void) const;
u16 shadowPkmID;
bool pkmFlags[3];
virtual void swap(Base::Pokemon& other);
virtual Pokemon& operator=(Base::Pokemon const& other);

View File

@@ -28,8 +28,9 @@ namespace XD {
bit 7: egg flag
bit 6: special (second) ability flag. Pokémon XD's catchable Pkms have a 50% chance to have their special ability
bit 5: invalidity flag. MUST **NOT** BE SET for the Pokémon to be considered as valid ("not empty")
bit 4: "not traded" flag ??
bit 2: "caught" flag ??
bit 4: "not tradable in game" flag
bit 3: ?
bit 2: "caught" flag
0x1e 0x1f : ??
0x20: u32 experience
0x24: u16 SID
@@ -73,15 +74,11 @@ public:
void swap(Pokemon& other);
Pokemon& operator=(Pokemon const& other);
bool hasSpecialAbility(void) const;
void setSpecialAbilityStatus(bool status);
u8 pkmFlags;
bool isEmptyOrInvalid(void) const;
Pokemon(Colosseum::Pokemon const& other);
Pokemon& operator=(GC::Pokemon const& other);
void swap(GC::Pokemon & other);
bool XDPkmFlags[3];
private:
void loadFields(void);

View File

@@ -136,7 +136,7 @@ bool Pokemon::isEmptyOrInvalid(void) const {
return (species > 0x19e) || (species == 0) || !getSpeciesData(species).isValid || version.isIncomplete();
}
bool Pokemon::isSpecialAbilityDefined(void) const{
bool Pokemon::isSecondAbilityDefined(void) const{
return (getSpeciesData(species).possibleAbilities[1] != NoAbility);
}
void Pokemon::swap(Pokemon& other) {

View File

@@ -12,14 +12,17 @@ Pokemon::Pokemon(void) : GC::Pokemon(0x138) { initWithEmptyData(); }
Pokemon::~Pokemon(void) {
}
Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other), specialAbilityStatus(other.specialAbilityStatus){}
Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other){}
Pokemon* Pokemon::clone(void) const { return new Pokemon(*this); }
Pokemon* Pokemon::create(void) const { return new Pokemon; }
void Pokemon::swap(Pokemon& other) {
GC::Pokemon::swap(other);
SW(specialAbilityStatus);
}
bool Pokemon::isEmptyOrInvalid(void) const {
return GC::Pokemon::isEmptyOrInvalid() && species == Bonsly;
}
void Pokemon::loadFields(void) {
@@ -70,7 +73,7 @@ void Pokemon::loadFields(void) {
LD_ARRAY_B(u8, specialRibbons, 12, 0xbd);
LD_FIELD(u8, pkrsStatus, 0xca);
LD_FIELD_B(u8, specialAbilityStatus, 0xcc);
LD_ARRAY_B(u8, pkmFlags, 3, 0xcb);
LD_FIELD(u8, marksTmp, 0xcf);
@@ -80,9 +83,13 @@ void Pokemon::loadFields(void) {
markings.load(marksTmp);
for (size_t i = 0; i < 4; ++i)
moves[i].load(data + 0x78 + 4 * i);
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
}
void Pokemon::save(void) {
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
SV_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex);
SV_FIELD(u32, PID, 0x04);
version.save(data + 0x08);
@@ -119,7 +126,7 @@ void Pokemon::save(void) {
SV_ARRAY_B(u8, specialRibbons, 12, 0xbd);
SV_FIELD(u8, pkrsStatus, 0xca);
SV_FIELD_B(u8, specialAbilityStatus, 0xcc);
LD_ARRAY_B(u8, pkmFlags, 3, 0xcb);
SV_FIELD(u8, markings.save(), 0xcf);
@@ -134,19 +141,12 @@ void Pokemon::save(void) {
Pokemon& Pokemon::operator=(Pokemon const& other) {
if (this != &other) {
GC::Pokemon::operator=(other);
CP(specialAbilityStatus);
}
return *this;
}
LIBPKMGC_GC_GEN_COL_VTF(Pokemon)
bool Pokemon::hasSpecialAbility(void) const {
return isSpecialAbilityDefined() && specialAbilityStatus;
}
void Pokemon::setSpecialAbilityStatus(bool status) {
specialAbilityStatus = isSpecialAbilityDefined() && status;
}
}
}

View File

@@ -13,23 +13,39 @@ Pokemon::~Pokemon(void)
{
}
Pokemon::Pokemon(Pokemon const& other) : Base::Pokemon(other), shadowPkmID(other.shadowPkmID) {}
void Pokemon::swap(Pokemon& other) { Base::Pokemon::swap(other); SW(shadowPkmID); }
Pokemon::Pokemon(Pokemon const& other) : Base::Pokemon(other), shadowPkmID(other.shadowPkmID) {
CP_ARRAY(pkmFlags, 3);
}
void Pokemon::swap(Pokemon& other) {
Base::Pokemon::swap(other);
SW(shadowPkmID);
SW_ARRAY(pkmFlags, 3);
}
PokemonAbilityIndex Pokemon::getAbility(void) const {
const PokemonSpeciesData dt = getSpeciesData(species);
return (hasSpecialAbility()) ? dt.possibleAbilities[1] : dt.possibleAbilities[0];
return (pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG]) ? dt.possibleAbilities[1] : dt.possibleAbilities[0];
}
Pokemon& Pokemon::operator=(Pokemon const& other) {
if (this != &other) {
Base::Pokemon::operator=(other);
CP(shadowPkmID);
CP_ARRAY(pkmFlags, 3);
}
return *this;
}
/*
bool Pokemon::hasSecondAbility(void) const {
return isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
}
void Pokemon::setSpecialAbilityStatus(bool status) {
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = status;
}*/
void Pokemon::swap(Base::Pokemon & other) {
return swap((Pokemon&)other);
}

View File

@@ -1,8 +1,8 @@
#include <LibPkmGC/XD/Common/Pokemon.h>
#define EGG_FLAG 0x80
#define SPECIAL_ABILITY_FLAG 0x40
#define INVALID_PKM_FLAG 0x20
#define LIBPKMGC_XD_NOT_TRADABLE_IN_GAME_FLAG 0
#define LIBPKMGC_XD_UNKNOWN_FLAG 1
#define LIBPKMGC_XD_CAUGHT_FLAG 2
namespace LibPkmGC {
namespace XD {
@@ -16,26 +16,27 @@ Pokemon::Pokemon(void) : GC::Pokemon(0xc4) { initWithEmptyData(); }
Pokemon::~Pokemon(void) {
}
Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other), pkmFlags(other.pkmFlags) {}
Pokemon::Pokemon(Pokemon const& other) : GC::Pokemon(other) {
CP_ARRAY(XDPkmFlags, 3);
}
Pokemon* Pokemon::clone(void) const { return new Pokemon(*this); }
Pokemon* Pokemon::create(void) const { return new Pokemon; }
void Pokemon::swap(Pokemon& other) {
GC::Pokemon::swap(other);
SW(pkmFlags);
}
Pokemon& Pokemon::operator=(Pokemon const& other) {
if (this != &other) {
GC::Pokemon::operator=(other);
CP(pkmFlags);
CP_ARRAY(XDPkmFlags, 3);
}
return *this;
}
void Pokemon::loadFields(void) {
u8 marksTmp = 0;
u16 specialRibbonsTmp = 0;
LD_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex);
LD_FIELD_E(u16, heldItem, 0x02, ItemIndex);
LD_FIELD(u16, partyData.currentHP, 0x04);
@@ -60,7 +61,8 @@ void Pokemon::loadFields(void) {
LD_FIELD_E(u8, partyData.status, 0x16, PokemonStatus);
partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status;
LD_FIELD(u8, pkmFlags, 0x1d);
LD_BIT_ARRAY(u8, pkmFlags, 3, 0x1d);
LD_BIT_ARRAY2(u8, XDPkmFlags, 3, 0x1d, 3);
LD_FIELD(u32, experience, 0x20);
LD_FIELD(u16, SID, 0x24);
LD_FIELD(u16, TID, 0x26);
@@ -69,9 +71,7 @@ void Pokemon::loadFields(void) {
OTName = new GC::PokemonString(data + 0x38, 10);
name = new GC::PokemonString(data + 0x4e, 10);
LD_FIELD(u16, specialRibbonsTmp, 0x7c);
LD_BIT_ARRAY(u16, specialRibbons, 12, 0x7c);
LD_ARRAY(u16, partyData.stats, 6, 0x90);
u16 EVs_tmp[6]; // EVs are internally stored as u16
@@ -92,21 +92,11 @@ void Pokemon::loadFields(void) {
for (size_t i = 0; i < 4; ++i)
moves[i].load(data + 0x80 + 4 * i);
specialRibbonsTmp >>= 4;
for (size_t i = 0; i < 12; ++i) {
specialRibbons[11 - i] = (specialRibbonsTmp & 1) != 0;
specialRibbonsTmp >>= 1;
}
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
}
void Pokemon::save(void) {
u16 specialRibbonsTmp = 0;
for (size_t i = 0; i < 12; ++i) {
specialRibbonsTmp <<= 1;
specialRibbonsTmp |= (specialRibbons[i]) ? 1 : 0;
}
specialRibbonsTmp <<= 4;
pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = isSecondAbilityDefined() && pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG];
SV_FIELD_E(u16, species, 0x00, PokemonSpeciesIndex);
SV_FIELD_E(u16, heldItem, 0x02, ItemIndex);
@@ -125,7 +115,9 @@ void Pokemon::save(void) {
partyData.status = (partyData.status != NoStatus && partyData.status < Poisoned && partyData.status > Asleep) ? NoStatus : partyData.status;
SV_FIELD_E(u8, partyData.status, 0x16, PokemonStatus);
SV_FIELD(u8, pkmFlags, 0x1d);
SV_BIT_ARRAY(u8, pkmFlags, 3, 0x1d);
SV_BIT_ARRAY2(u8, XDPkmFlags, 3, 0x1d, 3);
SV_FIELD(u32, experience, 0x20);
SV_FIELD(u16, SID, 0x24);
SV_FIELD(u16, TID, 0x26);
@@ -135,7 +127,7 @@ void Pokemon::save(void) {
name->save(data + 0x4e, 10);
name->save(data + 0x64, 10);
SV_FIELD(u16, specialRibbonsTmp, 0x7c);
SV_BIT_ARRAY(u16, specialRibbons, 12, 0x7c);
SV_ARRAY(u16, partyData.stats, 6, 0x90);
u16 EVs_tmp[6]; for (size_t i = 0; i < 6; ++i) EVs_tmp[i] = (u16)EVs[i];
@@ -156,19 +148,6 @@ void Pokemon::save(void) {
}
bool Pokemon::isEmptyOrInvalid(void) const {
return GC::Pokemon::isEmptyOrInvalid() || (pkmFlags & INVALID_PKM_FLAG) != 0;
}
bool Pokemon::hasSpecialAbility(void) const{
return isSpecialAbilityDefined() && ((pkmFlags & SPECIAL_ABILITY_FLAG) != 0);
}
void Pokemon::setSpecialAbilityStatus(bool status) {
status = isSpecialAbilityDefined() && status;
pkmFlags &= ~SPECIAL_ABILITY_FLAG; // reset bit 5
pkmFlags |= (status) ? SPECIAL_ABILITY_FLAG : 0;
}
LIBPKMGC_GC_GEN_XD_VTF(Pokemon)
}
}

View File

@@ -6,8 +6,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets)
find_package(Qt5LinguistTools OPTIONAL)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5LinguistTools)
file(GLOB_RECURSE source_files src/*)
@@ -28,14 +28,14 @@ if(Qt5LinguistTools_FOUND)
list(APPEND QT5_TRANSLATION_QM ${QT5_QM_DIR}/qt_${language}.qm)
elseif(EXISTS translations/qt/qt_${language}.qm)
list(APPEND QT5_TRANSLATION_QM translations/qt/qt_${language}.qm)
endif()
endif(EXISTS ${QT5_QM_DIR}/qt_${language}.qm)
if(EXISTS ${QT5_QM_DIR}/qtbase_${language}.qm)
list(APPEND QT5_TRANSLATION_QM ${QT5_QM_DIR}/qtbase_${language}.qm) # Required for Qt > 5.3
elseif(EXISTS translations/qt/qtbase_${language}.qm)
list(APPEND QT5_TRANSLATION_QM translations/qt/qtbase_${language}.qm)
endif()
endforeach()
endif(EXISTS ${QT5_QM_DIR}/qtbase_${language}.qm)
endforeach(language)
list(REMOVE_DUPLICATES QT5_TRANSLATION_QM)
set(QT5_TRANSLATION_QM ${QT5_TRANSLATION_QM} CACHE INTERNAL "Qt5 *.qm")
@@ -48,7 +48,9 @@ if(Qt5LinguistTools_FOUND)
install(FILES ${TRANSLATION_QM} DESTINATION Debug/bin/languages CONFIGURATIONS Debug)
install(FILES ${TRANSLATION_QM} DESTINATION Release/bin/languages CONFIGURATIONS Release RelWithDebInfo MinSizeRel)
endif()
else(Qt5LinguistTools_FOUND)
message("Qt5LinguistTools was NOT found. The translation files will not be able to be updated.")
endif(Qt5LinguistTools_FOUND)
# DLL hell

View File

@@ -23,6 +23,9 @@ QFormLayout(){
this->addRow(tr("Name"), nameFld);
this->addRow(tr("TID/SID"), TIDSIDLayout);
set(inName, inSID, inTID, inGender);
connect(TIDFld, SIGNAL(valueChanged(int)), this, SLOT(TIDorSIDChangedEmitter()));
connect(SIDFld, SIGNAL(valueChanged(int)), this, SLOT(TIDorSIDChangedEmitter()));
emit TIDorSIDChanged();
}
void TrainerInfoLayout::trainerName(LibPkmGC::Base::PokemonString * outName) {
@@ -65,6 +68,6 @@ void TrainerInfoLayout::set(LibPkmGC::Base::PokemonString * inName, LibPkmGC::u1
setTrainerGender(inGender);
}
void TrainerInfoLayout::TIDorSIDChangedEmmiter(void) {
void TrainerInfoLayout::TIDorSIDChangedEmitter(void) {
emit TIDorSIDChanged();
}

View File

@@ -31,7 +31,7 @@ signals:
void TIDorSIDChanged(void);
public slots:
void TIDorSIDChangedEmmiter(void);
void TIDorSIDChangedEmitter(void);
private:
QHBoxLayout* genderLayout;
QButtonGroup* genderButtonGroup;

View File

@@ -74,16 +74,16 @@ void PokemonDisplayWidget::updatePkmNameAndSummary(void) {
nameFld->setText(pkm->name->toUTF8());
s = "(";
if (!getSpeciesData(pkm->species).isValid) {
if (!getSpeciesData(pkm->species).isValid || (pkm->species == Bonsly && !LIBPKMGC_IS_XD(Pokemon,pkm))) {
tt = tr("Invalid species");
}
if (pkm->version.isIncomplete()) {
if (!tt.isEmpty()) tt += "\n";
tt = tr("Invalid version info");
}
if (LIBPKMGC_IS_XD(Pokemon, pkm) && (static_cast<XD::Pokemon*>(pkm)->pkmFlags & 0x20) != 0) {
if (pkm->pkmFlags[LIBPKMGC_GC_INVALID_POKEMON_FLAG]) {
if (!tt.isEmpty()) tt += "\n";
tt += tr("Bit 5 set on byte at offset 0x1d");
tt += tr("\"Invalid Pok\xc3\xa9mon\" flag set");
}
summary->setToolTip(tt);

View File

@@ -4,9 +4,6 @@
using namespace LibPkmGC; using namespace Localization; using namespace Base;
static QString s1[] = QT_TRANSLATE_NOOP3("GCUIs::PokemonUI", "None", "Status");
namespace GCUIs {
PokemonMoveLayout::PokemonMoveLayout(PokemonMove const& inMove) : QHBoxLayout(){
@@ -138,6 +135,11 @@ void PokemonUI::initWidget(void){
happinessFld = new UnsignedSpinbox<8>;
pkrsStatusFld = new UnsignedSpinbox<8>;
statusFld = new QComboBox;
flagsLayout = new QGridLayout;
flagsButtonGroup = new QButtonGroup;
markingsLayout = new QHBoxLayout;
markingsButtonGroup = new QButtonGroup;
statusFld->addItems(statusNames());
for (size_t i = 0; i < 387; ++i)
@@ -159,16 +161,33 @@ void PokemonUI::initWidget(void){
levelAndSyncLayout->setAlignment(Qt::AlignRight);
experienceLevelAndSyncLayout->addLayout(levelAndSyncLayout);
markingsLayout = new QHBoxLayout;
markingsButtonGroup = new QButtonGroup;
eggFlagCheckBox = new QCheckBox(tr("Egg")); secondAbilityFlagCheckBox = new QCheckBox(tr("Second ability"));
invalidPokemonCheckBox = new QCheckBox(tr("Invalid Pok\xc3\xa9mon"));
notTradableInGameFlagCheckBox = new QCheckBox(tr("Not tradable in-game")); unknownFlagCheckBox = new QCheckBox(tr("Unknown"));
caughtFlagCheckBox = new QCheckBox(tr("Caught"));
QCheckBox* g1[] = { eggFlagCheckBox, secondAbilityFlagCheckBox, invalidPokemonCheckBox,
notTradableInGameFlagCheckBox, unknownFlagCheckBox, caughtFlagCheckBox };
flagsButtonGroup->setExclusive(false);
for (int i = 0; i < 6; ++i) {
flagsButtonGroup->addButton(g1[i], i);
flagsLayout->addWidget(g1[i], i / 3, i % 3);
connect(g1[i], SIGNAL(stateChanged(int)), this, SLOT(flagsStateChangeHandler()));
}
circleMarkingCheckBox = new QCheckBox("\xe2\x97\x8f"); squareMarkingCheckBox = new QCheckBox("\xe2\x96\xa0");
triangleMarkingCheckBox = new QCheckBox("\xe2\x96\xb2"); heartMarkingCheckBox = new QCheckBox("\xe2\x99\xa5");
QCheckBox* g2[] = { circleMarkingCheckBox, squareMarkingCheckBox, triangleMarkingCheckBox, heartMarkingCheckBox };
markingsButtonGroup->setExclusive(false);
markingsButtonGroup->addButton(circleMarkingCheckBox); markingsButtonGroup->addButton(squareMarkingCheckBox);
markingsButtonGroup->addButton(triangleMarkingCheckBox); markingsButtonGroup->addButton(heartMarkingCheckBox);
markingsLayout->addWidget(circleMarkingCheckBox); markingsLayout->addWidget(squareMarkingCheckBox);
markingsLayout->addWidget(triangleMarkingCheckBox); markingsLayout->addWidget(heartMarkingCheckBox);
for (int i = 0; i < 4; ++i) {
markingsButtonGroup->addButton(g2[i], i);
markingsLayout->addWidget(g2[i]);
}
generalTabLayout->addRow(tr("Species"), speciesFld);
generalTabLayout->addRow(tr("Name or nickname"), nameLayout);
@@ -180,6 +199,7 @@ void PokemonUI::initWidget(void){
generalTabLayout->addRow(tr("Happiness"), happinessFld);
generalTabLayout->addRow(tr("Pok\xc3\xa9rus"), pkrsStatusFld);
generalTabLayout->addRow(tr("Status"), statusFld);
generalTabLayout->addRow(tr("Flags"), flagsLayout);
generalTabLayout->addRow(tr("Markings"), markingsLayout);
@@ -245,7 +265,6 @@ void PokemonUI::initWidget(void){
mainStatsFormLayout->addRow(statNames[i], mainStatsFlds[i]);
connect(mainStatsFlds[i], SIGNAL(IVOrEVChanged()), this, SLOT(updateMainStats()));
}
autoUpdateMainStatsCheckBox = new QCheckBox(tr("Update stats automatically"));
autoUpdateMainStatsCheckBox->setChecked(true);
@@ -341,6 +360,7 @@ void PokemonUI::initWidget(void){
connect(speciesFld, SIGNAL(currentIndexChanged(int)), this, SLOT(speciesChangeHandler()));
connect(resetNameButton, SIGNAL(clicked()), this, SLOT(resetName()));
connect(PIDFld, SIGNAL(valueChanged(int)), this, SLOT(PIDChangeHandler()));
connect(abilityFld, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFlags()));
connect(experienceFld, SIGNAL(valueChanged(int)), this, SLOT(updateLevelFromExperience()));
connect(levelFld, SIGNAL(valueChanged(int)), this, SLOT(updateExperienceFromLevel()));
connect(OTField, SIGNAL(TIDorSIDChanged()), this, SLOT(updatePkmAttributes()));
@@ -374,6 +394,7 @@ void PokemonUI::parseData(void){
nameFld->setText(pkm->name->toUTF8());
speciesFld->setCurrentIndex((int)Localization::pkmSpeciesIndexToNameIndex(pkm->species));
if (pkm->species == Bonsly && !isXD) speciesFld->setCurrentIndex(0);
PIDFld->setUnsignedValue(pkm->PID);
@@ -389,6 +410,16 @@ void PokemonUI::parseData(void){
pkrsStatusFld->setUnsignedValue(pkm->pkrsStatus);
statusFld->setCurrentIndex((pkm->partyData.status == NoStatus) ? 0 : (int)pkm->partyData.status - 2);
QCheckBox* g1[] = { eggFlagCheckBox, secondAbilityFlagCheckBox, invalidPokemonCheckBox,
notTradableInGameFlagCheckBox, unknownFlagCheckBox, caughtFlagCheckBox };
for (size_t i = 0; i < 3; ++i) {
g1[i]->setChecked(pkm->pkmFlags[i]);
g1[3 + i]->setVisible(isXD);
if (isXD)
g1[3 + i]->setChecked(static_cast<XD::Pokemon*>(pkm)->XDPkmFlags[i]);
}
circleMarkingCheckBox->setChecked(pkm->markings.circle);
squareMarkingCheckBox->setChecked(pkm->markings.square);
triangleMarkingCheckBox->setChecked(pkm->markings.triangle);
@@ -402,7 +433,7 @@ void PokemonUI::parseData(void){
versionFld->setInfo(pkm->version);
connect(versionFld, SIGNAL(versionChanged()), this, SLOT(versionChangeHandler()));
currentHPFld->setUnsignedValue(pkm->partyData.currentHP);
for (size_t i = 0; i < 6; ++i) {
PokemonStatLayout* l = mainStatsFlds[i];
l->IVFld->setUnsignedValue(pkm->IVs[i]);
@@ -422,7 +453,7 @@ void PokemonUI::parseData(void){
autoUpdateMainStatsCheckBox->setChecked(true);
versionChangeHandler();
abilityFld->setCurrentIndex(pkm->hasSpecialAbility());
abilityFld->setCurrentIndex((pkm->pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG]) ? 1 : 0);
}
@@ -431,7 +462,7 @@ void PokemonUI::saveChanges(void){
pkm->name->fromUTF8(nameFld->text().toUtf8().data());
pkm->PID = PIDFld->unsignedValue();
pkm->setSpecialAbilityStatus(abilityFld->currentIndex() != 0);
pkm->pkmFlags[LIBPKMGC_GC_SECOND_ABILITY_FLAG] = (abilityFld->currentIndex() != 0);
pkm->experience = experienceFld->unsignedValue();
pkm->partyData.level = (u8)levelFld->unsignedValue();
@@ -440,6 +471,15 @@ void PokemonUI::saveChanges(void){
pkm->pkrsStatus = (u8)pkrsStatusFld->unsignedValue();
pkm->partyData.status = (statusFld->currentIndex() == 0) ? NoStatus : (PokemonStatus)(2 + statusFld->currentIndex());
QCheckBox* g1[] = { eggFlagCheckBox, secondAbilityFlagCheckBox, invalidPokemonCheckBox,
notTradableInGameFlagCheckBox, unknownFlagCheckBox, caughtFlagCheckBox };
for (size_t i = 0; i < 3; ++i) {
pkm->pkmFlags[i] = g1[i]->isChecked();
if (isXD)
static_cast<XD::Pokemon*>(pkm)->XDPkmFlags[i] = g1[3 + i]->isChecked();
}
pkm->markings.circle = circleMarkingCheckBox->isChecked();
pkm->markings.square = squareMarkingCheckBox->isChecked();
pkm->markings.triangle = triangleMarkingCheckBox->isChecked();
@@ -455,6 +495,7 @@ void PokemonUI::saveChanges(void){
pkm->version = versionFld->info();
pkm->partyData.currentHP = currentHPFld->unsignedValue();
for (size_t i = 0; i < 6; ++i) {
PokemonStatLayout* l = mainStatsFlds[i];
pkm->IVs[i] = (u8)l->IVFld->unsignedValue();
@@ -484,9 +525,9 @@ QString PokemonUI::getShortPkmAttributeText(LibPkmGC::PokemonSpeciesIndex specie
else if (Base::Pokemon::getGender(species, PID) == Female)
ret += "<span style='color:magenta;'>\xe2\x99\x80</span>";
else {
if (!ret.isEmpty()) ret += ", ";
if (!ret.isEmpty()) ret += ",";
ret += "<span style='color:green;'>";
ret += " <span style='color:green;'>";
ret += tr("Genderless");
ret += "</span>";
}
@@ -521,7 +562,7 @@ QString PokemonUI::getShortPkmAttributeText(void){
if (versionFld->info().isIncomplete())
tt = tr("Invalid version info");
if (isXD && (static_cast<XD::Pokemon*>(pkm)->pkmFlags & 0x20) != 0) {
if (isXD && invalidPokemonCheckBox->isChecked()) {
if (!tt.isEmpty()) tt += "\n";
tt += tr("Bit 5 set on byte at offset 0x1d");
}
@@ -545,7 +586,7 @@ QString PokemonUI::getLongPkmAttributeText(void){
if (versionFld->info().isIncomplete())
tt = tr("Invalid version info");
if (isXD && (static_cast<XD::Pokemon*>(pkm)->pkmFlags & 0x20) != 0) {
if (isXD && invalidPokemonCheckBox->isChecked()) {
if (!tt.isEmpty()) tt += "\n";
tt += tr("Bit 5 set on byte at offset 0x1d");
}
@@ -571,9 +612,10 @@ void PokemonUI::updateMainStats(void) {
PokemonNatureIndex natureIndex = (PokemonNatureIndex)((u32)PIDFld->value() % 25);
u16 stat = Base::Pokemon::calculateStat(i, id, natureIndex,
(u8) levelFld->value(), (u8) l->IVFld->value(), (u8) l->EVFld->value());
l->statFld->setValue((int)stat);
l->statFld->setUnsignedValue(stat);
}
currentHPFld->setValue(mainStatsFlds[0]->statFld->value());
//currentHPFld->setUnsignedMaximum(mainStatsFlds[0]->statFld->value());
currentHPFld->setUnsignedValue(mainStatsFlds[0]->statFld->value());
}
}
@@ -585,18 +627,25 @@ void PokemonUI::updateAbilityList(void) {
LanguageIndex lg = generateDumpedNamesLanguage();
PokemonSpeciesIndex id = Localization::nameIndexToPkmSpeciesIndex((size_t)speciesFld->currentIndex());
const PokemonAbilityIndex* ab = getSpeciesData(id).possibleAbilities;
bool sec = abilityFld->currentIndex() == 1;
disconnect(abilityFld, SIGNAL(currentIndexChanged(int)));
disconnect(secondAbilityFlagCheckBox, SIGNAL(stateChanged(int)));
abilityFld->clear();
abilityFld->addItem(Localization::getPokemonAbilityName(lg, ab[0]));
if (ab[1] != NoAbility) {
abilityFld->addItem(Localization::getPokemonAbilityName(lg, ab[1]));
abilityFld->setDisabled(false);
return;
abilityFld->setCurrentIndex((sec) ? 1 : 0);
}
else {
abilityFld->setDisabled(true);
return;
}
updateFlags();
connect(abilityFld, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFlags()));
connect(secondAbilityFlagCheckBox, SIGNAL(stateChanged(int)), this, SLOT(flagsStateChangeHandler()));
}
@@ -636,6 +685,16 @@ void PokemonUI::PIDChangeHandler(void) {
updateMainStats();
}
void PokemonUI::updateFlags(void) {
secondAbilityFlagCheckBox->setDisabled(abilityFld->count() == 1);
secondAbilityFlagCheckBox->setChecked(abilityFld->currentIndex() == 1);
}
void PokemonUI::flagsStateChangeHandler(void) {
abilityFld->setCurrentIndex((secondAbilityFlagCheckBox->isChecked() && abilityFld->count() == 2) ? 1 : 0);
updatePkmAttributes();
}
void PokemonUI::autoUpdateStatsStateChangeHanler(void) {
bool checked = autoUpdateMainStatsCheckBox->isChecked();
if (checked) updateMainStats();

View File

@@ -109,6 +109,11 @@ private:
QComboBox* statusFld;
QGridLayout *flagsLayout;
QButtonGroup *flagsButtonGroup;
QCheckBox *eggFlagCheckBox, *secondAbilityFlagCheckBox, *invalidPokemonCheckBox;
QCheckBox *notTradableInGameFlagCheckBox, *unknownFlagCheckBox, *caughtFlagCheckBox;
QHBoxLayout* markingsLayout;
QButtonGroup* markingsButtonGroup;
QCheckBox *circleMarkingCheckBox, *squareMarkingCheckBox, *triangleMarkingCheckBox, *heartMarkingCheckBox;
@@ -174,6 +179,10 @@ public slots:
void updateLevelFromExperience(void);
void speciesChangeHandler(void);
void PIDChangeHandler(void);
void updateFlags(void);
void flagsStateChangeHandler(void);
void autoUpdateStatsStateChangeHanler(void);
void versionChangeHandler(void);

View File

@@ -24,11 +24,10 @@ void StrategyMemoEntryWidget::updatePIDText(void) {
}
}
void StrategyMemoEntryWidget::generateShinyPID(void) {
void StrategyMemoEntryWidget::generateShinyIDs(void) {
u32 PID = firstPIDFld->unsignedValue();
PID &= 0xffff0000;
PID |= (PID >> 16) ^ firstSIDFld->unsignedValue() ^ firstTIDFld->unsignedValue();
firstPIDFld->setUnsignedValue(PID);
firstTIDFld->setUnsignedValue(PID >> 16);
firstSIDFld->setUnsignedValue(PID & 0xffff);
}
void StrategyMemoEntryWidget::initWidget(void) {
@@ -44,7 +43,7 @@ void StrategyMemoEntryWidget::initWidget(void) {
PIDLayout = new QVBoxLayout;
firstPIDFld = new UnsignedSpinbox<32>;
PIDText = new QLabel;
generateShinyPIDButton = new QPushButton(tr("Generate shiny PID"));
generateShinyIDsButton = new QPushButton(tr("Generate shiny IDs"));
for (size_t i = 0; i <= 386; ++i)
speciesSelector->addItem(getPokemonSpeciesNameByPkdxIndex(lg, (u16)i));
@@ -58,7 +57,7 @@ void StrategyMemoEntryWidget::initWidget(void) {
mainLayout2->addRow(tr("First PID"), PIDLayout);
mainLayout2->addRow(tr("Partial information"), partialInfoCheckBox);
mainLayout->addLayout(mainLayout2);
mainLayout->addWidget(generateShinyPIDButton);
mainLayout->addWidget(generateShinyIDsButton);
mainLayout2->setHorizontalSpacing(20);
this->setLayout(mainLayout);
@@ -66,7 +65,9 @@ void StrategyMemoEntryWidget::initWidget(void) {
connect(speciesSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(speciesChangeHandler(int)));
connect(firstPIDFld, SIGNAL(valueChanged(int)), this, SLOT(updatePIDText()));
connect(generateShinyPIDButton, SIGNAL(clicked()), this, SLOT(generateShinyPID()));
connect(firstTIDFld, SIGNAL(valueChanged(int)), this, SLOT(updatePIDText()));
connect(firstSIDFld, SIGNAL(valueChanged(int)), this, SLOT(updatePIDText()));
connect(generateShinyIDsButton, SIGNAL(clicked()), this, SLOT(generateShinyIDs()));
}
StrategyMemoEntryWidget::~StrategyMemoEntryWidget(void) {
@@ -76,7 +77,7 @@ void StrategyMemoEntryWidget::parseData(void) {
if (entry == NULL) return;
isXD = LIBPKMGC_IS_XD(StrategyMemoEntry, entry);
generateShinyPIDButton->setVisible(!isXD);
generateShinyIDsButton->setVisible(!isXD);
partialInfoCheckBox->setChecked(entry->isInfoPartial());
partialInfoCheckBox->setDisabled(isXD);
@@ -98,7 +99,7 @@ void StrategyMemoEntryWidget::saveChanges(void) {
void StrategyMemoEntryWidget::speciesChangeHandler(int nameIndex) {
generateShinyPIDButton->setDisabled(nameIndex == 0);
generateShinyIDsButton->setDisabled(nameIndex == 0);
updatePIDText();
emit speciesChanged(entryIndex, nameIndex);
}

View File

@@ -32,7 +32,7 @@ signals:
public slots:
void speciesChangeHandler(int nameIndex);
void updatePIDText(void);
void generateShinyPID(void);
void generateShinyIDs(void);
protected:
void initWidget(void);
@@ -48,7 +48,7 @@ private:
QVBoxLayout* PIDLayout;
UnsignedSpinbox<32> *firstPIDFld;
QLabel* PIDText;
QPushButton* generateShinyPIDButton;
QPushButton* generateShinyIDsButton;
};

Binary file not shown.

Binary file not shown.