211 lines
4.9 KiB
Perl
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;
|