GEmeTool/lib/GEmeTool/Save/Pokemon.pm

211 lines
4.9 KiB
Perl

package GEmeTool::Save::Pokemon;
use v5.16.3;
use strict;
use warnings;
use Moo;
use Rsaves;
use Rsaves::Constants::Emerald::Species;
use Rsaves::Constants::Emerald::SpeciesData;
has _pokemon => ( is => 'rw', );
sub species {
my $self = shift;
my $arg = shift;
my $pokemon = $self->_pokemon;
my $substruct_0 = $pokemon->{substructures}[0];
if (defined $arg) {
$substruct_0->{species} = $arg;
}
return $substruct_0->{species};
}
sub level {
my $self = shift;
my $arg = shift;
if ( defined $arg ) {
die 'Not implemented';
}
my $pokemon = $self->_pokemon;
my $experience = $pokemon->{substructures}[0]{experience};
my $growth_func = sub {
my $n = shift;
if ($n == 1) {
return 1;
}
return $self->growth_function->($n);
};
my $level = 1;
while ($level <= 100 && int($growth_func->($level)) <= $experience) {
$level++;
}
$level -= 1;
return $level;
}
sub growth_function {
my $self = shift;
my $growth = $self->growth;
if ($growth eq 'GROWTH_FAST') {
return \&_exp_fast;
}
if ($growth eq 'GROWTH_MEDIUM_FAST') {
return \&_exp_medium_fast;
}
if ($growth eq 'GROWTH_MEDIUM_SLOW') {
return \&_exp_medium_slow;
}
if ($growth eq 'GROWTH_SLOW') {
return \&_exp_slow;
}
if ($growth eq 'GROWTH_ERRATIC') {
return \&_exp_erratic;
}
if ($growth eq 'GROWTH_FLUCTUATING') {
return \&_exp_fluctuating;
}
}
sub gender_ratio {
my $self = shift;
my $pokemon_name = $self->pokemon_name;
my %pokemon_data = %Rsaves::Constants::Emerald::SpeciesData::SPECIES_DATA;
my $data = $pokemon_data{$pokemon_name};
my $gender_ratio = $data->{gender_ratio};
return $gender_ratio;
}
sub gender {
# 0 male
# 1 female
# 2 genderless
my $self = shift;
my $gender_ratio = $self->gender_ratio;
my $pokemon = $self->_pokemon;
my $personality = $pokemon->{personality};
if ($gender_ratio == 0) {
return 0;
}
if ($gender_ratio == 254) {
return 1;
}
if ($gender_ratio == 255) {
return 2;
}
if ($gender_ratio <= ($personality & 0xff)) {
return 0;
}
return 1;
}
sub growth {
my $self = shift;
my $pokemon_name = $self->pokemon_name;
my %pokemon_data = %Rsaves::Constants::Emerald::SpeciesData::SPECIES_DATA;
my $data = $pokemon_data{$pokemon_name};
return $data->{growth_rate};
}
sub _square {
return $_[0]**2;
}
sub _cube {
return $_[0]**3;
}
sub _exp_slow {
my $n = shift;
return ( 5 * _cube($n) ) / 4;
}
sub _exp_fast {
my $n = shift;
return ( 4 * _cube($n) ) / 5;
}
sub _exp_medium_fast {
return _cube( $_[0] );
}
sub _exp_medium_slow {
my $n = shift;
#define EXP_MEDIUM_SLOW(n)((6 * CUBE(n)) / 5 - (15 * SQUARE(n)) + (100 * n) - 140) // (6 * (n)^3) / 5 - (15 * (n)^2) + (100 * n) - 140
my $return = (
( 6 * _cube($n) ) / 5 - ( 15 * _square($n) ) + ( 100 * $n ) - 140 );
return $return;
}
sub _exp_erratic {
my $n = shift;
if ( $n <= 50 ) {
return ( ( 100 - $n ) * _cube($n) / 50 );
}
if ( $n <= 68 ) {
return ( ( 150 - $n ) * _cube($n) / 100 );
}
if ( $n <= 98 ) {
return ( ( 1911 - 10 * $n ) / 3 * _cube($n) / 500 );
}
return ( ( 160 - $n ) * _cube($n) / 100 );
}
sub _exp_fluctuating {
my $n = shift;
if ( $n <= 15 ) {
return ( ( ( $n + 1 ) / 3 + 24 ) * _cube($n) / 50 );
}
if ( $n <= 36 ) {
return ( ( $n + 14 ) * _cube($n) / 50 );
}
return ( ( ( $n / 2 ) + 32 ) * _cube($n) / 50 );
}
sub pokemon_name {
my $self = shift;
return $Rsaves::Constants::Emerald::Species::SPECIES[ $self->species ];
}
sub nickname {
my $self = shift;
my $arg = shift;
if ( defined $arg ) {
die "Invalid nickname" if length $arg != 10;
$self->_pokemon->{nickname} = $arg;
}
return $self->_pokemon->{nickname};
}
sub get_icon {
my $self = shift;
my $pokemon_name =
$Rsaves::Constants::Emerald::Species::SPECIES[ $self->species ];
if ( lc($pokemon_name) eq 'unown' ) {
return "pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/z/icon.png";
}
return "pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/icon.png";
}
sub get_front {
my $self = shift;
my $pokemon_name =
$Rsaves::Constants::Emerald::Species::SPECIES[ $self->species ];
if ( Rsaves::pokemon_is_shiny( $self->_pokemon ) ) {
return "resources/shiny/@{[lc($pokemon_name)]}.png";
}
if ( lc($pokemon_name) eq 'castform' ) {
return
"pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/normal/front.png";
}
if ( lc($pokemon_name) eq 'unown' ) {
return
"pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/z/front.png";
}
return "pokeemerald/graphics/pokemon/@{[lc($pokemon_name)]}/front.png";
}
1;