LasTres/lib/LasTres/Schema/Result/Team.pm

250 lines
5.8 KiB
Perl

package LasTres::Schema::Result::Team;
use v5.36.0;
use strict;
use warnings;
use utf8;
use parent 'DBIx::Class::Core';
use LasTres::Location;
use JSON qw/to_json from_json/;
use Carp qw/cluck/;
use Moo;
__PACKAGE__->table('teams');
__PACKAGE__->add_columns(
uuid => {
data_type => 'uuid',
is_nullable => 0,
},
is_exploring => {
data_type => 'boolean',
is_nullable => 0,
default_value => \'false',
},
action_frame => {
data_type => 'integer',
is_nullable => 0,
default_value => \'0',
},
is_moving => {
data_type => 'boolean',
is_nullable => 0,
default_value => \'false',
},
last_spawn => {
data_type => 'jsonb',
is_nullable => 0,
default_value => \'\'null\'',
},
moving_to => {
data_type => 'jsonb',
is_nullable => 0,
default_value => \'\'null\'',
},
leader => {
data_type => 'uuid',
is_nullable => 1,
is_foreign_key => 1,
},
name => {
data_type => 'text',
is_nullable => 0,
},
planet => {
data_type => 'text',
is_nullable => 0,
accessor => '_planet',
},
super_area => {
data_type => 'text',
is_nullable => 0,
accessor => '_super_area',
},
area => {
data_type => 'text',
is_nullable => 0,
accessor => '_area',
},
location => {
data_type => 'text',
is_nullable => 0,
accessor => '_location',
},
current_battle => {
data_type => 'uuid',
is_nullable => 1,
},
);
sub append_log_line ( $self, $line ) {
for my $member ( $self->combat_members->@* ) {
$member->append_log_line($line);
}
}
sub is_defeated ($self) {
$self = $self->get_from_storage;
my @members = $self->members;
my @alive_members = grep { $_->health > 0 } @members;
if ( !scalar @alive_members ) {
return 1;
}
return 0;
}
sub combat_members_serializable ( $self, $pj = undef ) {
my @team_members = $self->members;
if ( defined $pj ) {
@team_members = grep { $pj->uuid ne $_->uuid } @team_members;
@team_members = ( $pj, @team_members );
}
my $team_pjs = [ map { $_->hash } (@team_members) ];
return $team_pjs;
}
sub on_win_combat ($self) {
}
sub on_blackout ($self) {
for my $pj ( $self->members ) {
$pj->append_log_line(
[
{
text =>
'No queda nadie en el equipo que pueda luchar, volvéis al último punto de aparición.'
}
]
);
}
require LasTres::Redis;
my $redis = LasTres::Redis->new;
my $last_spawn = $self->get_spawn;
$last_spawn->place_team($self);
$self->is_moving(0);
$self->moving_to('null');
for my $member ( $self->combat_members->@* ) {
$member->health( $member->max_health );
$member->mana( $member->max_mana );
$member->update;
}
$self->update;
for my $pj ( $self->members ) {
$pj->update_team_sprites;
$pj->update_location;
$pj->update_actions;
}
}
sub on_lose_combat ($self) {
$self->on_blackout;
}
sub update ($self) {
return $self->SUPER::update();
}
sub get_spawn ($self) {
my $location;
eval {
$location =
LasTres::Location::get( @{ from_json( $self->last_spawn ) } );
};
if ($@) {
$location = $self->leader->race->spawn;
}
return $location;
}
sub start_random_combat ($self) {
$self = $self->get_from_storage;
my $location = $self->location;
my $area = $location->to_array->[2];
}
# May throw error, it is needed to handle.
sub location {
my $self = shift;
my $location = shift;
my $planet;
my $super_area;
my $area;
if ( defined $location ) {
$self->_location( $location->identifier );
$area = $location->parent;
$self->_area( $area->identifier );
$super_area = $area->parent;
$self->_super_area( $super_area->identifier );
$planet = $super_area->parent;
$self->_planet( $planet->identifier );
}
$location = $self->_location;
$area = $self->_area;
$super_area = $self->_super_area;
$planet = $self->_planet;
$location =
LasTres::Location::get( $planet, $super_area, $area, $location );
return $location;
}
sub send_frame_to_members ($self) {
require LasTres::Redis;
my $redis = LasTres::Redis->new;
$self = $self->get_from_storage;
for my $pj ( $self->members ) {
$redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'show-frame' } ) );
}
}
sub combat_members ($self) {
$self = $self->get_from_storage;
my @members = $self->members;
# Add friendly NPCs here when implemented.
return [@members];
}
sub on_end_combat ($self) {
require LasTres::Redis;
my $redis = LasTres::Redis->new;
for my $pj ( $self->members ) {
$pj->update_team_sprites;
$pj->update_location;
$pj->update_actions;
}
}
sub to_serializable ($self) {
return {
is_db => $JSON::true,
uuid => $self->uuid,
};
}
sub from_serializable ( $class, $hash ) {
require LasTres::Schema;
my $schema = LasTres::Schema->Schema;
my $resultset = $schema->resultset('Team');
if ( !$hash->{is_db} ) {
die 'This is not a database Team.';
}
my @teams = $resultset->search( { uuid => $hash->{uuid} } );
if ( !@teams ) {
die 'This team does not exists.';
}
return $teams[0];
}
__PACKAGE__->set_primary_key('uuid');
__PACKAGE__->has_many( 'members', 'LasTres::Schema::Result::PJ', 'team' );
__PACKAGE__->belongs_to( 'leader', 'LasTres::Schema::Result::PJ' );
with 'LasTres::CombatCapableTeam';
1;