diff --git a/docs/OracleOfAnid.pod b/docs/OracleOfAnid.pod index 3e32e9fa..79953389 100644 --- a/docs/OracleOfAnid.pod +++ b/docs/OracleOfAnid.pod @@ -2,16 +2,16 @@ Oracle of Anid is accessible via the URL C. -The list of methods below represents changes and additions to the methods that all L share. +The list of methods below represents changes and additions to the methods that all L except that you can see the bodies even if there is no probe there. Therefore the same displays that you would have for the star and these bodies in the star map should work from this interface. Send a scow to a star, attack a player, send a mining platform, etc. +Retrieves info on a single star. Works like L Use L to look up the id of a star by name. +B records. + +=head3 page_size (optional) + +Defaults to a page size of 25, can have any value from 1 to 200 + +=head3 RESPONSE + + { + "status" : { ... }, + "stars" : [ + "id" : "id-goes-here", + "color" : "yellow", + "name" : "Sol", + "x" : 17, + "y" : 4, + "z" : -3, + "bodies" : [ + { See get_status() in Body }, + ... + ] + , + "star_count" : 5, + "max_distance" : 10, + } + +=cut diff --git a/lib/Lacuna/DB/Result/Building/Permanent/OracleOfAnid.pm b/lib/Lacuna/DB/Result/Building/Permanent/OracleOfAnid.pm index 91840190..ff80c9df 100644 --- a/lib/Lacuna/DB/Result/Building/Permanent/OracleOfAnid.pm +++ b/lib/Lacuna/DB/Result/Building/Permanent/OracleOfAnid.pm @@ -2,6 +2,9 @@ package Lacuna::DB::Result::Building::Permanent::OracleOfAnid; use Moose; use utf8; +use Data::Dumper; + + no warnings qw(uninitialized); extends 'Lacuna::DB::Result::Building::Permanent'; @@ -17,15 +20,85 @@ sub image_level { return $self->image.'1'; } +sub probes { + my $self = shift; + return Lacuna->db->resultset('Probes')->search_oracle; +} + after finish_upgrade => sub { my $self = shift; + + $self->recalc_probes; $self->body->add_news(30, sprintf('A warning to all enemies foreign and domestic. The government of %s sees all.', $self->body->name)); }; +before demolish => sub { + my $self = shift; + + $self->probes->delete_all; +}; + +after update => sub { + my $self = shift; + + $self->recalc_probes; +}; + +sub range { + my ($self) = @_; + + my $range = $self->level * 1000 * $self->efficiency / 100; + +} + use constant name => 'Oracle of Anid'; use constant time_to_build => 0; use constant max_instances_per_planet => 1; +# recalculate all of the virtual probes +# +sub recalc_probes { + my ($self) = @_; + + # It's easier to delete all the virtual probes, then recreate them. + $self->probes->delete_all; + + my $range = $self->range / 100; + + # get all stars within this range + my $minus_x = 0 - $self->body->x; + my $minus_y = 0 - $self->body->y; + my $stars = Lacuna->db->resultset('Map::Star')->search({ + -and => [ + \[ "ceil(pow(pow(me.x + $minus_x, 2) + pow(me.y + $minus_y, 2), 0.5)) <= $range"], + ], + },{ + '+select' => [ + { ceil => \"pow(pow(me.x + $minus_x,2) + pow(me.y + $minus_y,2), 0.5)", '-as' => 'distance' }, + ], + '+as' => [ + 'distance', + ], + order_by => 'distance', + }); + print STDERR "THERE ARE [".$stars->count."] STARS IN RANGE\n"; + + # Add a virtual probe at each star + my $body = $self->body; + if ($body->empire_id) { + my $empire = $body->empire; + while (my $star = $stars->next) { + Lacuna->db->resultset('Probes')->new({ + empire_id => $empire->id, + star_id => $star->id, + body_id => $body->id, + alliance_id => $empire->alliance_id, + virtual => 1, + })->insert; + } + } +} no Moose; __PACKAGE__->meta->make_immutable(inline_constructor => 0); + diff --git a/lib/Lacuna/DB/Result/Map/Body/Planet.pm b/lib/Lacuna/DB/Result/Map/Body/Planet.pm index f53c5d28..e063a0e0 100644 --- a/lib/Lacuna/DB/Result/Map/Body/Planet.pm +++ b/lib/Lacuna/DB/Result/Map/Body/Planet.pm @@ -726,6 +726,16 @@ has embassy => ( }, ); +has oracle => ( + is => 'rw', + lazy => 1, + default => sub { + my $self = shift; + my $building = $self->get_building_of_class('Lacuna::DB::Result::Building::Permanent::OracleOfAnid'); + return $building; + }, +); + sub is_space_free { my ($self, $unclean_x, $unclean_y) = @_; my $x = int( $unclean_x ); @@ -918,8 +928,6 @@ sub get_existing_build_queue_time { my $self = shift; my ($building) = @{$self->builds(1)}; -#print STDERR "GET_EXISTING_BUILD_QUEUE_TIME: building=[$building]\n"; - return (defined $building) ? $building->upgrade_ends : DateTime->now; } diff --git a/lib/Lacuna/RPC/Building/OracleOfAnid.pm b/lib/Lacuna/RPC/Building/OracleOfAnid.pm index 35d4ddc9..e6db6b74 100644 --- a/lib/Lacuna/RPC/Building/OracleOfAnid.pm +++ b/lib/Lacuna/RPC/Building/OracleOfAnid.pm @@ -21,13 +21,42 @@ sub get_star { unless (defined $star) { confess [1002, "Couldn't find a star."]; } - unless ($building->body->calculate_distance_to_target($star) < $building->level * 1000) { + unless ($building->body->calculate_distance_to_target($star) < $building->range) { confess [1009, 'That star is too far away.']; } return { star=>$star->get_status($empire, 1), status=>$self->format_status($empire, $building->body) }; } -__PACKAGE__->register_rpc_method_names(qw(get_star)); +sub get_probed_stars { + my ($self, $args) = @_; + + my $page_number = $args->{page_number} || 1; + my $page_size = $args->{page_size} || 25; + + if ($page_size > 200) { + confess [1002, "Page size cannot exceed 200."]; + } + + my $empire = $self->get_empire_by_session($args->{session_id}); + my $building = $self->get_building($empire, $args->{building_id}); + + my @stars; + my $probes = $building->probes->search(undef,{ rows => $page_size, page => $page_number }); + while (my $probe = $probes->next) { + push @stars, $probe->star->get_status($empire); + } + return { + stars => \@stars, + star_count => $probes->pager->total_entries, + status => $self->format_status($empire, $building->body), + max_distance => $building->level * 10, + }; +} + +__PACKAGE__->register_rpc_method_names(qw( + get_star + get_probed_stars +)); no Moose; diff --git a/t/560_oracle.t b/t/560_oracle.t new file mode 100644 index 00000000..60417cc3 --- /dev/null +++ b/t/560_oracle.t @@ -0,0 +1,30 @@ +use lib '../lib'; +use Test::More tests => 14; +use Test::Deep; +use Data::Dumper; +use 5.010; +use DateTime; + +use TestHelper; + +my $tester = TestHelper->new({empire_name => 'icydee'}); + +$tester->use_existing_test_empire; +diag("tester = [$tester]"); + +my $session_id = $tester->session->id; +my $empire = $tester->empire; +my $home = $empire->home_planet; + +my $oracle = $home->oracle; +isnt($oracle, undef, "Planet has an oracle"); + +$result = $tester->post('oracleofanid', 'get_probed_stars', [{ + session_id => $session_id, + building_id => $oracle->id, + page_size => 2, + page_number => 1, +}]); + + +