Adding enable deoxys.
This commit is contained in:
parent
6e4a74aa6c
commit
aa12800c52
@ -5,19 +5,23 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box/;
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box parse_version_name/;
|
||||||
|
|
||||||
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
make_all_pokemon_shiny($save);
|
make_all_pokemon_shiny($save);
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub make_all_pokemon_shiny {
|
sub make_all_pokemon_shiny {
|
||||||
|
@ -5,22 +5,26 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box/;
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box parse_version_name/;
|
||||||
|
|
||||||
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
|
|
||||||
# Easier than in real life.
|
# Easier than in real life.
|
||||||
# You will need to change room and voila.
|
# You will need to change room and voila.
|
||||||
change_gender( $save, $FEMALE );
|
change_gender( $save, $FEMALE );
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
start;
|
start;
|
||||||
|
29
examples/enable_deoxys.pl
Normal file
29
examples/enable_deoxys.pl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
use v5.34.1;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Rsaves
|
||||||
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box parse_version_name enable_deoxys_firered/;
|
||||||
|
|
||||||
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
|
sub start {
|
||||||
|
my ( @saves_raw, $extra );
|
||||||
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
|
check_correct_size( @saves_raw, $extra );
|
||||||
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
|
my $save = $saves[$current_save_index];
|
||||||
|
|
||||||
|
# Sightly more complex for other flags, take a look to enable_eon_ticket to see how it works.
|
||||||
|
enable_deoxys_firered($save);
|
||||||
|
save_changes( @saves, $extra, $output );
|
||||||
|
}
|
||||||
|
|
||||||
|
start;
|
@ -5,21 +5,24 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box enable_rematch_main_legendary/;
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box enable_rematch_main_legendary parse_version_name/;
|
||||||
|
|
||||||
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
|
|
||||||
# Sightly more complex for other flags, take a look to enable_eon_ticket to see how it works.
|
|
||||||
enable_rematch_main_legendary($save);
|
enable_rematch_main_legendary($save);
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
start;
|
start;
|
||||||
|
@ -5,21 +5,25 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box/;
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box parse_version_name/;
|
||||||
|
|
||||||
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
|
|
||||||
# Sightly more complex for other flags, take a look to enable_eon_ticket to see how it works.
|
# Sightly more complex for other flags, take a look to enable_eon_ticket to see how it works.
|
||||||
enable_eon_ticket($save);
|
enable_eon_ticket($save);
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
start;
|
start;
|
||||||
|
@ -9,11 +9,15 @@ use Rsaves
|
|||||||
|
|
||||||
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
use Rsaves::Constants::Ruby::Global qw/$MALE $FEMALE/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
|
|
||||||
@ -21,7 +25,7 @@ sub start {
|
|||||||
my $pc = read_pc_storage($save);
|
my $pc = read_pc_storage($save);
|
||||||
my $pokemon = $pc->{boxes}[0][4];
|
my $pokemon = $pc->{boxes}[0][4];
|
||||||
enable_mirage_island_for_pokemon($save, $pokemon);
|
enable_mirage_island_for_pokemon($save, $pokemon);
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
start;
|
start;
|
||||||
|
@ -5,13 +5,17 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box/;
|
qw/read_save check_correct_size get_saves find_current_save_index check_correct_size find_pokemon_substruct change_gender read_pc_storage save_pc_changes enable_eon_ticket save_changes pokemon_set_shiny read_pkm_file_box parse_version_name/;
|
||||||
|
|
||||||
|
my $input = $ARGV[0] or die "No input save";
|
||||||
|
my $output = $ARGV[1] or die "No output save";
|
||||||
|
my $version = parse_version_name($ARGV[2]) // parse_version_name('ruby');
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
my ( @saves_raw, $extra );
|
my ( @saves_raw, $extra );
|
||||||
( @saves_raw[ 0, 1 ], $extra ) = read_save('ruby.sav');
|
( @saves_raw[ 0, 1 ], $extra ) = read_save($input);
|
||||||
check_correct_size( @saves_raw, $extra );
|
check_correct_size( @saves_raw, $extra );
|
||||||
my @saves = get_saves(@saves_raw);
|
my @saves = get_saves(@saves_raw, $version);
|
||||||
my $current_save_index = find_current_save_index(@saves);
|
my $current_save_index = find_current_save_index(@saves);
|
||||||
my $save = $saves[$current_save_index];
|
my $save = $saves[$current_save_index];
|
||||||
my $pc = read_pc_storage($save);
|
my $pc = read_pc_storage($save);
|
||||||
@ -30,7 +34,7 @@ sub start {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_pc_changes( $save, $pc );
|
save_pc_changes( $save, $pc );
|
||||||
save_changes( @saves, $extra, 'ruby1.sav' );
|
save_changes( @saves, $extra, $output );
|
||||||
}
|
}
|
||||||
|
|
||||||
start;
|
start;
|
||||||
|
BIN
leafgreen.sav
Normal file
BIN
leafgreen.sav
Normal file
Binary file not shown.
293
lib/Rsaves.pm
293
lib/Rsaves.pm
@ -7,20 +7,25 @@ use warnings;
|
|||||||
|
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
use Rsaves::Constants::Ruby::Flags qw/$FLAG_SYS_HAS_EON_TICKET $FLAG_LEGENDARY_BATTLE_COMPLETED $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN/;
|
use Rsaves::Constants::Ruby::Flags
|
||||||
use Rsaves::Constants::Ruby::Vars qw/$VAR_CAVE_OF_ORIGIN_B4F_STATE $VARS_START $VAR_MIRAGE_RND_H/;
|
qw/$FLAG_SYS_HAS_EON_TICKET $FLAG_LEGENDARY_BATTLE_COMPLETED $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN/;
|
||||||
|
use Rsaves::Constants::Ruby::Vars qw/ $VAR_MIRAGE_RND_H $VAR_CAVE_OF_ORIGIN_B4F_STATE $VARS_START/;
|
||||||
|
use Rsaves::Constants::Global
|
||||||
|
qw/$SAPPHIRE_VERSION $RUBY_VERSION $EMERALD_VERSION $FIRERED_VERSION $LEAFGREEN_VERSION $COLOSSEUM_VERSION/;
|
||||||
|
|
||||||
|
use Rsaves::Constants::Firered::Flags qw/$FLAG_RECEIVED_AURORA_TICKET $FLAG_ENABLE_SHIP_BIRTH_ISLAND $FLAG_FOUGHT_DEOXYS $FLAG_DEOXYS_FLEW_AWAY/;
|
||||||
use Exporter;
|
use Exporter;
|
||||||
|
|
||||||
use parent 'Exporter';
|
use parent 'Exporter';
|
||||||
|
|
||||||
our @EXPORT_OK = (
|
our @EXPORT_OK = (
|
||||||
qw/read_pc_storage save_pc_changes save_changes enable_eon_ticket
|
qw/read_pc_storage save_pc_changes save_changes enable_eon_ticket
|
||||||
add_key_item set_flag_id change_gender read_save get_saves
|
add_key_item set_flag_id change_gender read_save get_saves
|
||||||
find_current_save_index check_correct_size find_pokemon_substruct
|
find_current_save_index check_correct_size find_pokemon_substruct
|
||||||
read_pkm_file_box calculate_shiny_personality pokemon_set_shiny
|
read_pkm_file_box calculate_shiny_personality pokemon_set_shiny
|
||||||
get_first_super_data set_first_super_data enable_rematch_main_legendary
|
get_first_super_data set_first_super_data enable_rematch_main_legendary
|
||||||
check_flag_id enable_mirage_island_for_pokemon/
|
check_flag_id enable_mirage_island_for_pokemon parse_version_name
|
||||||
|
enable_deoxys_firered/
|
||||||
);
|
);
|
||||||
|
|
||||||
my $SAVE_SIZE = 57344;
|
my $SAVE_SIZE = 57344;
|
||||||
@ -48,15 +53,19 @@ my $PC_BUFFER_G = 11;
|
|||||||
my $PC_BUFFER_H = 12;
|
my $PC_BUFFER_H = 12;
|
||||||
my $PC_BUFFER_I = 13;
|
my $PC_BUFFER_I = 13;
|
||||||
my ( $FEMALE, $MALE ) = ( 1, 0 );
|
my ( $FEMALE, $MALE ) = ( 1, 0 );
|
||||||
my $FLAGS_OFFSET = hex '1220';
|
my $FLAGS_OFFSET_RUBY = hex '1220';
|
||||||
my $TRAINER_FLAG_START = hex '500';
|
my $FLAGS_OFFSET_FIRERED = 0x0ee0;
|
||||||
my $NUMBER_OF_TRAINERS = 693;
|
my $TRAINER_FLAG_START = hex '500';
|
||||||
my $KEY_ITEMS_OFFSET = hex '5b0';
|
my $NUMBER_OF_TRAINERS = 693;
|
||||||
my $MAX_KEY_ITEMS = 20;
|
my $KEY_ITEMS_OFFSET_RUBY = 0x5b0;
|
||||||
my $ITEM_EON_TICKET = 275;
|
my $KEY_ITEMS_OFFSET_FIRERED = 0x03b8;
|
||||||
my $POKEMON_NAME_LENGTH = 10;
|
my $MAX_KEY_ITEMS_RUBY = 20;
|
||||||
my $OT_NAME_LENGTH = 7;
|
my $MAX_KEY_ITEMS_FIRERED = 30;
|
||||||
my $BOX_NAME_LENGTH = 9;
|
my $ITEM_EON_TICKET = 275;
|
||||||
|
my $ITEM_AURORA_TICKET = 371;
|
||||||
|
my $POKEMON_NAME_LENGTH = 10;
|
||||||
|
my $OT_NAME_LENGTH = 7;
|
||||||
|
my $BOX_NAME_LENGTH = 9;
|
||||||
|
|
||||||
my %CHECKSUM_BYTES = (
|
my %CHECKSUM_BYTES = (
|
||||||
$TRAINER_INFO => hex 'F80',
|
$TRAINER_INFO => hex 'F80',
|
||||||
@ -73,26 +82,43 @@ die 'Invalid number of checksum sections.'
|
|||||||
|
|
||||||
sub _hihalf_u32 {
|
sub _hihalf_u32 {
|
||||||
my $n = shift;
|
my $n = shift;
|
||||||
return (($n & 0xFFFF0000) >> 16);
|
return ( ( $n & 0xFFFF0000 ) >> 16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _lowhalf_u32 {
|
sub _lowhalf_u32 {
|
||||||
my $n = shift;
|
my $n = shift;
|
||||||
return ($n & 0xFFFF);
|
return ( $n & 0xFFFF );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub parse_version_name {
|
||||||
|
my $version_name = shift;
|
||||||
|
return if !defined $version_name;
|
||||||
|
(
|
||||||
|
return (
|
||||||
|
{
|
||||||
|
ruby => $RUBY_VERSION,
|
||||||
|
sapphire => $SAPPHIRE_VERSION,
|
||||||
|
emerald => $EMERALD_VERSION,
|
||||||
|
firered => $FIRERED_VERSION,
|
||||||
|
leafgreen => $LEAFGREEN_VERSION,
|
||||||
|
}->{$version_name}
|
||||||
|
)
|
||||||
|
) or die "Unsupported version";
|
||||||
|
}
|
||||||
|
|
||||||
sub pokemon_set_shiny {
|
sub pokemon_set_shiny {
|
||||||
my $pokemon = shift;
|
my $pokemon = shift;
|
||||||
$pokemon->{personality} = calculate_shiny_personality($pokemon->{otid}, $pokemon->{personality});
|
$pokemon->{personality} =
|
||||||
|
calculate_shiny_personality( $pokemon->{otid}, $pokemon->{personality} );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub calculate_shiny_personality {
|
sub calculate_shiny_personality {
|
||||||
my $otid = shift;
|
my $otid = shift;
|
||||||
my $personality = shift;
|
my $personality = shift;
|
||||||
my $wanted_three_parts_bytes = _lowhalf_u32($personality) ^ int(rand(7));
|
my $wanted_three_parts_bytes = _lowhalf_u32($personality) ^ int( rand(7) );
|
||||||
my $wanted_high_personality = _hihalf_u32($otid) ^ _lowhalf_u32($otid) ^ $wanted_three_parts_bytes;
|
my $wanted_high_personality =
|
||||||
return ($wanted_high_personality << 16) | _lowhalf_u32($personality);
|
_hihalf_u32($otid) ^ _lowhalf_u32($otid) ^ $wanted_three_parts_bytes;
|
||||||
|
return ( $wanted_high_personality << 16 ) | _lowhalf_u32($personality);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_first_super_data {
|
sub get_first_super_data {
|
||||||
@ -113,8 +139,6 @@ sub set_first_super_data {
|
|||||||
close $fh;
|
close $fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sub find_pokemon_substruct {
|
sub find_pokemon_substruct {
|
||||||
my $substructures = shift;
|
my $substructures = shift;
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@ -132,7 +156,7 @@ sub read_pc_storage {
|
|||||||
my $current_box = unpack 'C', $read;
|
my $current_box = unpack 'C', $read;
|
||||||
read $fh, $read, 3;
|
read $fh, $read, 3;
|
||||||
my $unknown = $read;
|
my $unknown = $read;
|
||||||
my $pc = _read_pokemon_boxes_from_fh($fh);
|
my $pc = _read_pokemon_boxes_from_fh($fh);
|
||||||
my @box_names;
|
my @box_names;
|
||||||
|
|
||||||
for ( 0 .. 13 ) {
|
for ( 0 .. 13 ) {
|
||||||
@ -149,7 +173,7 @@ sub read_pc_storage {
|
|||||||
return {
|
return {
|
||||||
current_box => $current_box,
|
current_box => $current_box,
|
||||||
boxes => $pc,
|
boxes => $pc,
|
||||||
unknown => $unknown,
|
unknown => $unknown,
|
||||||
boxes_names => \@box_names,
|
boxes_names => \@box_names,
|
||||||
wallpapers => \@wallpapers,
|
wallpapers => \@wallpapers,
|
||||||
};
|
};
|
||||||
@ -163,20 +187,20 @@ sub save_pc_changes {
|
|||||||
print $fh pack 'C', $pc->{current_box};
|
print $fh pack 'C', $pc->{current_box};
|
||||||
print $fh $pc->{unknown};
|
print $fh $pc->{unknown};
|
||||||
_write_pokemon_boxes_to_fh( $fh, $pc->{boxes} );
|
_write_pokemon_boxes_to_fh( $fh, $pc->{boxes} );
|
||||||
for (0..13) {
|
for ( 0 .. 13 ) {
|
||||||
print $fh $pc->{boxes_names}[$_];
|
print $fh $pc->{boxes_names}[$_];
|
||||||
}
|
}
|
||||||
for (0..13) {
|
for ( 0 .. 13 ) {
|
||||||
print $fh (pack 'C', $pc->{wallpapers}[$_]);
|
print $fh ( pack 'C', $pc->{wallpapers}[$_] );
|
||||||
}
|
}
|
||||||
my $length = length $superdata;
|
my $length = length $superdata;
|
||||||
die "Wrong pc size $length != @{[0x83d0]}" if $length != 0x83d0;
|
die "Wrong pc size $length != @{[0x83d0]}" if $length != 0x83d0;
|
||||||
my @sections = _find_sections_save( $save, $PC_BUFFER_A .. $PC_BUFFER_I );
|
my @sections = _find_sections_save( $save, $PC_BUFFER_A .. $PC_BUFFER_I );
|
||||||
open $fh, '<', \$superdata;
|
open $fh, '<', \$superdata;
|
||||||
for my $section (@sections) {
|
for my $section (@sections) {
|
||||||
read $fh, (my $read), $SECTION_DATA_SIZE;
|
read $fh, ( my $read ), $SECTION_DATA_SIZE;
|
||||||
my $length = length $read;
|
my $length = length $read;
|
||||||
$section->{data} = $read;
|
$section->{data} = $read;
|
||||||
}
|
}
|
||||||
read $fh, my $read, 1 and die "Not all readed";
|
read $fh, my $read, 1 and die "Not all readed";
|
||||||
close $fh;
|
close $fh;
|
||||||
@ -221,13 +245,13 @@ sub read_pkm_file_box {
|
|||||||
my $file_contents = join '', <$fh>;
|
my $file_contents = join '', <$fh>;
|
||||||
$file_contents = substr $file_contents, 0, 0x50;
|
$file_contents = substr $file_contents, 0, 0x50;
|
||||||
open $fh, '<', \$file_contents;
|
open $fh, '<', \$file_contents;
|
||||||
return _read_pokemon_box_from_fh($fh, 1);
|
return _read_pokemon_box_from_fh( $fh, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _write_pokemon_fh {
|
sub _write_pokemon_fh {
|
||||||
my $fh = shift;
|
my $fh = shift;
|
||||||
my $pokemon = shift;
|
my $pokemon = shift;
|
||||||
if ($pokemon->{personality} > 0xFFFFFFFF) {
|
if ( $pokemon->{personality} > 0xFFFFFFFF ) {
|
||||||
die "Too big personality";
|
die "Too big personality";
|
||||||
}
|
}
|
||||||
print $fh pack 'V', $pokemon->{personality};
|
print $fh pack 'V', $pokemon->{personality};
|
||||||
@ -242,10 +266,8 @@ sub _write_pokemon_fh {
|
|||||||
{
|
{
|
||||||
open my $fh_substructures, '>', \$substructures_raw;
|
open my $fh_substructures, '>', \$substructures_raw;
|
||||||
$pokemon->{checksum} = _write_pokemon_substructures_fh(
|
$pokemon->{checksum} = _write_pokemon_substructures_fh(
|
||||||
$fh_substructures,
|
$fh_substructures, $pokemon->{substructures},
|
||||||
$pokemon->{substructures},
|
$pokemon->{personality}, $pokemon->{otid}
|
||||||
$pokemon->{personality},
|
|
||||||
$pokemon->{otid}
|
|
||||||
);
|
);
|
||||||
close $fh_substructures;
|
close $fh_substructures;
|
||||||
}
|
}
|
||||||
@ -258,7 +280,7 @@ sub _write_pokemon_fh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub _read_pokemon_box_from_fh {
|
sub _read_pokemon_box_from_fh {
|
||||||
my $fh = shift;
|
my $fh = shift;
|
||||||
my $is_pkm_file = shift;
|
my $is_pkm_file = shift;
|
||||||
|
|
||||||
# 0
|
# 0
|
||||||
@ -312,14 +334,16 @@ sub _read_pokemon_substructures_from_fh {
|
|||||||
read $fh, my $read, ( 12 * 4 );
|
read $fh, my $read, ( 12 * 4 );
|
||||||
my $raw;
|
my $raw;
|
||||||
my @order_substructures;
|
my @order_substructures;
|
||||||
if (!$is_pkm_file) {
|
|
||||||
|
if ( !$is_pkm_file ) {
|
||||||
$raw = _decrypt_pokemon_substructures_raw( $read, $otid, $personality,
|
$raw = _decrypt_pokemon_substructures_raw( $read, $otid, $personality,
|
||||||
$checksum );
|
$checksum );
|
||||||
@order_substructures =
|
@order_substructures =
|
||||||
_pokemon_substructures_order_by_modulo( $personality % 24 );
|
_pokemon_substructures_order_by_modulo( $personality % 24 );
|
||||||
} else {
|
}
|
||||||
$raw = $read;
|
else {
|
||||||
@order_substructures = (0, 1, 2, 3);
|
$raw = $read;
|
||||||
|
@order_substructures = ( 0, 1, 2, 3 );
|
||||||
}
|
}
|
||||||
my $substructures = [];
|
my $substructures = [];
|
||||||
open my $fh_raw, '<', \$raw;
|
open my $fh_raw, '<', \$raw;
|
||||||
@ -328,7 +352,7 @@ sub _read_pokemon_substructures_from_fh {
|
|||||||
read $fh_raw, my $substruct, 12;
|
read $fh_raw, my $substruct, 12;
|
||||||
open my $fh_substruct, '<', \$substruct;
|
open my $fh_substruct, '<', \$substruct;
|
||||||
push @$substructures,
|
push @$substructures,
|
||||||
_read_pokemon_substruct_n_from_fh( $fh_substruct, $i);
|
_read_pokemon_substruct_n_from_fh( $fh_substruct, $i );
|
||||||
close $fh_substruct;
|
close $fh_substruct;
|
||||||
}
|
}
|
||||||
close $fh_raw;
|
close $fh_raw;
|
||||||
@ -360,7 +384,8 @@ sub _write_pokemon_substructures_fh {
|
|||||||
}
|
}
|
||||||
close $fh_decrypted_substructures;
|
close $fh_decrypted_substructures;
|
||||||
open $fh_decrypted_substructures, '<', \$decrypted_substructures;
|
open $fh_decrypted_substructures, '<', \$decrypted_substructures;
|
||||||
my $checksum = _pokemon_checksum_substructures_fh($fh_decrypted_substructures);
|
my $checksum =
|
||||||
|
_pokemon_checksum_substructures_fh($fh_decrypted_substructures);
|
||||||
seek $fh_decrypted_substructures, 0, 0;
|
seek $fh_decrypted_substructures, 0, 0;
|
||||||
my $encrypted_substructures;
|
my $encrypted_substructures;
|
||||||
open my $fh_encrypted_substructures, '>', \$encrypted_substructures;
|
open my $fh_encrypted_substructures, '>', \$encrypted_substructures;
|
||||||
@ -381,7 +406,7 @@ sub _pokemon_checksum_substructures_fh {
|
|||||||
for ( 0 .. 3 ) {
|
for ( 0 .. 3 ) {
|
||||||
for ( 0 .. 5 ) {
|
for ( 0 .. 5 ) {
|
||||||
read $fh, my $read, 2 or die "Unable to read";
|
read $fh, my $read, 2 or die "Unable to read";
|
||||||
$checksum = _sum_u16( (unpack 'v', $read), $checksum );
|
$checksum = _sum_u16( ( unpack 'v', $read ), $checksum );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $checksum;
|
return $checksum;
|
||||||
@ -741,7 +766,10 @@ sub save_changes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub enable_eon_ticket {
|
sub enable_eon_ticket {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
die "This is not Pokémon Ruby or Sapphire"
|
||||||
|
if !_is_ruby_or_sapphire( $section0->{version} );
|
||||||
my $superdata = get_first_super_data($save);
|
my $superdata = get_first_super_data($save);
|
||||||
say "Latios already enabled", return
|
say "Latios already enabled", return
|
||||||
if check_flag_id( $save, $superdata, $FLAG_SYS_HAS_EON_TICKET );
|
if check_flag_id( $save, $superdata, $FLAG_SYS_HAS_EON_TICKET );
|
||||||
@ -750,58 +778,108 @@ sub enable_eon_ticket {
|
|||||||
set_first_super_data( $save, $superdata );
|
set_first_super_data( $save, $superdata );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub enable_mirage_island_for_pokemon {
|
sub enable_deoxys_firered {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
my $pokemon = shift;
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
die "This is not Pokemon Leafgreen or Firered"
|
||||||
|
if !_is_leafgreen_or_firered( $section0->{version} );
|
||||||
my $superdata = get_first_super_data($save);
|
my $superdata = get_first_super_data($save);
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_RECEIVED_AURORA_TICKET, 1 );
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_ENABLE_SHIP_BIRTH_ISLAND, 1 );
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_FOUGHT_DEOXYS, 0 );
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_DEOXYS_FLEW_AWAY, 0 );
|
||||||
|
add_key_item( $save, $superdata, $ITEM_AURORA_TICKET );
|
||||||
|
set_first_super_data( $save, $superdata );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub enable_mirage_island_for_pokemon {
|
||||||
|
my $save = shift;
|
||||||
|
my $pokemon = shift;
|
||||||
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
die "This is not Pokémon Ruby or Sapphire"
|
||||||
|
if !_is_ruby_or_sapphire( $section0->{version} );
|
||||||
|
my $superdata = get_first_super_data($save);
|
||||||
my $personality = $pokemon->{personality};
|
my $personality = $pokemon->{personality};
|
||||||
my $substruct0 = find_pokemon_substruct($pokemon->{substructures}, 0);
|
my $substruct0 = find_pokemon_substruct( $pokemon->{substructures}, 0 );
|
||||||
say $substruct0->{species};
|
say $substruct0->{species};
|
||||||
|
|
||||||
printf "%x\n", $personality & 0xffff;
|
printf "%x\n", $personality & 0xffff;
|
||||||
set_var($save, $superdata, $VAR_MIRAGE_RND_H, $personality & 0xffff);
|
set_var( $save, $superdata, $VAR_MIRAGE_RND_H, $personality & 0xffff );
|
||||||
set_first_super_data ( $save, $superdata );
|
set_first_super_data( $save, $superdata );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub enable_rematch_main_legendary {
|
sub enable_rematch_main_legendary {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
die "This is not Pokémon Ruby or Sapphire"
|
||||||
|
if !_is_ruby_or_sapphire( $section0->{version} );
|
||||||
my $superdata = get_first_super_data($save);
|
my $superdata = get_first_super_data($save);
|
||||||
if (check_flag_id($save, $superdata, $FLAG_LEGENDARY_BATTLE_COMPLETED)) {
|
if ( check_flag_id( $save, $superdata, $FLAG_LEGENDARY_BATTLE_COMPLETED ) )
|
||||||
set_flag_id ($save, $superdata, $FLAG_LEGENDARY_BATTLE_COMPLETED, 0);
|
{
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_LEGENDARY_BATTLE_COMPLETED, 0 );
|
||||||
}
|
}
|
||||||
if (check_flag_id($save, $superdata, $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN)) {
|
if (
|
||||||
set_flag_id ($save, $superdata, $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN, 0);
|
check_flag_id(
|
||||||
|
$save, $superdata, $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
set_flag_id( $save, $superdata, $FLAG_HIDE_LEGEND_MON_CAVE_OF_ORIGIN,
|
||||||
|
0 );
|
||||||
}
|
}
|
||||||
if (get_var($save, $superdata, $VAR_CAVE_OF_ORIGIN_B4F_STATE)) {
|
if ( get_var( $save, $superdata, $VAR_CAVE_OF_ORIGIN_B4F_STATE ) ) {
|
||||||
set_var($save, $superdata, $VAR_CAVE_OF_ORIGIN_B4F_STATE, 0);
|
set_var( $save, $superdata, $VAR_CAVE_OF_ORIGIN_B4F_STATE, 0 );
|
||||||
}
|
}
|
||||||
set_first_super_data( $save, $superdata );
|
set_first_super_data( $save, $superdata );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_security_key {
|
||||||
|
my $save = shift;
|
||||||
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
my $version = $section0->{version};
|
||||||
|
my $data = $section0->{data};
|
||||||
|
open my $fh, '<', \$data;
|
||||||
|
if (_is_leafgreen_or_firered($version)) {
|
||||||
|
read $fh, my $read, 0xf20;
|
||||||
|
read $fh, $read, 4;
|
||||||
|
return unpack 'V', $read;
|
||||||
|
}
|
||||||
|
close $fh;
|
||||||
|
die "Not implemented";
|
||||||
|
}
|
||||||
|
|
||||||
sub add_key_item {
|
sub add_key_item {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
my $superdata = shift;
|
my $superdata = shift;
|
||||||
my $item_id = shift;
|
my $item_id = shift;
|
||||||
my $result = '';
|
my $result = '';
|
||||||
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
my $version = $section0->{version};
|
||||||
open my $fh, '<', $superdata;
|
open my $fh, '<', $superdata;
|
||||||
read $fh, my ($read), $KEY_ITEMS_OFFSET;
|
my $offset = $KEY_ITEMS_OFFSET_RUBY;
|
||||||
|
my $max_key_items = $MAX_KEY_ITEMS_RUBY;
|
||||||
|
if (_is_leafgreen_or_firered($version)) {
|
||||||
|
$offset = $KEY_ITEMS_OFFSET_FIRERED;
|
||||||
|
$max_key_items = $MAX_KEY_ITEMS_FIRERED;
|
||||||
|
}
|
||||||
|
read $fh, my ($read), $offset;
|
||||||
$result .= $read;
|
$result .= $read;
|
||||||
LOOP: {
|
LOOP: {
|
||||||
for my $i ( 0 .. 19 ) {
|
for my $i ( 0 .. $max_key_items - 1 ) {
|
||||||
read $fh, $read, 2;
|
read $fh, $read, 2;
|
||||||
my $found_item = unpack 'v', $read;
|
my $found_item = unpack 'v', $read;
|
||||||
if ( $found_item == 0 ) {
|
if ( $found_item == 0 ) {
|
||||||
read $fh, $read, 2;
|
read $fh, $read, 2;
|
||||||
$result .= pack 'v', $item_id;
|
$result .= pack 'v', $item_id;
|
||||||
$result .= pack 'v', 1;
|
$result .= pack 'v', get_security_key($save) ^ 1;
|
||||||
last LOOP;
|
last LOOP;
|
||||||
}
|
}
|
||||||
$result .= $read;
|
$result .= $read;
|
||||||
read $fh, $read, 2;
|
read $fh, $read, 2;
|
||||||
my $quantity = unpack 'v', $read;
|
my $quantity = get_security_key($save) ^ (unpack 'v', $read);
|
||||||
$result .= $read;
|
$result .= $read;
|
||||||
if ( $found_item == $item_id ) {
|
if ( $found_item == $item_id ) {
|
||||||
warn "$item_id already present.";
|
warn "$item_id already present with $quantity.";
|
||||||
last LOOP;
|
last LOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -813,12 +891,12 @@ sub add_key_item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub get_var {
|
sub get_var {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
my $superdata = shift;
|
my $superdata = shift;
|
||||||
my $var = shift;
|
my $var = shift;
|
||||||
my $read_until = (($var - $VARS_START) * 2) + 0x1340;
|
my $read_until = ( ( $var - $VARS_START ) * 2 ) + 0x1340;
|
||||||
open my $fh, '<', $superdata;
|
open my $fh, '<', $superdata;
|
||||||
read $fh, (my $read), $read_until or die "Unable to read";
|
read $fh, ( my $read ), $read_until or die "Unable to read";
|
||||||
read $fh, $read, 2 or die "Unable to read";
|
read $fh, $read, 2 or die "Unable to read";
|
||||||
my $flag = unpack 'v', $read;
|
my $flag = unpack 'v', $read;
|
||||||
close $fh;
|
close $fh;
|
||||||
@ -826,15 +904,15 @@ sub get_var {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub set_var {
|
sub set_var {
|
||||||
my $save = shift;
|
my $save = shift;
|
||||||
my $superdata = shift;
|
my $superdata = shift;
|
||||||
my $var = shift;
|
my $var = shift;
|
||||||
my $value = shift;
|
my $value = shift;
|
||||||
die "$value bigger than 0xffff" if $value > 0xffff;
|
die "$value bigger than 0xffff" if $value > 0xffff;
|
||||||
my $read_until = (($var - $VARS_START) * 2) + 0x1340;
|
my $read_until = ( ( $var - $VARS_START ) * 2 ) + 0x1340;
|
||||||
my $result = shift;
|
my $result = shift;
|
||||||
open my $fh, '<', $superdata;
|
open my $fh, '<', $superdata;
|
||||||
read $fh, (my $read), $read_until or die "Unable to read";
|
read $fh, ( my $read ), $read_until or die "Unable to read";
|
||||||
$result .= $read;
|
$result .= $read;
|
||||||
read $fh, $read, 2 or die "Unable to read";
|
read $fh, $read, 2 or die "Unable to read";
|
||||||
$result .= pack 'v', $value;
|
$result .= pack 'v', $value;
|
||||||
@ -848,8 +926,13 @@ sub set_flag_id {
|
|||||||
my $superdata = shift;
|
my $superdata = shift;
|
||||||
my $id = shift;
|
my $id = shift;
|
||||||
my $to_set = shift;
|
my $to_set = shift;
|
||||||
my $offset = int( $id / 8 ) + $FLAGS_OFFSET;
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
my $result = '';
|
my $version = $section0->{version};
|
||||||
|
my $offset = int( $id / 8 ) + $FLAGS_OFFSET_RUBY;
|
||||||
|
if ( _is_leafgreen_or_firered($version) ) {
|
||||||
|
$offset = (int $id / 8 ) + $FLAGS_OFFSET_FIRERED;
|
||||||
|
}
|
||||||
|
my $result = '';
|
||||||
open my $fh, '<', $superdata;
|
open my $fh, '<', $superdata;
|
||||||
read $fh, my ($read), $offset;
|
read $fh, my ($read), $offset;
|
||||||
$result .= $read;
|
$result .= $read;
|
||||||
@ -871,7 +954,13 @@ sub check_flag_id {
|
|||||||
my $save = shift;
|
my $save = shift;
|
||||||
my $superdata = shift;
|
my $superdata = shift;
|
||||||
my $id = shift;
|
my $id = shift;
|
||||||
my $offset = int( $id / 8 ) + $FLAGS_OFFSET;
|
my $section0 = _find_section_save( $save, 0 );
|
||||||
|
my $version = $section0->{version};
|
||||||
|
|
||||||
|
my $offset = int( $id / 8 ) + $FLAGS_OFFSET_RUBY;
|
||||||
|
if ( _is_leafgreen_or_firered($version) ) {
|
||||||
|
$offset = int ($id / 8 ) + $FLAGS_OFFSET_FIRERED;
|
||||||
|
}
|
||||||
|
|
||||||
my $flags_offset = unpack "x@{[$offset]} C", ${$superdata};
|
my $flags_offset = unpack "x@{[$offset]} C", ${$superdata};
|
||||||
return ( $flags_offset >> ( $id & 7 ) ) & 1;
|
return ( $flags_offset >> ( $id & 7 ) ) & 1;
|
||||||
@ -979,21 +1068,53 @@ sub _print_sections_debug {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _is_ruby_or_sapphire {
|
||||||
|
my $version = shift;
|
||||||
|
return 1 if $version == $SAPPHIRE_VERSION;
|
||||||
|
return 1 if $version == $RUBY_VERSION;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _is_emerald {
|
||||||
|
my $version = shift;
|
||||||
|
return 1 if $version == $EMERALD_VERSION;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _is_leafgreen_or_firered {
|
||||||
|
my $version = shift;
|
||||||
|
return 1 if $version == $FIRERED_VERSION;
|
||||||
|
return 1 if $version == $LEAFGREEN_VERSION;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _is_supported_version {
|
||||||
|
my $version = shift;
|
||||||
|
return 1
|
||||||
|
if _is_emerald($version)
|
||||||
|
|| _is_ruby_or_sapphire($version)
|
||||||
|
|| _is_leafgreen_or_firered($version);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sub get_saves {
|
sub get_saves {
|
||||||
my @saves_raw = @_;
|
my @saves_raw = @_[ 0, 1 ];
|
||||||
|
my $version = $_[2] // $RUBY_VERSION;
|
||||||
|
die "Version not supported" if !_is_supported_version($version);
|
||||||
my @saves;
|
my @saves;
|
||||||
for my $save_raw (@saves_raw) {
|
for my $save_raw (@saves_raw) {
|
||||||
push @saves, _get_sections($save_raw);
|
push @saves, _get_sections( $save_raw, $version );
|
||||||
}
|
}
|
||||||
return @saves;
|
return @saves;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _get_sections {
|
sub _get_sections {
|
||||||
my $content = shift;
|
my $content = shift;
|
||||||
|
my $version = shift;
|
||||||
my $sections = [];
|
my $sections = [];
|
||||||
for ( 0 .. 13 ) {
|
for ( 0 .. 13 ) {
|
||||||
my $section;
|
my $section;
|
||||||
( $content, $section ) = _get_section($content);
|
( $content, $section ) = _get_section( $content, $version );
|
||||||
push @$sections, $section;
|
push @$sections, $section;
|
||||||
}
|
}
|
||||||
return $sections;
|
return $sections;
|
||||||
@ -1001,6 +1122,7 @@ sub _get_sections {
|
|||||||
|
|
||||||
sub _get_section {
|
sub _get_section {
|
||||||
my $content = shift;
|
my $content = shift;
|
||||||
|
my $version = shift;
|
||||||
my $data = substr $content, 0, $SECTION_DATA_SIZE;
|
my $data = substr $content, 0, $SECTION_DATA_SIZE;
|
||||||
$content = substr $content, $SECTION_AFTER_DATA_PADDING;
|
$content = substr $content, $SECTION_AFTER_DATA_PADDING;
|
||||||
my $section_id = substr $content, 0, $SECTION_ID_SIZE;
|
my $section_id = substr $content, 0, $SECTION_ID_SIZE;
|
||||||
@ -1020,6 +1142,7 @@ sub _get_section {
|
|||||||
checksum => unpack( 'v', $checksum ),
|
checksum => unpack( 'v', $checksum ),
|
||||||
id => unpack( 'v', $section_id ),
|
id => unpack( 'v', $section_id ),
|
||||||
data => $data,
|
data => $data,
|
||||||
|
version => $version,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
1636
lib/Rsaves/Constants/Firered/Flags.pm
Normal file
1636
lib/Rsaves/Constants/Firered/Flags.pm
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user