Initial personality tuning support.

This commit is contained in:
Sergiotarxz 2024-03-09 21:03:09 +01:00
parent 34a41d74c2
commit 899f783cbb
3 changed files with 152 additions and 5 deletions

View File

@ -84,9 +84,9 @@ sub gender {
# 1 female
# 2 genderless
my $self = shift;
my $gender_ratio = $self->gender_ratio;
my $pokemon = $self->_pokemon;
my $personality = $pokemon->{personality};
my $personality = shift // $pokemon->{personality};
my $gender_ratio = $self->gender_ratio;
if ($gender_ratio == 0) {
return 0;
}
@ -102,6 +102,16 @@ sub gender {
return 1;
}
sub personality {
my $self = shift;
my $arg = shift;
my $pokemon = $self->_pokemon;
if (defined $arg) {
$self->_pokemon->{personality} = $arg;
}
return $pokemon->{personality};
}
sub growth {
my $self = shift;
my $pokemon_name = $self->pokemon_name;
@ -190,6 +200,52 @@ sub get_icon {
return "pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/icon.png";
}
sub generate_personality {
my $self = shift;
my $target_shiny = shift;
my $target_gender = shift;
my $target_nature = shift;
my $otid = $self->otid;
my $should_search_gender = 0;
my $personality;
if (defined $target_gender && !(grep {$self->gender_ratio eq $_} (0, 254, 255))) {
$should_search_gender = 1;
}
if (defined $target_gender && $target_gender != 0 && $target_gender != 1) {
die "Incorrect gender $target_gender.";
}
if (defined $target_nature && ($target_nature < 0 || $target_nature > 24)) {
die "Incorrect nature $target_nature.";
}
for (my $i = 0; $i < 0xffffffff; $i++) {
if (defined $target_nature && $i % 25 != $target_nature) {
next;
}
if (defined $target_shiny && !(!!$target_shiny == !!Rsaves::is_shiny($otid, $i))) {
next;
}
if ($should_search_gender && $self->gender($i) != $target_gender) {
next;
}
$personality = $i;
last;
}
if (!defined $personality) {
warn "Could not find personality combination, this is a bug.";
}
return $personality;
}
sub otid {
my $self = shift;
my $arg = shift;
my $pokemon = $self->_pokemon;
if (defined $arg) {
$pokemon->{otid} = $arg;
}
return $pokemon->{otid};
}
sub get_front {
my $self = shift;
my $pokemon_name =

View File

@ -38,6 +38,8 @@ has _selected_species => ( is => 'rw', );
has _save_callbacks => ( is => 'rw', default => sub { [] } );
has _current_personality => ( is => 'rw' );
my $root = path(__FILE__)->parent->parent->parent->parent;
my $width = 600;
my $height = 400;
@ -64,6 +66,7 @@ sub draw {
my $pokemon = $self->pokemon;
$window->set_title( 'Editing Pokémon '
. Rsaves::translate_3rd_encoding( $pokemon->nickname ) );
$self->_current_personality($pokemon->personality);
my $grid = Gtk4::Grid->new;
$grid->set_column_homogeneous(1);
my $canvas = Gtk4::DrawingArea->new;
@ -85,7 +88,7 @@ sub draw {
$cairo->paint;
}
);
$grid->attach( $canvas, 0, 0, 2, 2 );
$grid->attach( $canvas, 0, 0, 2, 4 );
my @species = (@Rsaves::Constants::Emerald::Species::SPECIES);
my $string_list = Gtk4::StringList->new( [@species] );
my $save_button = Gtk4::Button->new_with_label('Save changes');
@ -94,6 +97,7 @@ sub draw {
$save_button->signal_connect(
clicked => sub {
$pokemon->species( $self->_selected_species );
$pokemon->personality($self->_current_personality);
for my $func (@{$self->_save_callbacks}) {
$func->();
}
@ -101,10 +105,90 @@ sub draw {
}
);
$self->draw_dropdown_pokemon_list($grid);
$grid->attach( $save_button, 6, 6, 1, 1 );
$self->create_modify_personality($grid);
$grid->attach( $save_button, 12, 7, 1, 1 );
$window->set_child($grid);
}
sub create_modify_personality {
my $self = shift;
my $grid = shift;
my $button = Gtk4::Button->new_with_label('Edit personality');
$button->signal_connect(clicked => sub {
$self->open_window_personality;
});
$button->set_valign('start');
$button->set_halign('start');
$grid->attach($button, 2, 2, 1, 1);
}
sub open_window_personality {
my $self = shift;
my $window = Gtk4::Window->new;
my $box_window = Gtk4::Box->new('vertical', 1);
$box_window->append(Gtk4::Label->new('Select shiny'));
my $box_shiny = Gtk4::Box->new('horizontal', 1);
my $shiny_dont_mind = Gtk4::ToggleButton->new_with_label('Do not matter');
my $shiny_yes = Gtk4::ToggleButton->new_with_label('Yes');
my $shiny_no = Gtk4::ToggleButton->new_with_label('No');
$shiny_dont_mind->set_active(1);
$shiny_yes->set_group($shiny_dont_mind);
$shiny_no->set_group($shiny_dont_mind);
$box_shiny->append($shiny_dont_mind);
$box_shiny->append($shiny_yes);
$box_shiny->append($shiny_no);
$box_window->append($box_shiny);
$box_window->append(Gtk4::Label->new('Select gender'));
my $box_gender = Gtk4::Box->new('horizontal', 1);
my $gender_dont_mind = Gtk4::ToggleButton->new_with_label('Do not matter');
my $gender_male = Gtk4::ToggleButton->new_with_label('Male');
my $gender_female = Gtk4::ToggleButton->new_with_label('Female');
$gender_female->set_group($gender_male);
$gender_dont_mind->set_group($gender_male);
$gender_dont_mind->set_active(1);
$box_gender->append($gender_dont_mind);
$box_gender->append($gender_male);
$box_gender->append($gender_female);
$box_window->append($box_gender);
my $button_generate = Gtk4::Button->new_with_label('Generate personality');
$button_generate->signal_connect(clicked => sub {
my @gender_buttons = ($gender_male, $gender_female);
my $target_shiny = undef;
my $target_gender = undef;
if ($shiny_yes->get_active) {
$target_shiny = 1;
}
if ($shiny_no->get_active) {
$target_shiny = 0;
}
for my $i (0..1) {
if ($gender_buttons[$i]->get_active) {
$target_gender = $i;
last;
}
}
my $personality = $self->pokemon->generate_personality($target_shiny, $target_gender);
if (defined $personality) {
$self->_current_personality($personality);
}
$window->close;
});
$box_window->append($button_generate);
$window->set_child($box_window);
$window->present;
}
sub create_change_nickname_entry {
my $self = shift;
my $grid = shift;
@ -124,6 +208,8 @@ sub create_change_nickname_entry {
my $translated_nickname = Rsaves::to_3rd_encoding($entry->get_buffer->get_text);
if ( length $translated_nickname < 10 ) {
$translated_nickname .= chr(0xff);
my $length = length $translated_nickname;
$translated_nickname .= (chr(0x00)) x (10 - $length);
}
if ( length $translated_nickname > 10 ) {
$translated_nickname = substr $translated_nickname, 0, 10;

View File

@ -144,7 +144,12 @@ sub calculate_shiny_personality {
sub pokemon_is_shiny {
my $pokemon = shift;
my ($otid, $personality) = @{$pokemon}{ 'otid', 'personality' };
return is_shiny(@{$pokemon}{ 'otid', 'personality' });
}
sub is_shiny {
my $otid = shift;
my $personality = shift;
return ( _lowhalf_u32($personality) ^ _hihalf_u32($personality)
^ _lowhalf_u32($otid) ^ _hihalf_u32($otid) ) < 8;
}