Replace the PCCS code with a git submodule

This eliminates duplicate code. - Only maintain the code in one place!

To make sure the submodule is getting cloned too after cloning Poke_Transporter_GB, execute:
git submodule update --init --recursive

To update the submodule to a newer commit/different branch:

cd PCCS
git pull
git checkout <commit_or_branchname>
cd ..
git add PCCS
git commit
git push

The way it works is that a specific commit is tied to your Poke_Transporter_GB repository's PCCS folder.
This commit is contained in:
Philippe Symons 2025-11-27 23:14:29 +01:00
parent 2b682b185f
commit a7b2703bf8
21 changed files with 8 additions and 8576 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "PCCS"]
path = PCCS
url = git@github.com:GearsProgress/Pokemon-Community-Conversion-Standard.git

View File

@ -30,8 +30,8 @@ LIBTONC := $(DEVKITPRO)/libtonc
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))_mb
BUILD := build
SOURCES := source source/pccs
INCLUDES := include include/pccs
SOURCES := source PCCS/lib/source
INCLUDES := include PCCS/lib/include
DATA := data
MUSIC := audio
GRAPHICS := graphics

1
PCCS Submodule

@ -0,0 +1 @@
Subproject commit 289ded81568b847da1702c565ef6296e7d5e1abf

View File

@ -1,152 +0,0 @@
#ifndef GBPOKEMON_H
#define GBPOKEMON_H
#include "Pokemon.h"
#include "Gen3Pokemon.h"
class GBPokemon : public Pokemon // The class for gen 1 and 2 Pokemon, since they share some conversion functions
{
protected:
GBPokemon();
void updateValidity();
// These store the data bytes
byte nicknameArray[11];
byte OTArray[11];
byte externalIndexNumber;
Language lang = (Language)0;
static const DataVarInfo
// All of the data info variables
speciesIndexNumber[2],
level[2],
moveOne[2], moveTwo[2], moveThree[2], moveFour[2],
trainerID[2],
expPoints[2],
hpStatExp[2], atkStatExp[2], defStatExp[2], speStatExp[2], spcStatExp[2],
atkDV[2], defDV[2], speDV[2], spcDV[2],
ppUpNumMoveOne[2], ppUpNumMoveTwo[2], ppUpNumMoveThree[2], ppUpNumMoveFour[2],
ppNumTotalMoveOne[2], ppNumTotalMoveTwo[2], ppNumTotalMoveThree[2], ppNumTotalMoveFour[2];
static const DataVarInfo
// and the convenient arrays of some of the variable groups:
*moves[4],
*statExps[5],
*DVs[5],
*PPUpNums[4],
*PPUpTotals[4];
// This is used to easily print out a Pokemon, when using a standard C++ terminal
#if ON_GBA
#else
std::string parentPrint();
#endif
public:
virtual void loadData(Language nLang, byte nDataArray[], byte nNicknameArray[], byte nOTArray[], byte nExternalIndexNum);
// All of the simple getters and setters are defined here
u32 getLevel() { return getVar(level[generation - 1]); }
u32 getTrainerID() { return getVar(trainerID[generation - 1]); }
u32 getExpPoints() { return getVar(expPoints[generation - 1]); }
bool setLevel(byte newVal) { return setVar(level[generation - 1], newVal); }
bool setOriginalTrainerID(byte newVal) { return setVar(trainerID[generation - 1], newVal); }
bool setExpPoints(u32 newVal) { return setVar(expPoints[generation - 1], newVal); }
// The ones that access arrays are defined here:
u32 getMove(int moveIndex) { return getVar(moves[moveIndex][generation - 1]); }
u32 getStatExp(Stat currStat) { return getVar(statExps[currStat][generation - 1]); }
u32 getPPUpNum(int moveIndex) { return getVar(PPUpNums[moveIndex][generation - 1]); }
u32 getPPTotal(int moveIndex) { return getVar(PPUpTotals[moveIndex][generation - 1]); }
bool setMove(int moveIndex, byte newVal) { return setVar(moves[moveIndex][generation - 1], newVal); }
bool setStatExp(Stat currStat, byte newVal) { return setVar(statExps[currStat][generation - 1], newVal); }
bool setPPUpNum(int moveIndex, byte newVal) { return setVar(PPUpNums[moveIndex][generation - 1], newVal); }
bool setPPTotal(int moveIndex, byte newVal) { return setVar(PPUpTotals[moveIndex][generation - 1], newVal); }
// These are all replaced in the child classes, but give a default value or do nothing here
// ---- Gen 1
virtual u32 getSpeciesIndexNumber() { return getVar(*speciesIndexNumber); }
virtual u32 getCurrentHP() { return 0; }
virtual u32 getStatusCondition() { return 0; }
virtual u32 getCatchRate() { return 0; }
virtual u32 getType(int typeIndex) { return NORMAL; }
virtual bool setSpeciesIndexNumber(byte newVal) { return setVar(*speciesIndexNumber, newVal); }
virtual bool setCurrentHP(byte newVal) { return false; }
virtual bool setStatusCondition(byte newVal) { return false; }
virtual bool setCatchRate(byte newVal) { return false; }
virtual bool setType(int typeIndex, Gen1Types newVal) { return false; }
// ---- Gen 2
virtual u32 getHeldItem() { return 0; } // no item
virtual u32 getFriendship() { return 70; } // default friendship - make this different for Pikachu in Yellow???
virtual u32 getPokerusStrain() { return 0; }
virtual u32 getPokerusDaysRemaining() { return 0; }
virtual u32 getCaughtDataTime() { return 0; }
virtual u32 getCaughtDataLevel() { return 0; }
virtual u32 getCaughtDataGender() { return 0; }
virtual u32 getCaughtDataLocation() { return 0; }
virtual bool setHeldItem(byte newVal) { return false; } // This could *technically* be seen as setting the catch rate but...
virtual bool setFriendship(byte newVal) { return false; }
virtual bool setPokerusStrain(byte newVal) { return false; }
virtual bool setPokerusDaysRemaining(byte newVal) { return false; }
virtual bool setCaughtDataTime(byte newVal) { return false; }
virtual bool setCaughtDataLevel(byte newVal) { return false; }
virtual bool setCaughtDataGender(byte newVal) { return false; }
virtual bool setCaughtDataLocation(byte newVal) { return false; }
// These all have special implementations
u32 getDV(Stat currStat);
bool setDV(Stat currStat, byte newVal);
// These is virtual so it can be overwitten in Gen 1
// These aren't direct variables, but they're useful to have
Language getLanguage() { return lang; };
byte getUnownLetter();
Gender getGender();
Nature getVirtualConsoleNature();
bool getIsShiny();
bool externalConvertNickname(byte outputArray[]);
// And this is for all the conversion stuff
bool convertToGen3(Gen3Pokemon *newPkmn, bool sanitizeMythicals);
bool loadEvent(Gen3Pokemon *newPkmn);
bool generatePersonalityValue(Gen3Pokemon *newPkmn, RNGMethod rng);
bool convertTrainerID(Gen3Pokemon *newPkmn);
bool convertNickname(Gen3Pokemon *newPkmn);
bool convertLanguage(Gen3Pokemon *newPkmn);
bool convertMiscFlags(Gen3Pokemon *newPkmn);
bool convertTrainerNickname(Gen3Pokemon *newPkmn);
bool convertMarkings(Gen3Pokemon *newPkmn);
// Data
bool convertSpeciesIndexNumber(Gen3Pokemon *newPkmn);
bool convertItem(Gen3Pokemon *newPkmn);
bool convertEXP(Gen3Pokemon *newPkmn);
bool convertFriendship(Gen3Pokemon *newPkmn);
bool convertMoves(Gen3Pokemon *newPkmn);
bool convertEVs(Gen3Pokemon *newPkmn);
bool convertContestConditions(Gen3Pokemon *newPkmn);
bool convertPokerus(Gen3Pokemon *newPkmn);
bool convertMetLocation(Gen3Pokemon *newPkmn);
bool convertMetLevel(Gen3Pokemon *newPkmn);
bool convertGameOfOrigin(Gen3Pokemon *newPkmn);
bool convertPokeball(Gen3Pokemon *newPkmn);
bool convertTrainerGender(Gen3Pokemon *newPkmn);
bool convertIVs(Gen3Pokemon *newPkmn);
bool convertAbilityFlag(Gen3Pokemon *newPkmn);
bool convertRibbonsAndObedience(Gen3Pokemon *newPkmn);
bool convertShininess(Gen3Pokemon *newPkmn);
// Extra
bool setRequestedLetter(Gen3Pokemon *newPkmn);
bool setRequestedNature(Gen3Pokemon *newPkmn);
bool setRequestedGender(Gen3Pokemon *newPkmn);
bool setRequestedAbility(Gen3Pokemon *newPkmn);
bool setRequestedSize(Gen3Pokemon *newPkmn);
};
#endif

View File

@ -1,39 +0,0 @@
#ifndef GEN1POKEMON_H
#define GEN1POKEMON_H
#include "GBPokemon.h"
class Gen1Pokemon : public GBPokemon // The class for gen 1 Pokemon
{
public:
Gen1Pokemon(PokemonTables *table);
byte dataArray[33];
u32 getSpeciesIndexNumber();
u32 getCurrentHP() { return getVar(g1_currentHP); }
u32 getStatusCondition() { return getVar(g1_statusCondition); }
u32 getCatchRate() { return getVar(g1_catchRate); }
u32 getType(int typeIndex) { return getVar(*g1_types[typeIndex]); }
bool setSpeciesIndexNumber(byte newVal);
bool setCurrentHP(byte newVal) { return setVar(g1_currentHP, newVal); }
bool setStatusCondition(byte newVal) { return setVar(g1_statusCondition, newVal); }
bool setCatchRate(byte newVal) { return setVar(g1_catchRate, newVal); }
bool setType(int typeIndex, Gen1Types newVal) { return setVar(*g1_types[typeIndex], newVal); }
protected:
static const DataVarInfo
// Gen 1 specific data
g1_currentHP,
g1_statusCondition,
g1_typeOne, g1_typeTwo,
g1_catchRate,
*g1_types[2];
#if ON_GBA
#else
void print(std::ostream &os);
#endif
};
#endif

View File

@ -1,47 +0,0 @@
#ifndef GEN2POKEMON_H
#define GEN2POKEMON_H
#include "GBPokemon.h"
class Gen2Pokemon : public GBPokemon // The class for gen 2 Pokemon
{
public:
Gen2Pokemon(PokemonTables *table);
byte dataArray[32];
u32 getHeldItem() { return getVar(g2_heldItem); }
u32 getFriendship() { return getVar(g2_friendship); }
u32 getPokerusStrain() { return getVar(g2_pokerusStrain); }
u32 getPokerusDaysRemaining() { return getVar(g2_pokerusDaysRemaining); }
u32 getCaughtDataTime() { return getVar(g2_caughtDataTime); }
u32 getCaughtDataLevel() { return getVar(g2_caughtDataLevel); }
u32 getCaughtDataGender() { return getVar(g2_caughtDataGender); }
u32 getCaughtDataLocation() { return getVar(g2_caughtDataLocation); }
bool setHeldItem(byte newVal) { return setVar(g2_heldItem, newVal); }
bool setFriendship(byte newVal) { return setVar(g2_friendship, newVal); }
bool setPokerusStrain(byte newVal) { return setVar(g2_pokerusStrain, newVal); }
bool setPokerusDaysRemaining(byte newVal) { return setVar(g2_pokerusDaysRemaining, newVal); }
bool setCaughtDataTime(byte newVal) { return setVar(g2_caughtDataTime, newVal); }
bool setCaughtDataLevel(byte newVal) { return setVar(g2_caughtDataLevel, newVal); }
bool setCaughtDataGender(byte newVal) { return setVar(g2_caughtDataGender, newVal); }
bool setCaughtDataLocation(byte newVal) { return setVar(g2_caughtDataLocation, newVal); }
protected:
static const DataVarInfo
g2_heldItem,
g2_friendship,
g2_pokerusStrain,
g2_pokerusDaysRemaining,
g2_caughtDataTime,
g2_caughtDataLevel,
g2_caughtDataGender,
g2_caughtDataLocation;
#if ON_GBA
#else
void print(std::ostream &os);
#endif
};
#endif

View File

@ -1,295 +0,0 @@
#ifndef GEN3POKEMON_H
#define GEN3POKEMON_H
#include "Pokemon.h"
class Gen3Pokemon : public Pokemon // The class for gen 3 Pokemon
{
public:
Gen3Pokemon(PokemonTables *table);
bool convertToGen3(Gen3Pokemon *g3p);
u32 currRand;
u32 getNextRand_u32();
u32 getPrevRand_u32();
u16 getNextRand_u16();
u16 getPrevRand_u16();
// These are stored internally so that they can be set by different functions
byte internalUnownLetter;
Nature internalNature;
Gender internalGender;
int internalSize;
int internalAbility;
protected:
// These store the data bytes
byte dataArray[80] = {0};
// This stores if the data is current encrypted or not
bool isEncrypted;
// These store the offsets of the various data substructures:
int substructOffsets[4] = {0, 12, 24, 36};
int currSubstructureShift = 0;
void swapSubstructures(int indexOne, int indexTwo);
#pragma region
// Since there is only the Pokemon parent class, we can directly define these directly
static const DataVarInfo
// All of the data info variables
personalityValue,
trainerID,
secretID,
nicknameLetterOne, // This is silly. Change this.
nicknameLetterTwo,
nicknameLetterThree,
nicknameLetterFour,
nicknameLetterFive,
nicknameLetterSix,
nicknameLetterSeven,
nicknameLetterEight,
nicknameLetterNine,
nicknameLetterTen,
language,
isBadEgg,
hasSpecies,
useEggName,
blockBoxRS,
// unusedFlags,
originalTrainerNameLetterOne, // This is also silly. Change this.
originalTrainerNameLetterTwo,
originalTrainerNameLetterThree,
originalTrainerNameLetterFour,
originalTrainerNameLetterFive,
originalTrainerNameLetterSix,
originalTrainerNameLetterSeven,
markings,
checksum;
// unknown;
static const DataVarInfo
*nickname[10],
*originalTrainerName[7];
// data section G
static const DataVarInfo
speciesIndexNumber,
heldItem,
expPoints,
ppUpNumMoveOne,
ppUpNumMoveTwo,
ppUpNumMoveThree,
ppUpNumMoveFour,
friendship;
// unused;
static const DataVarInfo
*ppUpNums[4];
// data section A
static const DataVarInfo
moveOne,
moveTwo,
moveThree,
moveFour,
moveOnePP,
moveTwoPP,
moveThreePP,
moveFourPP;
static const DataVarInfo
*moves[4],
*ppUpTotals[4];
// data section E
static const DataVarInfo
hpEVs,
attackEVs,
defenseEVs,
speedEVs,
specialAttackEVs,
specialDefenseEVs,
coolnessCondition,
beautyCondition,
cutenessCondition,
smartnessCondition,
toughnessCondition,
sheen;
static const DataVarInfo
*EVs[6],
*contestConditions[5];
static const DataVarInfo
// data section M
pokerusStrain,
pokerusDaysRemaining,
metLocation,
levelMet,
gameOfOrigin,
pokeballCaughtIn,
originalTrainerGender,
hpIVs,
attackIVs,
defenseIVs,
speedIVs,
specialAttackIVs,
specialDefenseIVs,
isEgg,
ability,
coolNormalContestRibbon, // This is also very silly. Change it.
coolSuperContestRibbon,
coolHyperContestRibbon,
coolMasterContestRibbon,
beautyNormalContestRibbon,
beautySuperContestRibbon,
beautyHyperContestRibbon,
beautyMasterContestRibbon,
cuteNormalContestRibbon,
cuteSuperContestRibbon,
cuteHyperContestRibbon,
cuteMasterContestRibbon,
smartNormalContestRibbon,
smartSuperContestRibbon,
smartHyperContestRibbon,
smartMasterContestRibbon,
toughNormalContestRibbon,
toughSuperContestRibbon,
toughHyperContestRibbon,
toughMasterContestRibbon,
championRibbon,
winningRibbon,
victoryRibbon,
artistRibbon,
effortRibbon,
battleChampionRibbon,
regionalChampionRibbon,
nationalChampionRibbon,
countryRibbon,
nationalRibbon,
earthRibbon,
unusedRibbons,
fatefulEncounterObedience;
static const DataVarInfo
*IVs[6],
*ribbons[31];
#pragma endregion
// This is used to easily print out a Pokemon, when using a standard C++ terminal
#if ON_GBA
#else
public:
void print(std::ostream &os);
std::string printDataArray(bool encrypedData);
#endif
public:
// All of the simple getters and setters are defined here
u32 getPersonalityValue() { return getVar(personalityValue); }
u32 getTrainerID() { return getVar(trainerID); }
u32 getSecretID() { return getVar(secretID); }
u32 getLanguage() { return getVar(language); }
u32 getIsBadEgg() { return getVar(isBadEgg); }
u32 getHasSpecies() { return getVar(hasSpecies); }
u32 getUseEggName() { return getVar(useEggName); }
u32 getBlockBoxRS() { return getVar(blockBoxRS); }
u32 getMarkings() { return getVar(markings); }
u32 getChecksum() { return getVar(checksum); }
u32 getSpeciesIndexNumber() { return getVar(speciesIndexNumber, substructOffsets[SUB_G]); }
u32 getHeldItem() { return getVar(heldItem, substructOffsets[SUB_G]); }
u32 getExpPoints() { return getVar(expPoints, substructOffsets[SUB_G]); }
u32 getFriendship() { return getVar(friendship, substructOffsets[SUB_G]); }
u32 getSheen() { return getVar(sheen, substructOffsets[SUB_E]); }
u32 getPokerusStrain() { return getVar(pokerusStrain, substructOffsets[SUB_M]); }
u32 getPokerusDaysRemaining() { return getVar(pokerusDaysRemaining, substructOffsets[SUB_M]); }
u32 getMetLocation() { return getVar(metLocation, substructOffsets[SUB_M]); }
u32 getLevelMet() { return getVar(levelMet, substructOffsets[SUB_M]); }
u32 getGameOfOrigin() { return getVar(gameOfOrigin, substructOffsets[SUB_M]); }
u32 getPokeballCaughtIn() { return getVar(pokeballCaughtIn, substructOffsets[SUB_M]); }
u32 getOriginalTrainerGender() { return getVar(originalTrainerGender, substructOffsets[SUB_M]); }
u32 getIsEgg() { return getVar(isEgg, substructOffsets[SUB_M]); }
u32 getAbility() { return getVar(ability, substructOffsets[SUB_M]); }
u32 getFatefulEncounterObedience() { return getVar(fatefulEncounterObedience, substructOffsets[SUB_M]); }
bool setTrainerID(u32 newVal) { return setVar(trainerID, newVal); }
bool setSecretID(u32 newVal) { return setVar(secretID, newVal); }
bool setLanguage(u32 newVal) { return setVar(language, newVal); }
bool setIsBadEgg(u32 newVal) { return setVar(isBadEgg, newVal); }
bool setHasSpecies(u32 newVal) { return setVar(hasSpecies, newVal); }
bool setUseEggName(u32 newVal) { return setVar(useEggName, newVal); }
bool setBlockBoxRS(u32 newVal) { return setVar(blockBoxRS, newVal); }
bool setMarkings(u32 newVal) { return setVar(markings, newVal); }
bool setChecksum(u32 newVal) { return setVar(checksum, newVal); }
bool setSpeciesIndexNumber(u32 newVal) { return setVar(speciesIndexNumber, substructOffsets[SUB_G], newVal); }
bool setHeldItem(Item newVal) { return setVar(heldItem, substructOffsets[SUB_G], newVal); }
bool setExpPoints(u32 newVal) { return setVar(expPoints, substructOffsets[SUB_G], newVal); }
bool setFriendship(u32 newVal) { return setVar(friendship, substructOffsets[SUB_G], newVal); }
bool setSheen(u32 newVal) { return setVar(sheen, substructOffsets[SUB_E], newVal); }
bool setPokerusStrain(u32 newVal) { return setVar(pokerusStrain, substructOffsets[SUB_M], newVal); }
bool setPokerusDaysRemaining(u32 newVal) { return setVar(pokerusDaysRemaining, substructOffsets[SUB_M], newVal); }
bool setMetLocation(u32 newVal) { return setVar(metLocation, substructOffsets[SUB_M], newVal); }
bool setLevelMet(u32 newVal) { return setVar(levelMet, substructOffsets[SUB_M], newVal); }
bool setGameOfOrigin(Game newVal) { return setVar(gameOfOrigin, substructOffsets[SUB_M], newVal); }
bool setPokeballCaughtIn(u32 newVal) { return setVar(pokeballCaughtIn, substructOffsets[SUB_M], newVal); }
bool setOriginalTrainerGender(u32 newVal) { return setVar(originalTrainerGender, substructOffsets[SUB_M], newVal); }
bool setIsEgg(u32 newVal) { return setVar(isEgg, substructOffsets[SUB_M], newVal); }
bool setFatefulEncounterObedience(u32 newVal) { return setVar(fatefulEncounterObedience, substructOffsets[SUB_M], newVal); }
// The ones that access arrays are defined here:
u32 getPPUpNum(int moveIndex) { return getVar(*ppUpNums[moveIndex], substructOffsets[SUB_G]); }
u32 getMove(int moveIndex) { return getVar(*moves[moveIndex], substructOffsets[SUB_A]); }
u32 getPPTotal(int moveIndex) { return getVar(*ppUpTotals[moveIndex], substructOffsets[SUB_A]); }
u32 getEV(Stat currStat) { return getVar(*EVs[currStat], substructOffsets[SUB_E]); }
u32 getContestCondition(Condition currCondition) { return getVar(*contestConditions[currCondition], substructOffsets[SUB_E]); }
u32 getIV(Stat currStat) { return getVar(*IVs[currStat], substructOffsets[SUB_M]); }
u32 getRibbons(Ribbon currRibbon) { return getVar(*ribbons[currRibbon], substructOffsets[SUB_M]); }
u32 getNicknameLetter(int index) { return getVar(*nickname[index]); };
u32 getOTLetter(int index) { return getVar(*originalTrainerName[index]); };
bool setPPUpNum(int moveIndex, u32 newVal) { return setVar(*ppUpNums[moveIndex], substructOffsets[SUB_G], newVal); }
bool setMove(int moveIndex, u32 newVal) { return setVar(*moves[moveIndex], substructOffsets[SUB_A], newVal); }
bool setPPTotal(int moveIndex, u32 newVal) { return setVar(*ppUpTotals[moveIndex], substructOffsets[SUB_A], newVal); }
bool setEV(Stat currStat, u32 newVal) { return setVar(*EVs[currStat], substructOffsets[SUB_E], newVal); }
bool setContestCondition(Condition currCondition, u32 newVal) { return setVar(*contestConditions[currCondition], substructOffsets[SUB_E], newVal); }
bool setIV(Stat currStat, u32 newVal) { return setVar(*IVs[currStat], substructOffsets[SUB_M], newVal); }
bool setRibbons(Ribbon currRibbon, u32 newVal) { return setVar(*ribbons[currRibbon], substructOffsets[SUB_M], newVal); }
bool setNicknameLetter(int index, u32 newVal) { return setVar(*nickname[index], newVal); };
bool setOTLetter(int index, u32 newVal) { return setVar(*originalTrainerName[index], newVal); };
bool setPersonalityValue(u32 newVal);
bool setAbility(u32 newVal);
// This is used to load our data in from an array and decrypt it
void loadData(byte incomingArray[]);
// And then some general functions
void decryptSubstructures();
void encryptSubstructures();
void updateChecksum();
void updateSubstructureShift();
void resetSubstructureShift();
void updateSecurityData();
byte getUnownLetter();
Nature getNature();
Gender getGender();
int getAbilityFromPersonalityValue();
int getSize();
bool getIsShiny();
bool setNicknameArray(byte nameArr[], int nameArrSize);
bool setOTArray(byte nameArr[], int nameArrSize);
};
#endif

View File

@ -1,49 +0,0 @@
#ifndef POKEBOX_H
#define POKEBOX_H
#include "Gen1Pokemon.h"
#include "Gen2Pokemon.h"
#include "Gen3Pokemon.h"
class PokeBox // Stores up to 30 Pokemon in a box
{
private:
void convertPkmn(int index);
PokemonTables *table;
Pokemon *boxStorage[30];
Pokemon *nullMon;
int currIndex = 0;
public:
PokeBox();
PokeBox(PokemonTables *nTable);
void setTable(PokemonTables *nTable);
bool addPokemon(Pokemon *currPkmn);
Pokemon *getPokemon(int index);
GBPokemon *getGBPokemon(int index);
Gen3Pokemon *getGen3Pokemon(int index);
bool removePokemon(int index);
void loadData(int generation, Language nLang, byte nDataArray[]);
void convertAll();
int getNumInBox();
int getNumValid();
bool stabilize_mythical = false;
#if ON_GBA
#else
friend std::ostream &operator<<(std::ostream &os, PokeBox &pc)
{
for (int i = 0; i < pc.currIndex; i++)
{
os << "\n"
<< "---------------- " << "POKEMON #" << i << " ----------------" << "\n"
<< *pc.boxStorage[i] << "\n";
}
return os;
}
std::string printDataArray();
#endif
};
#endif

View File

@ -1,105 +0,0 @@
#ifndef POKEMON_H
#define POKEMON_H
#include "pokemon_data.h"
#if ON_GBA
#else
#include <iostream>
#include <sstream>
#include <iomanip>
#endif
#if !USE_EXTERNALDATA
// #include "pokemonData.h"
#endif
#if USE_CPP_RAND
#else
#include "random.h"
#endif
// Avoid having to import math
inline u32 sizeToMask(int len)
{
u32 out = 1;
for (int i = 0; i < len; i++)
{
out *= 2;
}
return (out - 1);
}
inline u32 getPureRand() // Gets a random number from the device itself
{
#if USE_CPP_RAND
srand(time(0));
return rand() << 16 | rand();
#else
return get_rand_u32();
#endif
}
// FNV-1a 32-bit hash function for byte arrays
inline u32 fnv1a_hash(unsigned char *data, size_t length)
{
const uint32_t fnv_prime = 0x01000193;
const uint32_t fnv_offset_basis = 0x811C9DC5;
uint32_t hash = fnv_offset_basis;
for (size_t i = 0; i < length; ++i)
{
hash ^= data[i];
hash *= fnv_prime;
}
return hash;
}
class Pokemon // The base Pokemon class
{
public:
Pokemon();
virtual ~Pokemon() {};
virtual u32 getSpeciesIndexNumber();
#if ON_GBA
#else
virtual void print(std::ostream &os)
{
os << "This is a base Pokemon, it has no info!";
};
friend std::ostream &operator<<(std::ostream &os, Pokemon &p)
{
p.print(os);
return os;
}
#endif
int dataArraySize;
int nicknameArraySize;
int OTArraySize;
// Will be set by child classes
byte *dataArrayPtr;
byte *nicknameArrayPtr;
byte *OTArrayPtr;
byte *externalIndexNumberPtr;
// This is extra information that's nice to hold on to
int generation = 0;
bool isValid;
protected:
PokemonTables *pokeTable;
bool isBigEndian;
u32 getVar(DataVarInfo dataVar);
u32 getVar(DataVarInfo dataVar, int extraByteOffset);
bool setVar(DataVarInfo dataVar, u32 newValue);
bool setVar(DataVarInfo dataVar, int extraByteOffset, u32 newValue);
};
#endif

View File

@ -1,9 +0,0 @@
#ifndef PCCS_SETTINGS_H
#define PCCS_SETTINGS_H
#define ON_GBA true
#define USE_COMPRESSED_DATA true
#define USE_CPP_RAND false
#define ACCESS_POKEDEX true
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,671 +0,0 @@
#ifndef TYPEDEFS_H
#define TYPEDEFS_H
#include "pccs_settings.h"
#if ON_GBA
#include <tonc.h>
#else
typedef unsigned char u8, byte, uchar, echar;
typedef unsigned short u16, hword, ushort, eshort;
typedef unsigned int u32, word, uint, eint;
typedef unsigned long long u64;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
#endif
// byte offset, data length (in bits), and bit offset
struct DataVarInfo
{
int byteOffset; // The offset of the value
int dataLength; // The length of the data in bits
int bitOffset; // The offset of where the bits are in the array
};
enum Stat
{
HP,
ATTACK,
DEFENSE,
SPEED,
SPECIAL_ATTACK,
SPECIAL_DEFENSE,
SPECIAL = SPECIAL_ATTACK,
};
enum Condition
{
COOLNESS,
BEAUTY,
CUTENESS,
SMARTNESS,
TOUGHNESS,
};
enum Gen1Types
{
NORMAL,
FIGHTING,
FLYING,
POISON,
GROUND,
ROCK,
BIRD,
BUG,
GHOST,
NINE,
TEN,
ELEVEN,
TWELVE,
THIRTEEN,
FOURTEEN,
FIFTEEN,
SIXTEEN,
SEVENTEEN,
EIGHTEEN,
NINETEEN,
FIRE,
WATER,
GRASS,
ELECTRIC,
PSYCHIC,
ICE,
DRAGON,
};
enum Ribbon
{
COOL_NORMAL_CONTEST,
COOL_SUPER_CONTEST,
COOL_HYPER_CONTEST,
COOL_MASTER_CONTEST,
BEAUTY_NORMAL_CONTEST,
BEAUTY_SUPER_CONTEST,
BEAUTY_HYPER_CONTEST,
BEAUTY_MASTER_CONTEST,
CUTE_NORMAL_CONTEST,
CUTE_SUPER_CONTEST,
CUTE_HYPER_CONTEST,
CUTE_MASTER_CONTEST,
SMART_NORMAL_CONTEST,
SMART_SUPER_CONTEST,
SMART_HYPER_CONTEST,
SMART_MASTER_CONTEST,
TOUGH_NORMAL_CONTEST,
TOUGH_SUPER_CONTEST,
TOUGH_HYPER_CONTEST,
TOUGH_MASTER_CONTEST,
CHAMPION,
WINNING,
VICTORY,
ARTIST,
EFFORT,
BATTLECHAMPION,
REGIONALCHAMPION,
NATIONALCHAMPION,
COUNTRY,
NATIONAL,
EARTH,
};
enum Gender
{
MALE,
FEMALE,
GENDERLESS,
};
enum Nature
{
HARDY,
LONELY,
BRAVE,
ADAMANT,
NAUGHTY,
BOLD,
DOCILE,
RELAXED,
IMPISH,
LAX,
TIMID,
HASTY,
SERIOUS,
JOLLY,
NAIVE,
MODEST,
MILD,
QUIET,
BASHFUL,
RASH,
CALM,
GENTLE,
SASSY,
CAREFUL,
QUIRKY,
};
enum Species
{
BULBASAUR = 1,
IVYSAUR,
VENUSAUR,
CHARMANDER,
CHARMELEON,
CHARIZARD,
SQUIRTLE,
WARTORTLE,
BLASTOISE,
CATERPIE,
METAPOD,
BUTTERFREE,
WEEDLE,
KAKUNA,
BEEDRILL,
PIDGEY,
PIDGEOTTO,
PIDGEOT,
RATTATA,
RATICATE,
SPEAROW,
FEAROW,
EKANS,
ARBOK,
PIKACHU,
RAICHU,
SANDSHREW,
SANDSLASH,
NIDORAN_F,
NIDORINA,
NIDOQUEEN,
NIDORAN_M,
NIDORINO,
NIDOKING,
CLEFAIRY,
CLEFABLE,
VULPIX,
NINETALES,
JIGGLYPUFF,
WIGGLYTUFF,
ZUBAT,
GOLBAT,
ODDISH,
GLOOM,
VILEPLUME,
PARAS,
PARASECT,
VENONAT,
VENOMOTH,
DIGLETT,
DUGTRIO,
MEOWTH,
PERSIAN,
PSYDUCK,
GOLDUCK,
MANKEY,
PRIMEAPE,
GROWLITHE,
ARCANINE,
POLIWAG,
POLIWHIRL,
POLIWRATH,
ABRA,
KADABRA,
ALAKAZAM,
MACHOP,
MACHOKE,
MACHAMP,
BELLSPROUT,
WEEPINBELL,
VICTREEBEL,
TENTACOOL,
TENTACRUEL,
GEODUDE,
GRAVELER,
GOLEM,
PONYTA,
RAPIDASH,
SLOWPOKE,
SLOWBRO,
MAGNEMITE,
MAGNETON,
FARFETCHD,
DODUO,
DODRIO,
SEEL,
DEWGONG,
GRIMER,
MUK,
SHELLDER,
CLOYSTER,
GASTLY,
HAUNTER,
GENGAR,
ONIX,
DROWZEE,
HYPNO,
KRABBY,
KINGLER,
VOLTORB,
ELECTRODE,
EXEGGCUTE,
EXEGGUTOR,
CUBONE,
MAROWAK,
HITMONLEE,
HITMONCHAN,
LICKITUNG,
KOFFING,
WEEZING,
RHYHORN,
RHYDON,
CHANSEY,
TANGELA,
KANGASKHAN,
HORSEA,
SEADRA,
GOLDEEN,
SEAKING,
STARYU,
STARMIE,
MR_MIME,
SCYTHER,
JYNX,
ELECTABUZZ,
MAGMAR,
PINSIR,
TAUROS,
MAGIKARP,
GYARADOS,
LAPRAS,
DITTO,
EEVEE,
VAPOREON,
JOLTEON,
FLAREON,
PORYGON,
OMANYTE,
OMASTAR,
KABUTO,
KABUTOPS,
AERODACTYL,
SNORLAX,
ARTICUNO,
ZAPDOS,
MOLTRES,
DRATINI,
DRAGONAIR,
DRAGONITE,
MEWTWO,
MEW,
CHIKORITA,
BAYLEEF,
MEGANIUM,
CYNDAQUIL,
QUILAVA,
TYPHLOSION,
TOTODILE,
CROCONAW,
FERALIGATR,
SENTRET,
FURRET,
HOOTHOOT,
NOCTOWL,
LEDYBA,
LEDIAN,
SPINARAK,
ARIADOS,
CROBAT,
CHINCHOU,
LANTURN,
PICHU,
CLEFFA,
IGGLYBUFF,
TOGEPI,
TOGETIC,
NATU,
XATU,
MAREEP,
FLAAFFY,
AMPHAROS,
BELLOSSOM,
MARILL,
AZUMARILL,
SUDOWOODO,
POLITOED,
HOPPIP,
SKIPLOOM,
JUMPLUFF,
AIPOM,
SUNKERN,
SUNFLORA,
YANMA,
WOOPER,
QUAGSIRE,
ESPEON,
UMBREON,
MURKROW,
SLOWKING,
MISDREAVUS,
UNOWN,
WOBBUFFET,
GIRAFARIG,
PINECO,
FORRETRESS,
DUNSPARCE,
GLIGAR,
STEELIX,
SNUBBULL,
GRANBULL,
QWILFISH,
SCIZOR,
SHUCKLE,
HERACROSS,
SNEASEL,
TEDDIURSA,
URSARING,
SLUGMA,
MAGCARGO,
SWINUB,
PILOSWINE,
CORSOLA,
REMORAID,
OCTILLERY,
DELIBIRD,
MANTINE,
SKARMORY,
HOUNDOUR,
HOUNDOOM,
KINGDRA,
PHANPY,
DONPHAN,
PORYGON2,
STANTLER,
SMEARGLE,
TYROGUE,
HITMONTOP,
SMOOCHUM,
ELEKID,
MAGBY,
MILTANK,
BLISSEY,
RAIKOU,
ENTEI,
SUICUNE,
LARVITAR,
PUPITAR,
TYRANITAR,
LUGIA,
HO_OH,
CELEBI,
TREECKO,
MISSINGNO = 0xFF,
};
enum PokeBall
{
MASTER = 1,
ULTRA,
GREAT,
POKE,
SAFARI,
NET,
DIVE,
NEST,
REPEAT,
TIMER,
LUXURY,
PREMIER,
};
enum Game
{
SAPPHIRE = 1,
RUBY,
EMERALD,
FIRERED,
LEAFGREEN,
HEARTGOLD = 7,
SOULSILVER,
DIAMOND = 10,
PEARL,
PLATINUM,
COlOSSEUM_XD = 15,
};
enum Item
{
NONE,
MASTER_BALL,
ULTRA_BALL,
GREAT_BALL,
POKE_BALL,
SAFARI_BALL,
NET_BALL,
DIVE_BALL,
NEST_BALL,
REPEAT_BALL,
TIMER_BALL,
LUXURY_BALL,
PREMIER_BALL,
POTION,
ANTIDOTE,
BURN_HEAL,
ICE_HEAL,
AWAKENING,
PARLYZ_HEAL,
FULL_RESTORE,
MAX_POTION,
HYPER_POTION,
SUPER_POTION,
FULL_HEAL,
REVIVE,
MAX_REVIVE,
FRESH_WATER,
SODA_POP,
LEMONADE,
MOOMOO_MILK,
ENERGYPOWDER,
ENERGY_ROOT,
HEAL_POWDER,
REVIVAL_HERB,
ETHER,
MAX_ETHER,
ELIXIR,
MAX_ELIXIR,
LAVA_COOKIE,
BLUE_FLUTE,
YELLOW_FLUTE,
RED_FLUTE,
BLACK_FLUTE,
WHITE_FLUTE,
BERRY_JUICE,
SACRED_ASH,
SHOAL_SALT,
SHOAL_SHELL,
RED_SHARD,
BLUE_SHARD,
YELLOW_SHARD,
GREEN_SHARD,
HP_UP = 0x3F,
PROTEIN,
IRON,
CARBOS,
CALCIUM,
RARE_CANDY,
PP_UP,
ZINC,
PP_MAX,
GUARD_SPEC = 0x49,
DIRE_HIT,
X_ATTACK,
X_DEFEND,
X_SPEED,
X_ACCURACY,
X_SPECIAL,
POKE_DOLL,
FLUFFY_TAIL,
SUPER_REPEL = 0x53,
MAX_REPEL,
ESCAPE_ROPE,
REPEL,
SUN_STONE = 0x5D,
MOON_STONE,
FIRE_STONE,
THUNDERSTONE,
WATER_STONE,
LEAF_STONE,
TINYMUSHROOM = 0x67,
BIG_MUSHROOM,
NORMAL_PEARL = 0x6A,
BIG_PEARL,
STARDUST,
STAR_PIECE,
NUGGET,
HEART_SCALE,
ORANGE_MAIL = 0x79,
HARBOR_MAIL,
GLITTER_MAIL,
MECH_MAIL,
WOOD_MAIL,
WAVE_MAIL,
BEAD_MAIL,
SHADOW_MAIL,
TROPIC_MAIL,
DREAM_MAIL,
FAB_MAIL,
RETRO_MAIL,
CHERI_BERRY,
CHESTO_BERRY,
PECHA_BERRY,
RAWST_BERRY,
ASPEAR_BERRY,
LEPPA_BERRY,
ORAN_BERRY,
PERSIM_BERRY,
LUM_BERRY,
SITRUS_BERRY,
FIGY_BERRY,
WIKI_BERRY,
MAGO_BERRY,
AGUAV_BERRY,
IAPAPA_BERRY,
RAZZ_BERRY,
BLUK_BERRY,
NANAB_BERRY,
WEPEAR_BERRY,
PINAP_BERRY,
POMEG_BERRY,
KELPSY_BERRY,
QUALOT_BERRY,
HONDEW_BERRY,
GREPA_BERRY,
TAMATO_BERRY,
CORNN_BERRY,
MAGOST_BERRY,
RABUTA_BERRY,
NOMEL_BERRY,
SPELON_BERRY,
PAMTRE_BERRY,
WATMEL_BERRY,
DURIN_BERRY,
BELUE_BERRY,
LIECHI_BERRY,
GANLON_BERRY,
SALAC_BERRY,
PETAYA_BERRY,
APICOT_BERRY,
LANSAT_BERRY,
STARF_BERRY,
ENIGMA_BERRY,
BRIGHTPOWDER = 0xB3,
WHITE_HERB,
MACHO_BRACE,
EXP_SHARE,
QUICK_CLAW,
SOOTHE_BELL,
MENTAL_HERB,
CHOICE_BAND,
KINGS_ROCK,
SILVERPOWDER,
AMULET_COIN,
CLEANSE_TAG,
SOUL_DEW,
DEEPSEATOOTH,
DEEPSEASCALE,
SMOKE_BALL,
EVERSTONE,
FOCUS_BAND,
LUCKY_EGG,
SCOPE_LENS,
METAL_COAT,
LEFTOVERS,
DRAGON_SCALE,
LIGHT_BALL,
SOFT_SAND,
HARD_STONE,
MIRACLE_SEED,
BLACKGLASSES,
BLACK_BELT,
MAGNET,
MYSTIC_WATER,
SHARP_BEAK,
POISON_BARB,
NEVERMELTICE,
SPELL_TAG,
TWISTEDSPOON,
CHARCOAL,
DRAGON_FANG,
SILK_SCARF,
UPGRADE,
SHELL_BELL,
SEA_INCENSE,
LAX_INCENSE,
LUCKY_PUNCH,
METAL_POWDER,
THICK_CLUB,
STICK,
RED_SCARF = 0xFE,
BLUE_SCARF,
PINK_SCARF,
GREEN_SCARF,
YELLOW_SCARF
};
enum Substructure
{
SUB_G,
SUB_A,
SUB_E,
SUB_M,
};
enum Language
{
JAPANESE = 1,
ENGLISH,
FRENCH,
ITALIAN,
GERMAN,
SPANISH,
KOREAN,
};
enum RNGMethod
{
ABCD_U, // Normal method
BACD_R, // Used for calculating events
};
#endif

View File

@ -2,7 +2,7 @@
#define POKEMON_PARTY_H
#include <tonc.h>
#include "pccs/PokeBox.h"
#include "PokeBox.h"
#include "gb_rom_values/base_gb_rom_struct.h"
class Pokemon_Party
{

View File

@ -1,5 +1,5 @@
#include <tonc.h>
#include "pccs/typeDefs.h"
#include "typeDefs.h"
#include "button_menu.h"
#include "button_handler.h"
#include "save_data_manager.h"

View File

@ -1,818 +0,0 @@
#include "GBPokemon.h"
// This constructor fills all our convenience arrays
GBPokemon::GBPokemon()
{
nicknameArrayPtr = nicknameArray;
nicknameArraySize = 11;
OTArrayPtr = OTArray;
OTArraySize = 11;
externalIndexNumberPtr = &externalIndexNumber;
isBigEndian = true;
generation = 0;
}
// This is used to load our data in from an array
void GBPokemon::loadData(Language nLang, byte nDataArray[], byte nNicknameArray[], byte nOTArray[], byte nExternalIndexNum)
{
for (int i = 0; i < dataArraySize; i++)
{
dataArrayPtr[i] = nDataArray[i];
}
for (int i = 0; i < nicknameArraySize; i++)
{
nicknameArray[i] = nNicknameArray[i];
}
for (int i = 0; i < OTArraySize; i++)
{
OTArray[i] = nOTArray[i];
}
if (generation == 1)
{
externalIndexNumber = gen_1_index_array[nExternalIndexNum];
}
else
{
externalIndexNumber = nExternalIndexNum;
}
lang = nLang;
updateValidity();
}
// This is used to easily print out a Pokemon, when using a standard C++ terminal
#if ON_GBA
#else
std::string GBPokemon::parentPrint()
{
pokeTable->load_input_charset(generation, ENGLISH);
std::stringstream os;
os << "Species Index Number: " << getSpeciesIndexNumber() << "\n"
<< "Nickname: [";
for (int i = 0; i < 10; i++)
{
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)nicknameArray[i] << (i < 9 ? ", " : "");
}
os << "] (";
for (int i = 0; i < 10; i++)
{
os << (char)(pokeTable->input_charset[(int)nicknameArray[i]]);
}
os << ")" << "\n"
<< "Original Trainer: [";
for (int i = 0; i < 7; i++)
{
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)OTArray[i] << (i < 6 ? ", " : "");
}
os << "] (";
for (int i = 0; i < 7; i++)
{
os << (char)(pokeTable->input_charset[(int)OTArray[i]]);
}
os << ")" << "\n"
<< std::dec
<< "Trainer ID: " << getTrainerID() << "\n"
<< "Level: " << getLevel() << "\n"
<< "Exp: " << getExpPoints() << "\n"
<< "Moves: "
<< "\n\t" << getMove(0) << " (" << getPPTotal(0) << " PP, " << getPPUpNum(0) << " PP Ups" << ")"
<< "\n\t" << getMove(1) << " (" << getPPTotal(1) << " PP, " << getPPUpNum(1) << " PP Ups" << ")"
<< "\n\t" << getMove(2) << " (" << getPPTotal(2) << " PP, " << getPPUpNum(2) << " PP Ups" << ")"
<< "\n\t" << getMove(3) << " (" << getPPTotal(3) << " PP, " << getPPUpNum(3) << " PP Ups" << ")" << "\n"
<< "Is Shiny: " << getIsShiny() << "\n";
return os.str();
}
#endif
u32 GBPokemon::getDV(Stat currStat)
{
if (currStat == HP)
{
return ((getVar(DVs[ATTACK][generation - 1]) & 0x1) << 3) |
((getVar(DVs[DEFENSE][generation - 1]) & 0x1) << 2) |
((getVar(DVs[SPEED][generation - 1]) & 0x1) << 1) |
((getVar(DVs[SPECIAL][generation - 1]) & 0x1) << 0);
}
else
{
return getVar(DVs[currStat][generation - 1]);
}
}
bool GBPokemon::setDV(Stat currStat, byte newVal)
{
if (currStat == HP)
{
return setVar(DVs[ATTACK][generation - 1], (getVar(DVs[ATTACK][generation - 1]) & 0b1110) | ((newVal >> 3) & 0x1)) &&
setVar(DVs[DEFENSE][generation - 1], (getVar(DVs[DEFENSE][generation - 1]) & 0b1110) | ((newVal >> 2) & 0x1)) &&
setVar(DVs[SPEED][generation - 1], (getVar(DVs[SPEED][generation - 1]) & 0b1110) | ((newVal >> 1) & 0x1)) &&
setVar(DVs[SPECIAL][generation - 1], (getVar(DVs[SPECIAL][generation - 1]) & 0b1110) | ((newVal >> 0) & 0x1));
}
else
{
return setVar(DVs[currStat][generation - 1], newVal);
}
}
byte GBPokemon::getUnownLetter()
{
if (getSpeciesIndexNumber() == 201)
{
byte letter = 0;
letter |= ((getDV(ATTACK) & 0b0110) >> 1) << 6;
letter |= ((getDV(DEFENSE) & 0b0110) >> 1) << 4;
letter |= ((getDV(SPEED) & 0b0110) >> 1) << 2;
letter |= ((getDV(SPECIAL) & 0b0110) >> 1) << 0;
letter = letter / 10;
return letter;
}
return 255;
}
Gender GBPokemon::getGender()
{
byte index = getSpeciesIndexNumber();
u32 threshold = pokeTable->get_gender_threshold(index, false);
if (threshold == 255)
{
return GENDERLESS;
}
else
{
if (getDV(ATTACK) <= threshold)
{
return FEMALE;
}
return MALE;
}
}
Nature GBPokemon::getVirtualConsoleNature()
{
return (Nature)(getExpPoints() % 25);
}
bool GBPokemon::getIsShiny()
{
return ((getDV(ATTACK) & 0b0010) == 0b0010) &&
getDV(DEFENSE) == 10 &&
getDV(SPEED) == 10 &&
getDV(SPECIAL) == 10;
}
bool GBPokemon::convertToGen3(Gen3Pokemon *newPkmn, bool sanitizeMythicals)
{
if (!isValid)
{
return false;
}
bool valid =
// Start with things that effect the PID
convertSpeciesIndexNumber(newPkmn) &&
setRequestedLetter(newPkmn) &&
setRequestedNature(newPkmn) &&
setRequestedGender(newPkmn) &&
setRequestedAbility(newPkmn) &&
setRequestedSize(newPkmn) &&
// Then set the PID
generatePersonalityValue(newPkmn, ABCD_U) &&
// Then set everything else
convertTrainerID(newPkmn) &&
convertNickname(newPkmn) &&
convertLanguage(newPkmn) &&
convertMiscFlags(newPkmn) &&
convertTrainerNickname(newPkmn) &&
convertMarkings(newPkmn) &&
convertItem(newPkmn) &&
convertEXP(newPkmn) &&
convertFriendship(newPkmn) &&
convertMoves(newPkmn) &&
convertEVs(newPkmn) &&
convertContestConditions(newPkmn) &&
convertPokerus(newPkmn) &&
convertMetLocation(newPkmn) &&
convertMetLevel(newPkmn) &&
convertGameOfOrigin(newPkmn) &&
convertPokeball(newPkmn) &&
convertTrainerGender(newPkmn) &&
convertIVs(newPkmn) &&
convertRibbonsAndObedience(newPkmn) &&
convertShininess(newPkmn);
if (sanitizeMythicals && (getSpeciesIndexNumber() == MEW || getSpeciesIndexNumber() == CELEBI))
{
// Modify the required data for the event
valid &= loadEvent(newPkmn);
}
newPkmn->isValid = valid;
return valid;
};
bool GBPokemon::loadEvent(Gen3Pokemon *newPkmn)
{
bool valid =
generatePersonalityValue(newPkmn, BACD_R) &&
convertEVs(newPkmn) &&
convertIVs(newPkmn);
if (!valid)
{
return false;
}
if (getSpeciesIndexNumber() == MEW)
{
newPkmn->setGameOfOrigin(RUBY);
newPkmn->setFatefulEncounterObedience(true);
newPkmn->setMetLocation(0xFF); // Fateful Encounter
newPkmn->setLevelMet(10);
newPkmn->setSecretID(00000);
if (newPkmn->getExpPoints() < 560) // 560 is level 10 for Mew
{
newPkmn->setExpPoints(560);
}
byte jpnOT[] = {0x6A, 0x95, 0x53, 0xFF, 0xFF, 0xFF, 0xFF};
byte engOT[] = {0xBB, 0xE9, 0xE6, 0xD5, 0xFF, 0x00, 0x00};
switch (getLanguage())
{
case JAPANESE:
case KOREAN:
newPkmn->setTrainerID(50716);
newPkmn->setOTArray(jpnOT, 7);
break;
case ENGLISH:
case FRENCH:
case ITALIAN:
case GERMAN:
case SPANISH:
default:
newPkmn->setTrainerID(20078);
newPkmn->setOTArray(engOT, 7);
break;
}
}
else if (getSpeciesIndexNumber() == CELEBI)
{
newPkmn->setGameOfOrigin(RUBY);
newPkmn->setFatefulEncounterObedience(false);
newPkmn->setMetLocation(0xFF); // Fateful Encounter
newPkmn->setSecretID(0);
byte jpnOT[] = {0x70, 0x62, 0x78, 0x7E, 0xFF, 0x00, 0x00};
byte engOT[] = {0xA2, 0xA1, 0x00, 0xBB, 0xC8, 0xC3, 0xD0};
switch (getLanguage())
{
case JAPANESE:
case KOREAN:
newPkmn->setLevelMet(10);
if (newPkmn->getExpPoints() < 560) // 560 is level 10 for Celebi
{
newPkmn->setExpPoints(560);
}
newPkmn->setTrainerID(60720);
newPkmn->setOTArray(jpnOT, 7);
break;
case ENGLISH:
case FRENCH:
case ITALIAN:
case GERMAN:
case SPANISH:
default:
newPkmn->setLanguage(ENGLISH);
newPkmn->setLevelMet(70);
if (newPkmn->getExpPoints() < 344960) // 344960 is level 70 for Celebi
{
newPkmn->setExpPoints(344960);
}
newPkmn->setTrainerID(10);
newPkmn->setOTArray(engOT, 7);
break;
}
}
int val = getExpPoints();
if (val < 560) // Mew and Celebi are both Medium Slow, 560 is level 10
{
setExpPoints(560);
}
return true;
}
void GBPokemon::updateValidity()
{
byte currSpeciesIndexNumber = getSpeciesIndexNumber();
isValid = ((currSpeciesIndexNumber <= CELEBI || // Checks if the Pokemon is beyond the spported Pokemon, excluding Treecko for now
(currSpeciesIndexNumber == MISSINGNO && generation == 1)) && // But keep MissingNo
currSpeciesIndexNumber != 0 && // Makes sure the Pokemon isn't a blank party space
currSpeciesIndexNumber == externalIndexNumber && // Checks that the Pokemon isn't a hybrid or an egg
getHeldItem() == 0 // Makes sure the current Pokemon doesn't have a held item
);
};
bool GBPokemon::externalConvertNickname(byte outputArray[])
{
pokeTable->load_input_charset(generation, ENGLISH);
pokeTable->load_gen3_charset(ENGLISH);
for (int i = 0; i < 10; i++)
{
outputArray[i] = pokeTable->get_gen_3_char(pokeTable->input_charset[nicknameArray[i]]);
}
outputArray[10] = 0xFF;
return true;
};
bool GBPokemon::generatePersonalityValue(Gen3Pokemon *newPkmn, RNGMethod rng)
{
newPkmn->currRand = getPureRand();
u32 pid = 0;
u16 seedA = 0;
u16 seedB = 0;
do
{
if (rng == ABCD_U)
{
seedA = newPkmn->getNextRand_u16();
seedB = newPkmn->getNextRand_u16();
pid = seedA | (seedB << 16);
}
else if (rng == BACD_R)
{
newPkmn->currRand &= 0xFFFF; // Restrict the seed to 16 bits
seedA = newPkmn->getNextRand_u16();
seedB = newPkmn->getNextRand_u16();
pid = seedB | (seedA << 16);
}
newPkmn->setPersonalityValue(pid);
// std::cout << "Testing PID: " << std::hex << pid << "\n";
/*
std::cout << "PV: " << newPkmn->getPersonalityValue() << "\n"
<< "Letter: " << newPkmn->getUnownLetter() << " | " << getUnownLetter() << "\n"
<< "Nature: " << newPkmn->getNature() << " | " << getVirtualConsoleNature() << "\n"
<< "Gender: " << newPkmn->getGender() << " | " << getGender() << "\n";
*/
} while (!(
newPkmn->getAbilityFromPersonalityValue() == newPkmn->internalAbility &&
newPkmn->getUnownLetter() == newPkmn->internalUnownLetter &&
newPkmn->getNature() == newPkmn->internalNature &&
newPkmn->getGender() == newPkmn->internalGender &&
newPkmn->getSize() == newPkmn->internalSize));
return true;
};
bool GBPokemon::convertTrainerID(Gen3Pokemon *newPkmn)
{
newPkmn->setTrainerID(getTrainerID());
return true;
}
bool GBPokemon::convertNickname(Gen3Pokemon *newPkmn)
{
pokeTable->load_input_charset(generation, ENGLISH);
pokeTable->load_gen3_charset(ENGLISH);
for (int i = 0; i < 10; i++)
{
newPkmn->setNicknameLetter(i, pokeTable->get_gen_3_char(pokeTable->input_charset[nicknameArray[i]]));
}
return true;
};
bool GBPokemon::convertLanguage(Gen3Pokemon *newPkmn)
{
newPkmn->setLanguage(getLanguage());
return true;
}
bool GBPokemon::convertMiscFlags(Gen3Pokemon *newPkmn)
{
newPkmn->setIsBadEgg(false);
newPkmn->setHasSpecies(true);
newPkmn->setUseEggName(false);
newPkmn->setIsEgg(false);
return true;
}
bool GBPokemon::convertTrainerNickname(Gen3Pokemon *newPkmn)
{
pokeTable->load_input_charset(1, ENGLISH);
pokeTable->load_gen3_charset(ENGLISH);
for (int i = 0; i < 6; i++)
{
newPkmn->setOTLetter(i, pokeTable->get_gen_3_char(pokeTable->input_charset[OTArray[i]]));
}
return true;
};
bool GBPokemon::convertMarkings(Gen3Pokemon *newPkmn)
{
newPkmn->setMarkings(0b0000);
return true;
}
bool GBPokemon::convertSpeciesIndexNumber(Gen3Pokemon *newPkmn)
{
switch (getSpeciesIndexNumber())
{
case TREECKO:
newPkmn->setSpeciesIndexNumber(0x115);
break;
case MISSINGNO:
newPkmn->setSpeciesIndexNumber(PORYGON);
break;
default:
newPkmn->setSpeciesIndexNumber(getSpeciesIndexNumber());
break;
}
return true;
}
bool GBPokemon::convertItem(Gen3Pokemon *newPkmn)
{
#if ACCESS_POKEDEX
#include "save_data_manager.h"
if (!is_caught(newPkmn->getSpeciesIndexNumber()))
{
newPkmn->setHeldItem(RARE_CANDY);
set_caught(newPkmn->getSpeciesIndexNumber());
}
else
{
newPkmn->setHeldItem(NONE);
}
#else
newPkmn->setHeldItem(NONE);
#endif
return true;
}
bool GBPokemon::convertEXP(Gen3Pokemon *newPkmn)
{
// As per Poke Transporter, the level will be based on the level value, not the EXP
// Make sure Level is not over 100
int speciesIndex = getSpeciesIndexNumber();
int currLevel = getLevel();
if (currLevel > 100)
{
currLevel = 100;
}
// Truncate the EXP down to the current level
pokeTable->load_exp_groups();
switch (pokeTable->EXP_GROUPS[speciesIndex])
{
case EXP_FAST:
newPkmn->setExpPoints((4 * (currLevel * currLevel * currLevel)) / 5);
break;
default: // MissingNo is the only one that should hit default, so match it to Porygon
case EXP_MED_FAST:
newPkmn->setExpPoints(currLevel * currLevel * currLevel);
break;
case EXP_MED_SLOW:
newPkmn->setExpPoints(((6 * currLevel * currLevel * currLevel) / 5) - (15 * currLevel * currLevel) + (100 * currLevel) - 140);
break;
case EXP_SLOW:
newPkmn->setExpPoints((5 * (currLevel * currLevel * currLevel)) / 4);
break;
}
return true;
};
bool GBPokemon::convertFriendship(Gen3Pokemon *newPkmn)
{
newPkmn->setFriendship(70);
return true;
}
bool GBPokemon::convertMoves(Gen3Pokemon *newPkmn)
{
Species speciesIndexNum = (Species)getSpeciesIndexNumber();
// Check that the moves are valid
if ((speciesIndexNum != SMEARGLE) &&
(speciesIndexNum != MISSINGNO) &&
(speciesIndexNum != TREECKO)) // Ignore Smeargle, MissingNo, and Treecko
{
for (int i = 0; i < 4; i++)
{
if (pokeTable->can_learn_move(speciesIndexNum, getMove(i)))
{
newPkmn->setMove(i, getMove(i)); // Add the move
newPkmn->setPPUpNum(i, getPPUpNum(i)); // Add the PP Bonuses
}
}
}
// Make sure it has at least one move
int count = 0;
for (int i = 0; i < 4; i++)
{
count += (newPkmn->getMove(i) != 0);
}
if (count == 0)
{
newPkmn->setMove(0, pokeTable->get_earliest_move(speciesIndexNum));
}
// Bubble valid moves to the top
int i, j;
bool swapped;
for (i = 0; i < 3; i++)
{
swapped = false;
for (j = 0; j < 3 - i; j++)
{
if (newPkmn->getMove(j) == 0 && newPkmn->getMove(j + 1) != 0)
{
// Move the move *and* PP bonus up if there is a blank space
newPkmn->setMove(j, newPkmn->getMove(j + 1));
newPkmn->setPPUpNum(j, newPkmn->getPPUpNum(j + 1));
newPkmn->setMove(j + 1, 0);
newPkmn->setPPUpNum(j + 1, 0);
swapped = true;
}
}
// If no two elements were swapped
// by inner loop, then break
if (swapped == false)
break;
}
// Restore the PP values
pokeTable->load_power_points();
for (int i = 0; i < 4; i++)
{
int move = newPkmn->getMove(i);
newPkmn->setPPTotal(i, pokeTable->POWER_POINTS[move] + ((pokeTable->POWER_POINTS[move] / 5) * newPkmn->getPPUpNum(i)));
}
return true;
};
bool GBPokemon::convertEVs(Gen3Pokemon *newPkmn)
{
for (int i = 0; i < 6; i++)
{
newPkmn->setEV((Stat)i, 0);
}
return true;
};
bool GBPokemon::convertContestConditions(Gen3Pokemon *newPkmn)
{
for (int i = 0; i < 5; i++)
{
newPkmn->setContestCondition((Condition)i, 0);
}
newPkmn->setSheen(0);
return true;
};
bool GBPokemon::convertPokerus(Gen3Pokemon *newPkmn)
{
newPkmn->setPokerusStrain(getPokerusStrain());
newPkmn->setPokerusDaysRemaining(getPokerusDaysRemaining());
return true;
}
bool GBPokemon::convertMetLocation(Gen3Pokemon *newPkmn)
{
newPkmn->setMetLocation(0xFF); // A fateful encounter
return true;
}
bool GBPokemon::convertMetLevel(Gen3Pokemon *newPkmn)
{
newPkmn->setLevelMet(getLevel());
return true;
}
bool GBPokemon::convertGameOfOrigin(Gen3Pokemon *newPkmn)
{
switch (generation)
{
case 1:
newPkmn->setGameOfOrigin(FIRERED);
break;
case 2:
newPkmn->setGameOfOrigin(HEARTGOLD);
break;
default:
return false;
}
return true;
}
bool GBPokemon::convertPokeball(Gen3Pokemon *newPkmn)
{
if (getSpeciesIndexNumber() == MISSINGNO)
{
newPkmn->setPokeballCaughtIn(MASTER);
}
else
{
newPkmn->setPokeballCaughtIn(POKE);
}
return true;
}
bool GBPokemon::convertTrainerGender(Gen3Pokemon *newPkmn)
{
newPkmn->setOriginalTrainerGender(getCaughtDataGender());
return true;
};
bool GBPokemon::convertIVs(Gen3Pokemon *newPkmn)
{
u16 currRand;
currRand = newPkmn->getNextRand_u16();
newPkmn->setIV(HP, (currRand >> 0) & 0b11111);
newPkmn->setIV(ATTACK, (currRand >> 5) & 0b11111);
newPkmn->setIV(DEFENSE, (currRand >> 10) & 0b11111);
currRand = newPkmn->getNextRand_u16();
newPkmn->setIV(SPEED, (currRand >> 0) & 0b11111);
newPkmn->setIV(SPECIAL_ATTACK, (currRand >> 5) & 0b11111);
newPkmn->setIV(SPECIAL_DEFENSE, (currRand >> 10) & 0b11111);
return true;
};
bool GBPokemon::convertAbilityFlag(Gen3Pokemon *newPkmn)
{
newPkmn->setAbility(newPkmn->getPersonalityValue() & 0b1);
return true;
}
bool GBPokemon::convertRibbonsAndObedience(Gen3Pokemon *newPkmn)
{
Species speciesIndexNumber = (Species)getSpeciesIndexNumber();
if (speciesIndexNumber == MEW || speciesIndexNumber == CELEBI)
{
newPkmn->setFatefulEncounterObedience(true);
}
return true;
};
bool GBPokemon::setRequestedLetter(Gen3Pokemon *newPkmn)
{
newPkmn->internalUnownLetter = getUnownLetter();
return true;
};
bool GBPokemon::setRequestedNature(Gen3Pokemon *newPkmn)
{
newPkmn->internalNature = getVirtualConsoleNature();
return true;
};
bool GBPokemon::setRequestedGender(Gen3Pokemon *newPkmn)
{
newPkmn->internalGender = getGender();
return true;
};
bool GBPokemon::setRequestedAbility(Gen3Pokemon *newPkmn)
{
newPkmn->internalAbility = 255;
return true;
};
bool GBPokemon::setRequestedSize(Gen3Pokemon *newPkmn)
{
newPkmn->internalSize = 255;
return true;
};
bool GBPokemon::convertShininess(Gen3Pokemon *newPkmn)
{
byte nickname[10] = {};
byte trainerName[7] = {};
for (int i = 0; i < 10; i++)
{
nickname[i] = newPkmn->getNicknameLetter(i);
}
for (int i = 0; i < 7; i++)
{
trainerName[i] = newPkmn->getOTLetter(i);
}
if ((getSpeciesIndexNumber() == 52) &&
fnv1a_hash(trainerName, 7) == 1342961308 &&
(fnv1a_hash(nickname, 7) == 1515822901 || fnv1a_hash(nickname, 8) == 2671449886))
{
for (int i = 1; i <= 4; i++)
{
setDV((Stat)i, 15);
}
}
u16 shinyTest = newPkmn->getTrainerID() ^
(newPkmn->getPersonalityValue() >> 0 & 0xFFFF) ^
(newPkmn->getPersonalityValue() >> 16 & 0xFFFF);
if (getIsShiny())
{ // Make shiny
newPkmn->setSecretID(shinyTest);
}
else
{ // Make sure it isn't shiny
if (shinyTest < 8)
{ // It became shiny, fix that
newPkmn->setSecretID(51691);
}
else
{
newPkmn->setSecretID(0);
}
}
return true;
};
const DataVarInfo
GBPokemon::speciesIndexNumber[2] = {{0x00, 8, 0}, {0x00, 8, 0}},
GBPokemon::level[2] = {{0x03, 8, 0}, {0x1F, 8, 0}},
GBPokemon::moveOne[2] = {{0x08, 8, 0}, {0x02, 8, 0}},
GBPokemon::moveTwo[2] = {{0x09, 8, 0}, {0x03, 8, 0}},
GBPokemon::moveThree[2] = {{0x0A, 8, 0}, {0x04, 8, 0}},
GBPokemon::moveFour[2] = {{0x0B, 8, 0}, {0x05, 8, 0}},
GBPokemon::trainerID[2] = {{0x0C, 16, 0}, {0x06, 16, 0}},
GBPokemon::expPoints[2] = {{0x0E, 24, 0}, {0x08, 24, 0}},
GBPokemon::hpStatExp[2] = {{0x11, 16, 0}, {0x0B, 16, 0}},
GBPokemon::atkStatExp[2] = {{0x13, 16, 0}, {0x0D, 16, 0}},
GBPokemon::defStatExp[2] = {{0x15, 16, 0}, {0x0F, 16, 0}},
GBPokemon::speStatExp[2] = {{0x17, 16, 0}, {0x11, 16, 0}},
GBPokemon::spcStatExp[2] = {{0x19, 16, 0}, {0x13, 16, 0}},
GBPokemon::atkDV[2] = {{0x1B, 4, 4}, {0x15, 4, 4}},
GBPokemon::defDV[2] = {{0x1B, 4, 0}, {0x15, 4, 0}},
GBPokemon::speDV[2] = {{0x1C, 4, 4}, {0x16, 4, 4}},
GBPokemon::spcDV[2] = {{0x1C, 4, 0}, {0x16, 4, 0}},
GBPokemon::ppUpNumMoveOne[2] = {{0x1D, 2, 6}, {0x17, 2, 6}},
GBPokemon::ppNumTotalMoveOne[2] = {{0x1D, 6, 0}, {0x17, 6, 0}},
GBPokemon::ppUpNumMoveTwo[2] = {{0x1E, 2, 6}, {0x18, 2, 6}},
GBPokemon::ppNumTotalMoveTwo[2] = {{0x1E, 6, 0}, {0x18, 6, 0}},
GBPokemon::ppUpNumMoveThree[2] = {{0x1F, 2, 6}, {0x19, 2, 6}},
GBPokemon::ppNumTotalMoveThree[2] = {{0x1F, 6, 0}, {0x19, 6, 0}},
GBPokemon::ppUpNumMoveFour[2] = {{0x20, 2, 6}, {0x1A, 2, 6}},
GBPokemon::ppNumTotalMoveFour[2] = {{0x20, 6, 0}, {0x1A, 6, 0}};
const DataVarInfo
*GBPokemon::moves[4] = {
GBPokemon::moveOne,
GBPokemon::moveTwo,
GBPokemon::moveThree,
GBPokemon::moveFour,
},
*GBPokemon::statExps[5] = {
GBPokemon::hpStatExp,
GBPokemon::atkStatExp,
GBPokemon::defStatExp,
GBPokemon::speStatExp,
GBPokemon::spcStatExp,
},
*GBPokemon::DVs[5] = {
GBPokemon::atkDV, // This is wrong, but it will never be accessed anyway.
GBPokemon::atkDV,
GBPokemon::defDV,
GBPokemon::speDV,
GBPokemon::spcDV,
},
*GBPokemon::PPUpNums[4] = {
GBPokemon::ppUpNumMoveOne,
GBPokemon::ppUpNumMoveTwo,
GBPokemon::ppUpNumMoveThree,
GBPokemon::ppUpNumMoveFour,
},
*GBPokemon::PPUpTotals[4] = {
GBPokemon::ppNumTotalMoveOne,
GBPokemon::ppNumTotalMoveTwo,
GBPokemon::ppNumTotalMoveThree,
GBPokemon::ppNumTotalMoveFour,
};

View File

@ -1,60 +0,0 @@
#include "Gen1Pokemon.h"
Gen1Pokemon::Gen1Pokemon(PokemonTables *table)
{
pokeTable = table;
dataArrayPtr = dataArray;
dataArraySize = 33;
generation = 1;
}
#if ON_GBA
#else
void Gen1Pokemon::print(std::ostream &os)
{
os << parentPrint()
<< "Stats: "
<< "\n\tHP: " << getStatExp(HP) << " Stat EXP, " << getDV(HP) << " DVs"
<< "\n\tAttack: " << getStatExp(ATTACK) << " Stat EXP, " << getDV(ATTACK) << " DVs"
<< "\n\tDefense: " << getStatExp(DEFENSE) << " Stat EXP, " << getDV(DEFENSE) << " DVs"
<< "\n\tSpeed: " << getStatExp(SPEED) << " Stat EXP, " << getDV(SPEED) << " DVs"
<< "\n\tSpecial: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs" << "\n"
<< "Types: "
<< "\n\t" << getType(0)
<< "\n\t" << getType(1) << "\n"
<< "Current HP: " << getCurrentHP() << "\n"
<< "Status Condition: " << getStatusCondition() << "\n"
<< "Catch Rate: " << getCatchRate() << "\n";
}
#endif
u32 Gen1Pokemon::getSpeciesIndexNumber()
{
return gen_1_index_array[getVar(speciesIndexNumber[1])];
}
bool Gen1Pokemon::setSpeciesIndexNumber(byte newVal)
{
for (int i = 0; i < 191; i++)
{
if (gen_1_index_array[i] == newVal)
{
return setVar(speciesIndexNumber[1], newVal);
}
}
return setVar(speciesIndexNumber[1], newVal);
}
const DataVarInfo
Gen1Pokemon::g1_currentHP = {0x01, 16, 0},
Gen1Pokemon::g1_statusCondition = {0x04, 8, 0},
Gen1Pokemon::g1_typeOne = {0x05, 8, 0},
Gen1Pokemon::g1_typeTwo = {0x06, 8, 0},
Gen1Pokemon::g1_catchRate = {0x07, 8, 0};
const DataVarInfo
*Gen1Pokemon::g1_types[2] =
{
&Gen1Pokemon::g1_typeOne,
&Gen1Pokemon::g1_typeTwo,
};

View File

@ -1,44 +0,0 @@
#include "Gen2Pokemon.h"
Gen2Pokemon::Gen2Pokemon(PokemonTables *table)
{
pokeTable = table;
dataArrayPtr = dataArray;
dataArraySize = 32;
generation = 2;
}
#if ON_GBA
#else
void Gen2Pokemon::print(std::ostream &os)
{
os << parentPrint()
<< "Stats: "
<< "\n\tHP: " << getStatExp(HP) << " Stat EXP, " << getDV(HP) << " DVs"
<< "\n\tAttack: " << getStatExp(ATTACK) << " Stat EXP, " << getDV(ATTACK) << " DVs"
<< "\n\tDefense: " << getStatExp(DEFENSE) << " Stat EXP, " << getDV(DEFENSE) << " DVs"
<< "\n\tSpeed: " << getStatExp(SPEED) << " Stat EXP, " << getDV(SPEED) << " DVs"
<< "\n\tSpecial Attack: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs"
<< "\n\tSpecial Defense: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs" << "\n" // Special Attack and Special Defense are the same
<< "Held Item: " << getHeldItem() << "\n"
<< "Friendship: " << getFriendship() << "\n"
<< "Pokerus: "
<< "\n\tStrain: " << getPokerusStrain()
<< "\n\tDays Remaining: " << getPokerusDaysRemaining() << "\n"
<< "Caught Data: "
<< "\n\tTime: " << getCaughtDataTime()
<< "\n\tLevel: " << getCaughtDataLevel()
<< "\n\tTrainer Gender: " << getCaughtDataGender()
<< "\n\tLocation: " << getCaughtDataLocation() << "\n";
}
#endif
const DataVarInfo
Gen2Pokemon::g2_heldItem = {0x01, 8, 0},
Gen2Pokemon::g2_friendship = {0x1B, 8, 0},
Gen2Pokemon::g2_pokerusStrain = {0x1C, 4, 4},
Gen2Pokemon::g2_pokerusDaysRemaining = {0x1C, 4, 0},
Gen2Pokemon::g2_caughtDataTime = {0x1D, 2, 6},
Gen2Pokemon::g2_caughtDataLevel = {0x1D, 6, 0},
Gen2Pokemon::g2_caughtDataGender = {0x1E, 1, 7},
Gen2Pokemon::g2_caughtDataLocation = {0x1E, 7, 0};

View File

@ -1,743 +0,0 @@
#include "Gen3Pokemon.h"
Gen3Pokemon::Gen3Pokemon(PokemonTables *table)
{
pokeTable = table;
dataArrayPtr = dataArray;
dataArraySize = 80;
nicknameArrayPtr = &dataArray[0x8];
OTArrayPtr = &dataArray[0x14];
isBigEndian = false;
isEncrypted = false;
generation = 3;
};
bool Gen3Pokemon::convertToGen3(Gen3Pokemon *g3p)
{
return false;
}
// This is used to easily print out a Pokemon, when using a standard C++ terminal
#if ON_GBA
#else
void Gen3Pokemon::print(std::ostream &os)
{
updateChecksum();
updateSubstructureShift();
pokeTable->load_gen3_charset(ENGLISH);
if (!isValid)
{
os << "ERROR: POKEMON IS INVALID\n";
}
else
{
os
<< "Personality Value: " << std::hex << getPersonalityValue() << std::dec
<< "\n\tLetter: " << (int)getUnownLetter()
<< "\n\tNature: " << getNature()
<< "\n\tGender: " << getGender() << '\n'
<< "Trainer ID: " << getTrainerID() << "\n"
<< "Secret ID: " << getSecretID() << "\n"
<< "Nickname: [";
for (int i = 0; i < 10; i++)
{
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)getNicknameLetter(i) << (i < 9 ? ", " : "");
}
os << "] (";
for (int i = 0; i < 10; i++)
{
os << (char)(pokeTable->gen3_charset[(int)getNicknameLetter(i)]);
}
os << ")" << "\n"
<< "Original Trainer: [";
for (int i = 0; i < 7; i++)
{
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)getOTLetter(i) << (i < 6 ? ", " : "");
}
os << "] (";
for (int i = 0; i < 7; i++)
{
os << (char)(pokeTable->gen3_charset[(int)getOTLetter(i)]);
}
os << ")" << "\n"
<< std::dec
<< "Language: " << getLanguage() << "\n"
<< "Is Bad Egg: " << getIsBadEgg() << "\n"
<< "Has Species: " << getHasSpecies() << "\n"
<< "Use Egg Name: " << getUseEggName() << "\n"
<< "Block Box RS: " << getBlockBoxRS() << "\n"
<< "Markings: " << getMarkings() << "\n"
<< "Checksum: " << getChecksum() << "\n"
<< "Species Index Number: " << getSpeciesIndexNumber() << "\n"
<< "Held Item: " << getHeldItem() << "\n"
<< "Experience: " << getExpPoints() << "\n"
<< "Friendship: " << getFriendship() << "\n"
<< "Stats: "
<< "\n\tHP: " << getEV(HP) << " EVs, " << getIV(HP) << " IVs"
<< "\n\tAttack: " << getEV(ATTACK) << " EVs, " << getIV(ATTACK) << " IVs"
<< "\n\tDefense: " << getEV(DEFENSE) << " EVs, " << getIV(DEFENSE) << " IVs"
<< "\n\tSpecial Attack: " << getEV(SPECIAL_ATTACK) << " EVs, " << getIV(SPECIAL_ATTACK) << " IVs"
<< "\n\tSpecial Defense: " << getEV(SPECIAL_DEFENSE) << " EVs, " << getIV(SPECIAL_DEFENSE) << " IVs"
<< "\n\tSpeed: " << getEV(SPEED) << " EVs, " << getIV(SPEED) << " IVs" << "\n"
<< "Contest Stats: "
<< "\n\tCoolness: " << getContestCondition(COOLNESS)
<< "\n\tBeauty: " << getContestCondition(BEAUTY)
<< "\n\tCuteness: " << getContestCondition(CUTENESS)
<< "\n\tSmartness: " << getContestCondition(SMARTNESS)
<< "\n\tToughness: " << getContestCondition(TOUGHNESS)
<< "\n\tSheen: " << getSheen() << "\n"
<< "Moves: "
<< "\n\t" << getMove(0) << " (" << getPPTotal(0) << " PP, " << getPPUpNum(0) << " PP Ups" << ")"
<< "\n\t" << getMove(1) << " (" << getPPTotal(1) << " PP, " << getPPUpNum(1) << " PP Ups" << ")"
<< "\n\t" << getMove(2) << " (" << getPPTotal(2) << " PP, " << getPPUpNum(2) << " PP Ups" << ")"
<< "\n\t" << getMove(3) << " (" << getPPTotal(3) << " PP, " << getPPUpNum(3) << " PP Ups" << ")" << "\n"
<< "Pokerus: "
<< "\n\tStrain: " << getPokerusStrain()
<< "\n\tDays Remaining: " << getPokerusDaysRemaining() << "\n"
<< "Met Location: " << getMetLocation() << "\n"
<< "Level Met: " << getLevelMet() << "\n"
<< "Game of Origin: " << getGameOfOrigin() << "\n"
<< "Pokeball Caught In: " << getPokeballCaughtIn() << "\n"
<< "Original Trainer Gender: " << getOriginalTrainerGender() << "\n"
<< "Is Egg: " << getIsEgg() << "\n"
<< "Ability: " << getAbility() << "\n"
<< "Fateful Encounter/Obedience: " << getFatefulEncounterObedience() << "\n"
<< "Is Shiny: " << getIsShiny() << "\n"
<< "\n"
<< "Substructure Perm: " << currSubstructureShift << "\n"
<< "Encryption Key: " << std::hex << ((getTrainerID() | getSecretID() << 16) ^ getPersonalityValue()) << std::dec << "\n"
<< "Substructure offsets:"
<< "\n\tG: " << substructOffsets[SUB_G]
<< "\n\tA: " << substructOffsets[SUB_A]
<< "\n\tE: " << substructOffsets[SUB_E]
<< "\n\tM: " << substructOffsets[SUB_M]
<< "\n";
}
};
std::string Gen3Pokemon::printDataArray(bool encrypedData)
{
updateSubstructureShift();
updateChecksum();
encryptSubstructures();
std::stringstream ss;
for (int i = 0; i < 80; i++)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)dataArray[i] << (i < 79 ? " " : "");
}
return ss.str();
}
#endif
// Get Nickname is different
// u32 getNickname() {};
// u32 getOriginalTrainerName() {}
u32 Gen3Pokemon::getNextRand_u32()
{
currRand = (0x41C64E6D * currRand) + 0x6073;
// std::cout << "Rolled: " << std::hex << currRand << "\n";
return currRand;
}
u32 Gen3Pokemon::getPrevRand_u32()
{
currRand = (currRand - 24691) * 4005161829;
return currRand;
}
u16 Gen3Pokemon::getNextRand_u16()
{
return getNextRand_u32() >> 16;
}
u16 Gen3Pokemon::getPrevRand_u16()
{
return getPrevRand_u32() >> 16;
}
bool Gen3Pokemon::setPersonalityValue(u32 newVal) // Setting the Personality Value should modify some other values as well
{
bool successful = setVar(personalityValue, newVal);
if (successful)
{
//successful &= setAbility(getPersonalityValue() & 0b1);
}
return successful;
}
bool Gen3Pokemon::setAbility(u32 newVal) // We need to check if they have two abilities
{
if (pokeTable->get_num_abilities(getSpeciesIndexNumber()) == 0)
{
newVal = 0;
}
internalAbility = newVal;
return setVar(ability, substructOffsets[SUB_M], newVal);
}
// This is used to load our data in from an array and mark it as encrypted
void Gen3Pokemon::loadData(byte incomingArray[])
{
for (int i = 0; i < dataArraySize; i++)
{
dataArrayPtr[i] = incomingArray[i];
}
isEncrypted = true;
}
// And then some general functions
void Gen3Pokemon::decryptSubstructures()
{
if (isEncrypted)
{
u32 key = (getTrainerID() | getSecretID() << 16) ^ getPersonalityValue();
for (int i = 0; i < 48; i++)
{
dataArrayPtr[0x20 + i] ^= ((key >> (8 * (i % 4))) & 0xFF);
}
}
};
void Gen3Pokemon::encryptSubstructures()
{
if (!isEncrypted)
{
u32 key = (getTrainerID() | getSecretID() << 16) ^ getPersonalityValue();
for (int i = 0; i < 48; i++)
{
dataArrayPtr[0x20 + i] ^= ((key >> (8 * (i % 4))) & 0xFF);
}
}
};
void Gen3Pokemon::updateChecksum()
{
bool encryptionState = isEncrypted;
decryptSubstructures();
int checksum = 0x0000;
for (int i = 0; i < 48; i = i + 2)
{
checksum = checksum + ((dataArrayPtr[0x20 + i + 1] << 8) | dataArrayPtr[0x20 + i]);
}
setChecksum(checksum);
if (encryptionState)
{
encryptSubstructures();
}
}
void Gen3Pokemon::updateSubstructureShift()
{
int structureVal = getPersonalityValue() % 24;
if (structureVal == currSubstructureShift)
{
return;
}
currSubstructureShift = structureVal;
resetSubstructureShift();
#define MAX_LEN 4
int index = 0;
while (index < MAX_LEN)
{
int len = MAX_LEN - index;
int factorial = 1;
for (int i = 1; i < len; i++)
{
factorial *= i;
}
int swapLoc = (structureVal / factorial) + index;
for (int i = index; i < swapLoc; i++)
{
swapSubstructures(index, (i + 1));
}
index += 1;
structureVal %= factorial;
}
}
void Gen3Pokemon::resetSubstructureShift()
{
for (int currDest = 0; currDest < 4; currDest++)
{
for (int i = 0; i < 4; i++)
{
if ((substructOffsets[i] / 12) == currDest)
{
swapSubstructures(currDest, i);
}
}
}
}
void Gen3Pokemon::swapSubstructures(int indexOne, int indexTwo)
{
if (indexOne == indexTwo)
{
return;
}
byte tempByte;
for (int i = 0; i < 12; i++)
{
tempByte = dataArrayPtr[0x20 + (indexOne * 12) + i];
dataArrayPtr[0x20 + (indexOne * 12) + i] = dataArrayPtr[0x20 + (indexTwo * 12) + i];
dataArrayPtr[0x20 + (indexTwo * 12) + i] = tempByte;
}
int valOne = 0;
int valTwo = 0;
int tempInt;
for (int i = 0; i < 4; i++)
{
if (substructOffsets[i] == indexOne * 12)
{
valOne = i;
}
if (substructOffsets[i] == indexTwo * 12)
{
valTwo = i;
}
}
tempInt = substructOffsets[valOne];
substructOffsets[valOne] = substructOffsets[valTwo];
substructOffsets[valTwo] = tempInt;
}
void Gen3Pokemon::updateSecurityData()
{
updateSubstructureShift();
updateChecksum();
encryptSubstructures();
}
byte Gen3Pokemon::getUnownLetter()
{
if (getSpeciesIndexNumber() == 201)
{
u32 personalityValue = getPersonalityValue();
return (
((personalityValue & 0x03000000) >> 18) +
((personalityValue & 0x00030000) >> 12) +
((personalityValue & 0x00000300) >> 6) +
((personalityValue & 0x00000003) >> 0)) %
28;
}
else
{
return 255;
}
};
Nature Gen3Pokemon::getNature()
{
return (Nature)(getPersonalityValue() % 25);
};
Gender Gen3Pokemon::getGender()
{
byte index = getSpeciesIndexNumber();
u32 threshold = pokeTable->get_gender_threshold(index, true);
switch (threshold)
{
case 0:
return MALE;
case 254:
return FEMALE;
case 255:
return GENDERLESS;
default:
if ((getPersonalityValue() & 0xFF) >= threshold)
{
return MALE;
}
return FEMALE;
}
}
int Gen3Pokemon::getAbilityFromPersonalityValue()
{
if (internalAbility == 255)
{
return 255;
}
return getPersonalityValue() & 0b1;
}
int Gen3Pokemon::getSize()
{
return 255;
}
bool Gen3Pokemon::getIsShiny()
{
return (getTrainerID() ^
getSecretID() ^
(getPersonalityValue() >> 0 & 0xFFFF) ^
(getPersonalityValue() >> 16 & 0xFFFF)) < 8;
}
bool Gen3Pokemon::setNicknameArray(byte nameArr[], int nameArrSize)
{
for (int i = 0; i < nameArrSize; i++)
{
setNicknameLetter(i, nameArr[i]);
}
return true;
}
bool Gen3Pokemon::setOTArray(byte otArr[], int otArrSize)
{
for (int i = 0; i < otArrSize; i++)
{
setOTLetter(i, otArr[i]);
}
return true;
}
#pragma region
// Since there is only the Pokemon parent class, we can directly define these directly
const DataVarInfo
// All of the data info variables
Gen3Pokemon::personalityValue =
{0x00, 32, 0},
Gen3Pokemon::trainerID =
{0x04, 16, 0},
Gen3Pokemon::secretID =
{0x06, 16, 0},
Gen3Pokemon::nicknameLetterOne =
{0x08, 8, 0}, // This is silly. Change this.
Gen3Pokemon::nicknameLetterTwo =
{0x09, 8, 0},
Gen3Pokemon::nicknameLetterThree =
{0x0A, 8, 0},
Gen3Pokemon::nicknameLetterFour =
{0x0B, 8, 0},
Gen3Pokemon::nicknameLetterFive =
{0x0C, 8, 0},
Gen3Pokemon::nicknameLetterSix =
{0x0D, 8, 0},
Gen3Pokemon::nicknameLetterSeven =
{0x0E, 8, 0},
Gen3Pokemon::nicknameLetterEight =
{0x0F, 8, 0},
Gen3Pokemon::nicknameLetterNine =
{0x10, 8, 0},
Gen3Pokemon::nicknameLetterTen =
{0x11, 8, 0},
Gen3Pokemon::language =
{0x12, 8, 0},
Gen3Pokemon::isBadEgg =
{0x13, 1, 0},
Gen3Pokemon::hasSpecies =
{0x13, 1, 1},
Gen3Pokemon::useEggName =
{0x13, 1, 2},
Gen3Pokemon::blockBoxRS =
{0x13, 1, 3},
// Gen3Pokemon::unusedFlags =
// {0x13, 4, 4},
Gen3Pokemon::originalTrainerNameLetterOne =
{0x14, 8, 0}, // This is also silly. Change this.
Gen3Pokemon::originalTrainerNameLetterTwo =
{0x15, 8, 0},
Gen3Pokemon::originalTrainerNameLetterThree =
{0x16, 8, 0},
Gen3Pokemon::originalTrainerNameLetterFour =
{0x17, 8, 0},
Gen3Pokemon::originalTrainerNameLetterFive =
{0x18, 8, 0},
Gen3Pokemon::originalTrainerNameLetterSix =
{0x19, 8, 0},
Gen3Pokemon::originalTrainerNameLetterSeven =
{0x1A, 8, 0},
Gen3Pokemon::markings =
{0x1B, 4, 0},
Gen3Pokemon::checksum =
{0x1C, 16, 0};
// Gen3Pokemon::unknown =
// {0x1E, 16, 0};
const DataVarInfo
*Gen3Pokemon::nickname[10] = {
&Gen3Pokemon::nicknameLetterOne,
&Gen3Pokemon::nicknameLetterTwo,
&Gen3Pokemon::nicknameLetterThree,
&Gen3Pokemon::nicknameLetterFour,
&Gen3Pokemon::nicknameLetterFive,
&Gen3Pokemon::nicknameLetterSix,
&Gen3Pokemon::nicknameLetterSeven,
&Gen3Pokemon::nicknameLetterEight,
&Gen3Pokemon::nicknameLetterNine,
&Gen3Pokemon::nicknameLetterTen,
},
*Gen3Pokemon::originalTrainerName[7] = {
&Gen3Pokemon::originalTrainerNameLetterOne,
&Gen3Pokemon::originalTrainerNameLetterTwo,
&Gen3Pokemon::originalTrainerNameLetterThree,
&Gen3Pokemon::originalTrainerNameLetterFour,
&Gen3Pokemon::originalTrainerNameLetterFive,
&Gen3Pokemon::originalTrainerNameLetterSix,
&Gen3Pokemon::originalTrainerNameLetterSeven,
};
// data section G
const DataVarInfo
Gen3Pokemon::speciesIndexNumber =
{0x20 + 0x00, 16, 0},
Gen3Pokemon::heldItem =
{0x20 + 0x02, 16, 0},
Gen3Pokemon::expPoints =
{0x20 + 0x04, 32, 0},
Gen3Pokemon::ppUpNumMoveOne =
{0x20 + 0x08, 2, 0},
Gen3Pokemon::ppUpNumMoveTwo =
{0x20 + 0x08, 2, 2},
Gen3Pokemon::ppUpNumMoveThree =
{0x20 + 0x08, 2, 4},
Gen3Pokemon::ppUpNumMoveFour =
{0x20 + 0x08, 2, 6},
Gen3Pokemon::friendship =
{0x20 + 0x09, 8, 0};
// Gen3Pokemon::unused =
// {0x20 + 0x0A, 16, 0};
const DataVarInfo
*Gen3Pokemon::ppUpNums[4] = {
&Gen3Pokemon::ppUpNumMoveOne,
&Gen3Pokemon::ppUpNumMoveTwo,
&Gen3Pokemon::ppUpNumMoveThree,
&Gen3Pokemon::ppUpNumMoveFour,
};
// data section A
const DataVarInfo
Gen3Pokemon::moveOne =
{0x20 + 0x00, 16, 0},
Gen3Pokemon::moveTwo =
{0x20 + 0x02, 16, 0},
Gen3Pokemon::moveThree =
{0x20 + 0x04, 16, 0},
Gen3Pokemon::moveFour =
{0x20 + 0x06, 16, 0},
Gen3Pokemon::moveOnePP =
{0x20 + 0x08, 8, 0},
Gen3Pokemon::moveTwoPP =
{0x20 + 0x09, 8, 0},
Gen3Pokemon::moveThreePP =
{0x20 + 0x0A, 8, 0},
Gen3Pokemon::moveFourPP =
{0x20 + 0x0B, 8, 0};
const DataVarInfo
*Gen3Pokemon::moves[4] = {
&Gen3Pokemon::moveOne,
&Gen3Pokemon::moveTwo,
&Gen3Pokemon::moveThree,
&Gen3Pokemon::moveFour,
},
*Gen3Pokemon::ppUpTotals[4] = {
&Gen3Pokemon::moveOnePP,
&Gen3Pokemon::moveTwoPP,
&Gen3Pokemon::moveThreePP,
&Gen3Pokemon::moveFourPP,
};
// data section E
const DataVarInfo
Gen3Pokemon::hpEVs =
{0x20 + 0x00, 8, 0},
Gen3Pokemon::attackEVs =
{0x20 + 0x01, 8, 0},
Gen3Pokemon::defenseEVs =
{0x20 + 0x02, 8, 0},
Gen3Pokemon::speedEVs =
{0x20 + 0x03, 8, 0},
Gen3Pokemon::specialAttackEVs =
{0x20 + 0x04, 8, 0},
Gen3Pokemon::specialDefenseEVs =
{0x20 + 0x05, 8, 0},
Gen3Pokemon::coolnessCondition =
{0x20 + 0x06, 8, 0},
Gen3Pokemon::beautyCondition =
{0x20 + 0x07, 8, 0},
Gen3Pokemon::cutenessCondition =
{0x20 + 0x08, 8, 0},
Gen3Pokemon::smartnessCondition =
{0x20 + 0x09, 8, 0},
Gen3Pokemon::toughnessCondition =
{0x20 + 0x0A, 8, 0},
Gen3Pokemon::sheen =
{0x20 + 0x0B, 8, 0};
const DataVarInfo
*Gen3Pokemon::EVs[6] = {
&Gen3Pokemon::hpEVs,
&Gen3Pokemon::attackEVs,
&Gen3Pokemon::defenseEVs,
&Gen3Pokemon::speedEVs,
&Gen3Pokemon::specialAttackEVs,
&Gen3Pokemon::specialDefenseEVs,
},
*Gen3Pokemon::contestConditions[5] = {
&Gen3Pokemon::coolnessCondition,
&Gen3Pokemon::beautyCondition,
&Gen3Pokemon::cutenessCondition,
&Gen3Pokemon::smartnessCondition,
&Gen3Pokemon::toughnessCondition,
};
const DataVarInfo
// data section M
Gen3Pokemon::pokerusStrain =
{0x20 + 0x00, 4, 0},
Gen3Pokemon::pokerusDaysRemaining =
{0x20 + 0x00, 4, 4},
Gen3Pokemon::metLocation =
{0x20 + 0x01, 8, 0},
Gen3Pokemon::levelMet =
{0x20 + 0x02, 7, 0},
Gen3Pokemon::gameOfOrigin =
{0x20 + 0x02, 4, 7},
Gen3Pokemon::pokeballCaughtIn =
{0x20 + 0x02, 4, 11},
Gen3Pokemon::originalTrainerGender =
{0x20 + 0x02, 1, 15},
Gen3Pokemon::hpIVs =
{0x20 + 0x04, 5, 0},
Gen3Pokemon::attackIVs =
{0x20 + 0x04, 5, 5},
Gen3Pokemon::defenseIVs =
{0x20 + 0x04, 5, 10},
Gen3Pokemon::speedIVs =
{0x20 + 0x04, 5, 15},
Gen3Pokemon::specialAttackIVs =
{0x20 + 0x04, 5, 20},
Gen3Pokemon::specialDefenseIVs =
{0x20 + 0x04, 5, 25},
Gen3Pokemon::isEgg =
{0x20 + 0x04, 1, 30},
Gen3Pokemon::ability =
{0x20 + 0x04, 1, 31},
Gen3Pokemon::coolNormalContestRibbon =
{0x20 + 0x08, 1, 0}, // This is also very silly. Change it.
Gen3Pokemon::coolSuperContestRibbon =
{0x20 + 0x08, 1, 0},
Gen3Pokemon::coolHyperContestRibbon =
{0x20 + 0x08, 1, 1},
Gen3Pokemon::coolMasterContestRibbon =
{0x20 + 0x08, 1, 2},
Gen3Pokemon::beautyNormalContestRibbon =
{0x20 + 0x08, 1, 3},
Gen3Pokemon::beautySuperContestRibbon =
{0x20 + 0x08, 1, 4},
Gen3Pokemon::beautyHyperContestRibbon =
{0x20 + 0x08, 1, 5},
Gen3Pokemon::beautyMasterContestRibbon =
{0x20 + 0x08, 1, 6},
Gen3Pokemon::cuteNormalContestRibbon =
{0x20 + 0x08, 1, 7},
Gen3Pokemon::cuteSuperContestRibbon =
{0x20 + 0x08, 1, 8},
Gen3Pokemon::cuteHyperContestRibbon =
{0x20 + 0x08, 1, 9},
Gen3Pokemon::cuteMasterContestRibbon =
{0x20 + 0x08, 1, 10},
Gen3Pokemon::smartNormalContestRibbon =
{0x20 + 0x08, 1, 11},
Gen3Pokemon::smartSuperContestRibbon =
{0x20 + 0x08, 1, 12},
Gen3Pokemon::smartHyperContestRibbon =
{0x20 + 0x08, 1, 13},
Gen3Pokemon::smartMasterContestRibbon =
{0x20 + 0x08, 1, 14},
Gen3Pokemon::toughNormalContestRibbon =
{0x20 + 0x08, 1, 15},
Gen3Pokemon::toughSuperContestRibbon =
{0x20 + 0x08, 1, 16},
Gen3Pokemon::toughHyperContestRibbon =
{0x20 + 0x08, 1, 17},
Gen3Pokemon::toughMasterContestRibbon =
{0x20 + 0x08, 1, 18},
Gen3Pokemon::championRibbon =
{0x20 + 0x08, 1, 19},
Gen3Pokemon::winningRibbon =
{0x20 + 0x08, 1, 20},
Gen3Pokemon::victoryRibbon =
{0x20 + 0x08, 1, 21},
Gen3Pokemon::artistRibbon =
{0x20 + 0x08, 1, 22},
Gen3Pokemon::effortRibbon =
{0x20 + 0x08, 1, 23},
Gen3Pokemon::battleChampionRibbon =
{0x20 + 0x08, 1, 24},
Gen3Pokemon::regionalChampionRibbon =
{0x20 + 0x08, 1, 25},
Gen3Pokemon::nationalChampionRibbon =
{0x20 + 0x08, 1, 26},
Gen3Pokemon::countryRibbon =
{0x20 + 0x08, 1, 27},
Gen3Pokemon::nationalRibbon =
{0x20 + 0x08, 1, 28},
Gen3Pokemon::earthRibbon =
{0x20 + 0x08, 1, 29},
Gen3Pokemon::unusedRibbons =
{0x20 + 0x08, 1, 30},
Gen3Pokemon::fatefulEncounterObedience =
{0x20 + 0x08, 1, 31};
const DataVarInfo
*Gen3Pokemon::IVs[6] = {
&Gen3Pokemon::hpIVs,
&Gen3Pokemon::attackIVs,
&Gen3Pokemon::defenseIVs,
&Gen3Pokemon::speedIVs,
&Gen3Pokemon::specialAttackIVs,
&Gen3Pokemon::specialDefenseIVs,
},
*Gen3Pokemon::ribbons[31] = {
&Gen3Pokemon::coolNormalContestRibbon,
&Gen3Pokemon::coolSuperContestRibbon,
&Gen3Pokemon::coolHyperContestRibbon,
&Gen3Pokemon::coolMasterContestRibbon,
&Gen3Pokemon::beautyNormalContestRibbon,
&Gen3Pokemon::beautySuperContestRibbon,
&Gen3Pokemon::beautyHyperContestRibbon,
&Gen3Pokemon::beautyMasterContestRibbon,
&Gen3Pokemon::cuteNormalContestRibbon,
&Gen3Pokemon::cuteSuperContestRibbon,
&Gen3Pokemon::cuteHyperContestRibbon,
&Gen3Pokemon::cuteMasterContestRibbon,
&Gen3Pokemon::smartNormalContestRibbon,
&Gen3Pokemon::smartSuperContestRibbon,
&Gen3Pokemon::smartHyperContestRibbon,
&Gen3Pokemon::smartMasterContestRibbon,
&Gen3Pokemon::toughNormalContestRibbon,
&Gen3Pokemon::toughSuperContestRibbon,
&Gen3Pokemon::toughHyperContestRibbon,
&Gen3Pokemon::toughMasterContestRibbon,
&Gen3Pokemon::championRibbon,
&Gen3Pokemon::winningRibbon,
&Gen3Pokemon::victoryRibbon,
&Gen3Pokemon::artistRibbon,
&Gen3Pokemon::effortRibbon,
&Gen3Pokemon::battleChampionRibbon,
&Gen3Pokemon::regionalChampionRibbon,
&Gen3Pokemon::nationalChampionRibbon,
&Gen3Pokemon::countryRibbon,
&Gen3Pokemon::nationalRibbon,
&Gen3Pokemon::earthRibbon,
};
#pragma endregion

View File

@ -1,165 +0,0 @@
#include "PokeBox.h"
#include <string>
#if ON_GBA
#include "global_frame_controller.h"
#include "text_engine.h"
#endif
PokeBox::PokeBox()
{
nullMon = new Pokemon();
}
PokeBox::PokeBox(PokemonTables *nTable)
{
table = nTable;
}
void PokeBox::setTable(PokemonTables *nTable)
{
table = nTable;
}
bool PokeBox::addPokemon(Pokemon *currPkmn)
{
if (currIndex < 30)
{
boxStorage[currIndex] = currPkmn;
currIndex++;
return true;
}
return false;
}
Pokemon *PokeBox::getPokemon(int index)
{
if (index < currIndex)
{
return boxStorage[index];
}
return nullMon;
}
GBPokemon *PokeBox::getGBPokemon(int index)
{
Pokemon *currPkmn = getPokemon(index);
GBPokemon *currGBPkmn = (GBPokemon *)currPkmn;
return currGBPkmn;
}
Gen3Pokemon *PokeBox::getGen3Pokemon(int index)
{
Pokemon *currPkmn = getPokemon(index);
Gen3Pokemon *currGen3Pkmn = (Gen3Pokemon *)currPkmn;
currGen3Pkmn->updateSecurityData();
return currGen3Pkmn;
}
bool PokeBox::removePokemon(int index)
{
if (index < currIndex)
{
for (int i = index; i < currIndex; i++)
{
boxStorage[i] = boxStorage[i + 1];
}
currIndex -= 1;
return true;
}
return false;
}
// This is used to load our data in from an array
void PokeBox::loadData(int generation, Language nLang, byte nDataArray[])
{
if (nLang != ENGLISH)
{
return; // Other languages are not supported yet
}
for (int pkmnIndex = 0; pkmnIndex < nDataArray[0]; pkmnIndex++)
{
GBPokemon *newPkmn = nullptr;
if (generation == 1)
{
newPkmn = new Gen1Pokemon(table);
}
else if (generation == 2)
{
newPkmn = new Gen2Pokemon(table);
}
int externalIDOffset = 1;
int dataOffset = externalIDOffset + (20 * 1) + 1;
int trainerNameOffset = dataOffset + (20 * newPkmn->dataArraySize);
int nicknameOffset = trainerNameOffset + (20 * newPkmn->OTArraySize);
externalIDOffset += pkmnIndex * 1;
dataOffset += pkmnIndex * newPkmn->dataArraySize;
trainerNameOffset += pkmnIndex * newPkmn->OTArraySize;
nicknameOffset += pkmnIndex * newPkmn->nicknameArraySize;
newPkmn->loadData(
nLang,
&nDataArray[dataOffset], // Pokemon Data
&nDataArray[nicknameOffset], // Nickname
&nDataArray[trainerNameOffset], // Trainer Name
nDataArray[externalIDOffset] // External ID Number
);
addPokemon(newPkmn);
}
}
void PokeBox::convertPkmn(int index)
{
Gen3Pokemon *convertedPkmn = new Gen3Pokemon(table);
Pokemon *basePkmn = getPokemon(index);
GBPokemon *oldPkmn = (GBPokemon *)(basePkmn);
oldPkmn->convertToGen3(convertedPkmn, stabilize_mythical);
delete boxStorage[index];
boxStorage[index] = convertedPkmn;
}
void PokeBox::convertAll()
{
for (int i = 0; i < currIndex; i++)
{
convertPkmn(i);
}
}
int PokeBox::getNumInBox()
{
return currIndex;
}
int PokeBox::getNumValid()
{
int numValid = 0;
for (int i = 0; i < currIndex; i++)
{
if (getPokemon(i)->isValid)
{
numValid++;
}
}
return numValid;
}
#if ON_GBA
#else
std::string PokeBox::printDataArray()
{
std::stringstream ss;
for (int i = 0; i < currIndex; i++)
{
if (boxStorage[i]->generation == 3)
{
ss << ((Gen3Pokemon *)boxStorage[i])->printDataArray(true) << "\n";
}
}
return ss.str();
}
#endif

View File

@ -1,99 +0,0 @@
#include "Pokemon.h"
Pokemon::Pokemon()
{
isValid = false;
}
u32 Pokemon::getSpeciesIndexNumber()
{
return 0;
}
u32 Pokemon::getVar(DataVarInfo dataVar)
{
return getVar(dataVar, 0);
}
u32 Pokemon::getVar(DataVarInfo dataVar, int extraByteOffset)
{
u32 out = 0;
if (dataVar.dataLength < 8)
{ // is less than a byte, do bitwise stuff on a single byte
// ... but we can't assume that the data is within a single byte (thanks gen 3)
if (dataVar.dataLength + dataVar.bitOffset > 8)
{
int numBytes = (dataVar.dataLength + dataVar.bitOffset) / 8 + 1;
if (numBytes > 4)
{
numBytes = 4; // This avoids importing math for rounding. Silly though.
}
int arrayIndex;
for (int i = 0; i < numBytes; i++)
{
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
out = (out << 8) | dataArrayPtr[dataVar.byteOffset + extraByteOffset + arrayIndex];
}
out = (out >> dataVar.bitOffset) & sizeToMask(dataVar.dataLength);
}
else
{
out = (dataArrayPtr[dataVar.byteOffset + extraByteOffset] >> dataVar.bitOffset) & sizeToMask(dataVar.dataLength);
}
}
else
{ // is larger than a byte, will have to access multiple parts of the array
int numBytes = dataVar.dataLength / 8;
int arrayIndex;
for (int i = 0; i < numBytes; i++)
{
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
out = (out << 8) | dataArrayPtr[dataVar.byteOffset + extraByteOffset + arrayIndex];
}
}
return out;
}
bool Pokemon::setVar(DataVarInfo dataVar, u32 newValue)
{
return setVar(dataVar, 0, newValue);
}
bool Pokemon::setVar(DataVarInfo dataVar, int extraByteOffset, u32 newValue)
{
if (dataVar.dataLength < 8)
{ // is less than a byte, do bitwise stuff on a single byte
// ... but we can't assume that the data is within a single byte (thanks gen 3)
if (dataVar.dataLength + dataVar.bitOffset > 8)
{
int numBytes = (dataVar.dataLength + dataVar.bitOffset) / 8 + 1;
if (numBytes > 4)
{
numBytes = 4; // This avoids importing math for rounding. Silly though.
}
int arrayIndex;
for (int i = 0; i < numBytes; i++)
{
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] &= ~((sizeToMask(dataVar.dataLength) << dataVar.bitOffset) >> (arrayIndex * 8));
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] |= ((newValue & sizeToMask(dataVar.dataLength)) << dataVar.bitOffset) >> (arrayIndex * 8);
}
}
else
{
dataArrayPtr[dataVar.byteOffset + extraByteOffset] &= ~(sizeToMask(dataVar.dataLength) << dataVar.bitOffset);
dataArrayPtr[dataVar.byteOffset + extraByteOffset] |= (newValue & sizeToMask(dataVar.dataLength)) << dataVar.bitOffset;
}
}
else
{ // is larger than a byte, will have to access multiple parts of the array
int numBytes = dataVar.dataLength / 8;
int arrayIndex;
for (int i = 0; i < numBytes; i++)
{
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] = (newValue >> (8 * ((numBytes - 1) - i)));
}
}
return true;
}

File diff suppressed because it is too large Load Diff