File Coverage

blib/lib/Games/Lacuna/Task/Action/Astronomy.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Games::Lacuna::Task::Action::Astronomy;
2              
3 1     1   1793 use 5.010;
  1         4  
  1         53  
4             our $VERSION = $Games::Lacuna::Task::VERSION;
5              
6 1     1   621 use Moose;
  0            
  0            
7             extends qw(Games::Lacuna::Task::Action);
8             with qw(Games::Lacuna::Task::Role::Stars
9             Games::Lacuna::Task::Role::Ships
10             Games::Lacuna::Task::Role::PlanetRun
11             Games::Lacuna::Task::Role::RPCLimit);
12              
13             sub description {
14             return q[Explore solar systems in your vincity];
15             }
16              
17             before 'run' => sub {
18             my $self = shift;
19             $self->check_for_destroyed_probes();
20             };
21              
22             sub process_planet {
23             my ($self,$planet_stats) = @_;
24            
25             # Get observatory
26             my $observatory = $self->find_building($planet_stats->{id},'Observatory');
27            
28             # Get space port
29             my $spaceport = $self->find_building($planet_stats->{id},'SpacePort');
30            
31             return
32             unless $observatory && $spaceport;
33            
34             # Max probes controllable
35             my $max_probes = $observatory->{level} * 3;
36            
37             # Get observatory probed stars
38             my $observatory_object = $self->build_object($observatory);
39             my $observatory_data = $self->request(
40             object => $observatory_object,
41             method => 'get_probed_stars',
42             params => [1],
43             );
44            
45             my $can_send_probes = $max_probes - $observatory_data->{star_count};
46            
47             # Reached max probed stars
48             return
49             if $can_send_probes <= 0;
50            
51             # Get available probes
52             my @avaliable_probes = $self->get_ships(
53             planet => $planet_stats,
54             quantity => $can_send_probes,
55             type => 'probe',
56             travelling => 1,
57             );
58            
59             return
60             if (scalar @avaliable_probes == 0);
61            
62            
63             my $spaceport_object = $self->build_object($spaceport);
64            
65             # Get unprobed stars
66             my @unprobed_stars = $self->closest_unprobed_stars($planet_stats->{x},$planet_stats->{y},scalar(@avaliable_probes));
67            
68             # Send available probes to stars
69             STARS:
70             foreach my $star (@unprobed_stars) {
71             my $probe = pop(@avaliable_probes);
72             if (defined $probe) {
73             # Send probe to star
74             my $response = $self->request(
75             object => $spaceport_object,
76             method => 'send_ship',
77             params => [ $probe,{ "star_id" => $star } ],
78             catch => [
79             [1009,sub {
80             return;
81             }]
82             ]
83             );
84            
85             last STARS
86             unless defined $response;
87            
88             $self->log('notice',"Sending probe from from %s to %s",$planet_stats->{name},$response->{ship}{to}{name});
89             }
90             }
91             }
92              
93             sub check_for_destroyed_probes {
94             my ($self) = @_;
95            
96             my $inbox_object = $self->build_object('Inbox');
97            
98             # Get inbox for attacks
99             my $inbox_data = $self->request(
100             object => $inbox_object,
101             method => 'view_inbox',
102             params => [{ tags => ['Attack','Probe'],page_number => 1 }],
103             );
104            
105             my @archive_messages;
106            
107             foreach my $message (@{$inbox_data->{messages}}) {
108             next
109             unless $message->{from_id} == $message->{to_id};
110            
111             if ($message->{subject} ~~ ['Probe Destroyed','Lost Contact With Probe']) {
112             # Get message
113             my $message_data = $self->request(
114             object => $inbox_object,
115             method => 'read_message',
116             params => [$message->{id}],
117             );
118            
119             # Parse star id,x,y
120             next
121             unless $message_data->{message}{body} =~ m/\{Starmap\s(?<x>-*\d+)\s(?<y>-*\d+)\s(?<star_name>[^}]+)\}/;
122            
123             my $star_name = $+{star_name};
124             my $star_data = $self->get_star_by_xy($+{x},$+{y});
125            
126             next
127             unless $star_data;
128             next
129             unless $message_data->{message}{body} =~ m/{Empire\s(?<empire_id>\d+)\s(?<empire_name>[^}]+)}/;
130            
131             $self->log('warn','A probe in the %s system was destroyed by %s',$star_name,$+{empire_name});
132            
133             # Fetch star data from api and check if solar system is still probed
134             $self->_get_star_api($star_data->{id},$star_data->{x},$star_data->{y});
135            
136             push(@archive_messages,$message->{id});
137             }
138             }
139            
140             # Archive
141             if (scalar @archive_messages) {
142             $self->log('notice',"Archiving %i messages",scalar @archive_messages);
143            
144             $self->request(
145             object => $inbox_object,
146             method => 'archive_messages',
147             params => [\@archive_messages],
148             );
149             }
150             }
151              
152             sub closest_unprobed_stars {
153             my ($self,$x,$y,$limit) = @_;
154            
155             $limit //= 1;
156            
157             my @unprobed_stars;
158            
159             $self->log('debug','Trying to find %i unprobed solar systems',$limit);
160            
161             my $count = 0;
162            
163             $self->search_stars_callback(
164             sub {
165             my ($star_data) = @_;
166            
167             # Fetch star data from api and check if solar system is still unprobed
168             $star_data = $self->_get_star_api($star_data->{id},$star_data->{x},$star_data->{y});
169            
170             next
171             if $star_data->{is_probed};
172            
173             # Get incoming probe info
174             my $star_incomming = $self->request(
175             object => $self->build_object('Map'),
176             params => [ $star_data->{id} ],
177             method => 'check_star_for_incoming_probe',
178             );
179            
180             return 1
181             if (defined $star_incomming->{incoming_probe}
182             && $star_incomming->{incoming_probe} ne '0');
183            
184             # Add to todo list
185             push(@unprobed_stars,$star_data->{id});
186            
187             return 0
188             if scalar(@unprobed_stars) >= $limit;
189            
190             return 1;
191             },
192             x => $x,
193             y => $y,
194             is_probed => 0,
195             distance => 1,
196             );
197              
198             return @unprobed_stars;
199             }
200              
201             __PACKAGE__->meta->make_immutable;
202             no Moose;
203             1;