LasTres/lib/LasTres/CombatCapableEntity.pm

231 lines
7.1 KiB
Perl

package LasTres::CombatCapableEntity;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo::Role;
use JSON qw/to_json from_json/;
requires(
'uuid', 'race_string', 'nick', 'born_stats',
'health', 'mana', 'training_stats', 'experience',
'combat_action', 'combat_target', 'team',
'gain_experience', 'get_from_storage',
);
## OVERRIDE
sub update_location {
}
## OVERRIDE
sub update_actions {
}
## OVERRIDE
sub append_log_line {
}
## OVERRIDE
sub update_team_sprites {
}
sub race ($self) {
my $hash;
$hash = LasTres::Races->new->hash;
if ( $self->isa('LasTres::Schema::Result::PJ') ) {
$hash = LasTres::Races->new->hash_playable;
}
my $race = $hash->{ $self->race_string };
if ( !defined $race ) {
die "Not valid race for entity " . $self->uuid;
}
return $race;
}
## OVERRIDE (Call super)
sub update($self) {
$self = $self->get_from_storage;
if ( $self->health < 1 ) {
$self->on_faint;
}
}
sub attack ( $self, $enemy_entity ) {
my $defense = $enemy_entity->resistance;
my $attack = $self->strength;
my $level = $self->level;
# This should change with the different attacks.
my $power = 20;
my $damage = int(
( ( ( 2 * $level ) / 5 + 2 ) * $power * $attack / $defense ) / 50 + 2 );
my $final_health = $enemy_entity->health - $damage;
if ( $final_health < 0 ) {
$final_health = 0;
}
$enemy_entity->health($final_health);
my $team1 = $self->team;
my $team2 = $enemy_entity->team;
require LasTres::Redis;
my $redis = LasTres::Redis->new;
for my $team ( $team1, $team2 ) {
next if !$team->isa('LasTres::Schema::Result::Team');
for my $pj ( $team->members ) {
$redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'update-team-sprites' } ) );
}
}
for my $member ( $team1->combat_members->@* ) {
$member->append_log_line(
[
{ color => 'green', text => "@{[$self->nick]}" },
{
text => ' atacó a '
},
{ color => 'red', text => "@{[$enemy_entity->nick]}" },
{
text => ". Le causó $damage puntos de daño, ",
},
{
text =>
"vida restante @{[$enemy_entity->health]}/@{[$enemy_entity->max_health]}."
}
]
);
}
for my $member ( $team2->combat_members->@* ) {
$member->append_log_line(
[
{ color => 'red', text => "@{[$self->nick]}" },
{
text => ' atacó a '
},
{ color => 'green', text => "@{[$enemy_entity->nick]}" },
{
text => ". Le causó $damage puntos de daño, ",
},
{
text =>
"vida restante @{[$enemy_entity->health]}/@{[$enemy_entity->max_health]}."
}
]
);
}
$enemy_entity->update;
}
sub on_faint($self) {
my $team2 = $self->team;
for my $member ( $team2->combat_members->@* ) {
$member->append_log_line(
[
{ color => 'green', text => "@{[$self->nick]}" },
{ text => " se ha debilitado." },
]
);
}
my $battle = $team2->battle;
if (!defined $battle) {
return;
}
my $team1 = $battle->get_enemy_team($team2);
for my $member ( $team1->combat_members->@* ) {
$member->append_log_line(
[
{ color => 'red', text => "@{[$self->nick]}" },
{ text => " se ha debilitado." },
]
);
$member->gain_experience((($self->race->experience_drop_base * $self->level)/7));
}
}
sub level ($self) {
# Floating point trick, works in level 100,
# for upper levels maybe it may need adjusting.
return int( $self->experience**( 1 / 3 ) + 0.0000000000001 );
}
sub max_health ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $health_base_race = $race->base_stats->health;
my $health_born = $self->born_stats->health;
my $health_training = $self->training_stats->health;
my $health_mix =
2 * $health_base_race + $health_born + ( $health_training / 4 );
my $health_scaled = ( ( $health_mix * $self->level ) / 100 );
return int( $health_scaled + $self->level + 10 );
}
sub strength ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $strength_base_race = $race->base_stats->strength;
my $strength_born = $self->born_stats->strength;
my $strength_training = $self->training_stats->strength;
my $strength_mix =
2 * $strength_base_race + $strength_born + ( $strength_training / 4 );
my $strength_scaled = ( ( $strength_mix * $self->level ) / 100 );
return int( ( $strength_scaled + 5 ) * 1.1 );
}
sub speed ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $speed_base_race = $race->base_stats->speed;
my $speed_born = $self->born_stats->speed;
my $speed_training = $self->training_stats->speed;
my $speed_mix =
2 * $speed_base_race + $speed_born + ( $speed_training / 4 );
my $speed_scaled = ( ( $speed_mix * $self->level ) / 100 );
return int( ( $speed_scaled + 5 ) * 1.1 );
}
sub intelligence ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $intelligence_base_race = $race->base_stats->intelligence;
my $intelligence_born = $self->born_stats->intelligence;
my $intelligence_training = $self->training_stats->intelligence;
my $intelligence_mix =
2 * $intelligence_base_race +
$intelligence_born +
( $intelligence_training / 4 );
my $intelligence_scaled = ( ( $intelligence_mix * $self->level ) / 100 );
return int( ( $intelligence_scaled + 5 ) * 1.1 );
}
sub resistance ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $resistance_base_race = $race->base_stats->resistance;
my $resistance_born = $self->born_stats->resistance;
my $resistance_training = $self->training_stats->resistance;
my $resistance_mix =
2 * $resistance_base_race +
$resistance_born +
( $resistance_training / 4 );
my $resistance_scaled = ( ( $resistance_mix * $self->level ) / 100 );
return int( ( $resistance_scaled + 5 ) * 1.1 );
}
sub max_mana ($self) {
my $races = LasTres::Races->new;
my $race = $self->race;
my $mana_base_race = $race->base_stats->mana;
my $mana_born = $self->born_stats->mana;
my $mana_training = $self->training_stats->mana;
my $mana_mix = 2 * $mana_base_race + $mana_born + ( $mana_training / 4 );
my $mana_scaled = ( ( $mana_mix * $self->level ) / 100 );
return int( $mana_scaled + $self->level + 10 );
}
1;