gpkm/pkm/pkm_bytes
Types
pub type EffortValues {
EffortValues(
hp: Int,
atk: Int,
def: Int,
spe: Int,
spa: Int,
spd: Int,
)
}
Constructors
-
EffortValues( hp: Int, atk: Int, def: Int, spe: Int, spa: Int, spd: Int, )
Encoding used to serialize pkm data
- binary data (readable from a BitArray)
- base64 data (converting base64 string to a BitArray)
pub type Encoding {
Bin
B64
}
Constructors
-
Bin
-
B64
Types used to read pkm data (wether is encoded with base64 or simple binary)
-
*File: read pkm data from .pkm file
-
*Bits: read pkm data from BitArray
-
SavPkm*: encrypted pkm data (that will need to be decrypted first)
-
Sav*: encrypted saved game data (containing multiple pkm BitArrays)
-
Pkm*: unencrypted pkm data
pub type EncryptedDataType {
PkmBits(Encoding)
SavBits(Encoding)
SavPkmBits(Encoding)
PkmFile(Encoding)
SavFile(Encoding)
SavPkmFile(Encoding)
}
Constructors
-
PkmBits(Encoding)
-
SavBits(Encoding)
-
SavPkmBits(Encoding)
-
PkmFile(Encoding)
-
SavFile(Encoding)
-
SavPkmFile(Encoding)
pub type HiddenPower {
HiddenPower(power_type: String, base_power: Int)
}
Constructors
-
HiddenPower(power_type: String, base_power: Int)
pub type IndividualValues {
IndividualValues(
hp: Int,
atk: Int,
def: Int,
spe: Int,
spa: Int,
spd: Int,
)
}
Constructors
-
IndividualValues( hp: Int, atk: Int, def: Int, spe: Int, spa: Int, spd: Int, )
pub type Moves {
Moves(
move_1: Option(Move),
move_2: Option(Move),
move_3: Option(Move),
move_4: Option(Move),
)
}
Constructors
-
Moves( move_1: Option(Move), move_2: Option(Move), move_3: Option(Move), move_4: Option(Move), )
pub type UnencryptedHeaderBytes {
UnencryptedHeaderBytes(pid: Bytes, tmp: Bytes, checksum: Bytes)
}
Constructors
-
UnencryptedHeaderBytes(pid: Bytes, tmp: Bytes, checksum: Bytes)
UnencryptedPkmBytes record is used to store named pkm data bytes, according to ProjectPokemon documentation
Handling Gen4 PKM structure for now, but newer generations should be handled later
pub type UnencryptedPkmBytes {
UnencryptedPkmBytes(
pid: Bytes,
tmp: Bytes,
checksum: Bytes,
national_pokedex_id: Bytes,
held_item: Bytes,
ot_id: Bytes,
ot_secret_id: Bytes,
experience_points: Bytes,
friendship: Bytes,
ability: Bytes,
markings: Bytes,
original_language: Bytes,
hp_effort_value: Bytes,
attack_effort_value: Bytes,
defense_effort_value: Bytes,
speed_effort_value: Bytes,
sp_attack_effort_value: Bytes,
sp_defense_effort_value: Bytes,
cool_contest_value: Bytes,
beauty_contest_value: Bytes,
cute_contest_value: Bytes,
smart_contest_value: Bytes,
tough_contest_value: Bytes,
sheen_contest_value: Bytes,
sinnoh_ribbon_set_1: Bytes,
sinnoh_ribbon_set_2: Bytes,
move_1_id: Bytes,
move_2_id: Bytes,
move_3_id: Bytes,
move_4_id: Bytes,
move_1_current_pp: Bytes,
move_2_current_pp: Bytes,
move_3_current_pp: Bytes,
move_4_current_pp: Bytes,
move_pp_ups: Bytes,
individual_values: Bytes,
hoenn_ribbon_set_1: Bytes,
hoenn_ribbon_set_2: Bytes,
encounter_main_info: Bytes,
hgss_shiny_leaves: Bytes,
unused_b_1: Bytes,
egg_platinum_location: Bytes,
met_at_platinum_location: Bytes,
nickname: Bytes,
unused_c_1: Bytes,
origin_game: Bytes,
sinnoh_ribbon_set_3: Bytes,
sinnoh_ribbon_set_4: Bytes,
unused_c_2: Bytes,
ot_name: Bytes,
date_egg_received: Bytes,
date_met: Bytes,
egg_diamond_pearl_location: Bytes,
met_at_diamond_pearl_location: Bytes,
pokerus: Bytes,
poke_ball: Bytes,
encounter_bonus_info: Bytes,
encounter_type: Bytes,
hgss_poke_ball: Bytes,
unused_d_1: Bytes,
current_status: Bytes,
unknown_1: Bytes,
unknown_2: Bytes,
level: Bytes,
seals_capsule_index: Bytes,
current_hp: Bytes,
max_hp: Bytes,
attack: Bytes,
defense: Bytes,
speed: Bytes,
special_attack: Bytes,
special_defense: Bytes,
unknown_3: Bytes,
seal_coordinates: Bytes,
b64_pkm: String,
)
}
Constructors
-
UnencryptedPkmBytes( pid: Bytes, tmp: Bytes, checksum: Bytes, national_pokedex_id: Bytes, held_item: Bytes, ot_id: Bytes, ot_secret_id: Bytes, experience_points: Bytes, friendship: Bytes, ability: Bytes, markings: Bytes, original_language: Bytes, hp_effort_value: Bytes, attack_effort_value: Bytes, defense_effort_value: Bytes, speed_effort_value: Bytes, sp_attack_effort_value: Bytes, sp_defense_effort_value: Bytes, cool_contest_value: Bytes, beauty_contest_value: Bytes, cute_contest_value: Bytes, smart_contest_value: Bytes, tough_contest_value: Bytes, sheen_contest_value: Bytes, sinnoh_ribbon_set_1: Bytes, sinnoh_ribbon_set_2: Bytes, move_1_id: Bytes, move_2_id: Bytes, move_3_id: Bytes, move_4_id: Bytes, move_1_current_pp: Bytes, move_2_current_pp: Bytes, move_3_current_pp: Bytes, move_4_current_pp: Bytes, move_pp_ups: Bytes, individual_values: Bytes, hoenn_ribbon_set_1: Bytes, hoenn_ribbon_set_2: Bytes, encounter_main_info: Bytes, hgss_shiny_leaves: Bytes, unused_b_1: Bytes, egg_platinum_location: Bytes, met_at_platinum_location: Bytes, nickname: Bytes, unused_c_1: Bytes, origin_game: Bytes, sinnoh_ribbon_set_3: Bytes, sinnoh_ribbon_set_4: Bytes, unused_c_2: Bytes, ot_name: Bytes, date_egg_received: Bytes, date_met: Bytes, egg_diamond_pearl_location: Bytes, met_at_diamond_pearl_location: Bytes, pokerus: Bytes, poke_ball: Bytes, encounter_bonus_info: Bytes, encounter_type: Bytes, hgss_poke_ball: Bytes, unused_d_1: Bytes, current_status: Bytes, unknown_1: Bytes, unknown_2: Bytes, level: Bytes, seals_capsule_index: Bytes, current_hp: Bytes, max_hp: Bytes, attack: Bytes, defense: Bytes, speed: Bytes, special_attack: Bytes, special_defense: Bytes, unknown_3: Bytes, seal_coordinates: Bytes, b64_pkm: String, )
Functions
pub fn get_evs(pkm_bytes: UnencryptedPkmBytes) -> EffortValues
Each EV is a single-byte value
pub fn get_ivs(data: List(Int)) -> IndividualValues
Extract each IV from a 32bits (4 bytes) Int. More info in the UnencryptedPkmBytes type definition
The 32bits Int also hold 2 flags (isEgg, isNicknamed), but I don’t use them for now (maybe later, to make a more exhaustive JSON)
pub fn get_moves(upbs: UnencryptedPkmBytes) -> Moves
Get moves and their pps.
Each move/pp combo will be a Result(Move, Nil), as a Pokemon might not always have learned 4 moves
pub fn get_name(data: List(Int)) -> String
As the in-game names are composed by non-standard unicode chars, they need to be deserialized using a lookup table
In-game names (or nicknames), are little endian bytes lists with variable lengths.
Each encoded letter is a little endian 16bits (2 bytes) value, used as an index of the corresponding unicode letter, from the lookup table
When the name’s length is smaller than the its reserved offset length, an EOL byte (0xffff) is used to determine the end of a name.
Example:
- field: Origin Trainer Name
- offset: 0x68-0x77 (length: 15)
- OT name: "John" (length: 4)
- bytes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 'n', 'h', 'o', 'J' ]
^ ^ ^ ^
each letter here is used to visualize the logic but
is actually a 2-bytes value (the index of the letter)
pub fn get_shifted_iv(ivs: Int, by: Int) -> Int
Use IV max value: 0x1f
(a.k.a 31
), as bit mask to extract target IV
IVS >> BY & MASK
pub fn lookup_move(
move_id: List(Int),
move_pp: List(Int),
) -> Option(Move)
Get move names from the ‘moves’ lookup table