From c1a6386614e331486eeb70bb666c6a4f392db55f Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 01/31] Started adding new fleet action API calls --- docs/SpacePort.pod | 289 +++++++++++++++++++++------ lib/Lacuna/DB/Result/Ships.pm | 20 +- lib/Lacuna/RPC/Building/SpacePort.pm | 167 +++++++++++++++- t/440_fleets.t | 32 +++ 4 files changed, 440 insertions(+), 68 deletions(-) create mode 100644 t/440_fleets.t diff --git a/docs/SpacePort.pod b/docs/SpacePort.pod index a6ff0737..28d8d061 100644 --- a/docs/SpacePort.pod +++ b/docs/SpacePort.pod @@ -61,8 +61,8 @@ Shows you all your ships whatever they are doing. "name" : "Mars" } }, - { - "id" : "id-goes-here", + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -85,11 +85,11 @@ Shows you all your ships whatever they are doing. "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3 + "x" : 4, + "y" : -3 } - }, + }, ... ], "number_of_ships" : 13, @@ -206,7 +206,87 @@ The unique id of the space port. Defaults to page 1. Shows 25 at a time. +=head2 get_fleet_for ( session_id, from_body_id, target ) + +Provides a summary of ships that can be included in a fleet action + + { + "ships" : [ + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 103, + "estimated_travel_time" : "3654", + }, + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 25000, + "quantity" : 26, + "estimated_travel_time" : "3745", + }, + { + "type" : "surveyor", + "type_human" : "Surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 24, + "estimated_travel_time" : "4123", + } + ... + ], + "status" : { ... } + } + +Ships are grouped according to type,speed,stealth and combat, the number of ships in each group is given. + +=head3 session_id + +A session id. + +=head3 from_body_id + +The unique id of the planet that should send the ships. + +=head3 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. =head2 get_ships_for ( session_id, from_body_id, target ) @@ -258,27 +338,27 @@ Provides a list of incoming ships and ships that are available to send to a spec ... ], "unavailable" : [ - { + { "reason" : [1009, "You can't send a detonator to a star."], - "ship" : { - "id" : "id-goes-here", - "name" : "D13", - "type_human" : "Detonator", - "type" : "detonator", - "task" : "Docked", - "speed" : "700", + "ship" : { + "id" : "id-goes-here", + "name" : "D13", + "type_human" : "Detonator", + "type" : "detonator", + "task" : "Docked", + "speed" : "700", "fleet_speed" : "0", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "01 31 2010 13:09:05 +0600" + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "01 31 2010 13:09:05 +0600" } }, ... ], - "orbiting" : [ - { - "id" : "id-goes-here", + "orbiting" : [ + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -299,13 +379,13 @@ Provides a list of incoming ships and ships that are available to send to a spec "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3, + "x" : 4, + "y" : -3, } - }, - ... - ], + }, + ... + ], "mining_platforms" : [ { empire_id => "id-goes-here", @@ -362,7 +442,6 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. - =head2 send_ship ( session_id, ship_id, target ) Sends a ship to a specified body or star. Use with C. @@ -440,44 +519,138 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. +=head2 send_ship_types ( session_id, from_body_id, target, types, arrival ) + +Sends a quantity of ships, of a specific type (type, speed, combat, stealth) to a target. + +Look at B for a summary of what ships can be sent. + +Returns the same as B showing how many ships are remaining to be sent. + +Throws 1002,1009,1010,1019 + +=head4 session_id + +A session ID. + +=head4 from_body_id + +The Unique ID of the body that should send the ships + +=head4 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id + +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. + +=head4 types + +An array reference that contains the specification of the ships to send and the quantity. + + [ + { + "type" : "sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 100 + }, + { + "type" : "surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 10 + } + ] + +=head4 arrival + +A hash reference of the required arrival time. + + { + "day" : "23", + "hour" : "12", + "minute" : "01", + "second" : "30" + } + +So long as the sending body has that quantity of ships with those specifications, then the +ships will be sent. + +Ships will be set to arrive at the B time and date, which can be up to 28 days in +the future. B is the day of the month, either the remainder of the current month, or +the start of next month. e.g. if the current date is 23rd of January, then a B of 23 +will refer to today whereas 3 would refer to 3rd of February. + +If an arrival time is set which is prior to the earliest arrival time of the slowest ship, +then an exception is raised. =head2 send_fleet ( session_id, ship_ids, target, [ set_speed ] ) Sends a fleet of ships to a specified body or star. Use with C. - { + { "status" : { ... }, - "fleet" : [ - "ship" : { - "id" : "id-goes-here", - "name" : "P13", - "type_human" : "Probe", - "type" : "probe", - "task" : "Travelling", - "speed" : "1200", - "fleet_speed" : "250", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "02 01 2010 10:08:33 +0600", - "date_arrives" : "02 01 2010 10:08:33 +0600", - "can_recall" : "0", - "can_scuttle" : "0", - "from" : { - "id" : "id-goes-here", - "type" : "body", - "name" : "Earth" - }, - "to" : { - "id" : "id-goes-here", - "type" : "star", - "name" : "Sol" - } - }, - ... - ] - } + "fleet" : [ + "ship" : { + "id" : "id-goes-here", + "name" : "P13", + "type_human" : "Probe", + "type" : "probe", + "task" : "Travelling", + "speed" : "1200", + "fleet_speed" : "250", + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "02 01 2010 10:08:33 +0600", + "date_arrives" : "02 01 2010 10:08:33 +0600", + "can_recall" : "0", + "can_scuttle" : "0", + "from" : { + "id" : "id-goes-here", + "type" : "body", + "name" : "Earth" + }, + "to" : { + "id" : "id-goes-here", + "type" : "star", + "name" : "Sol" + } + }, + ... + ] +} Throws 1002, 1009, 1010, 1016. @@ -485,7 +658,7 @@ Throws 1002, 1009, 1010, 1016. A session id. -=head3 ship_id +=head3 ship_ids An array reference of ship ids to send. diff --git a/lib/Lacuna/DB/Result/Ships.pm b/lib/Lacuna/DB/Result/Ships.pm index 57908408..45349bb7 100644 --- a/lib/Lacuna/DB/Result/Ships.pm +++ b/lib/Lacuna/DB/Result/Ships.pm @@ -174,7 +174,13 @@ sub can_recall { sub type_formatted { my $self = shift; - my $type = $self->type; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + $type =~ s/_/ /g; $type =~ s/\b(\w)/\u$1/g; return $type; @@ -276,7 +282,9 @@ sub send { $self->payload($options{payload} || {}); $self->roundtrip($options{roundtrip} || 0); $self->direction($options{direction} || 'out'); - $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($options{target}))); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { $self->foreign_body_id($options{target}->id); $self->foreign_body($options{target}); @@ -336,11 +344,19 @@ sub land { sub calculate_travel_time { my ($self, $target) = @_; + my $distance = $self->body->calculate_distance_to_target($target); my $speed = $self->speed; if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { $speed = $self->fleet_speed; } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); $speed ||= 1; my $hours = $distance / $speed; my $seconds = 60 * 60 * $hours; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f0e78911..bdfe3685 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -41,11 +41,55 @@ sub find_target { } } unless (defined $target) { - confess [ 1002, 'Could not find the target.', $target]; + confess [ 1002, 'Could not find the target.', $target]; } return $target; } +sub get_fleet_for { + my ($self, $session_id, $body_id, $target_params) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + + my $berth = Lacuna->db->resultset('Lacuna::DB::Result::Building')->search( { + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $body_id, + efficiency => 100, + } )->get_column('level')->max; + my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( + { + body_id => $body->id, + task => 'docked', + },{ + '+select' => [{count => 'id'}], + '+as' => [ qw(quantity) ], + group_by => [ qw(type speed stealth combat hold_size) ], + }, + ); + my $summary; + while (my $ship_group = $ships->next) { + my $travel_time = Lacuna::DB::Result::Ships->travel_time($body,$target,$ship_group->speed); + my $type_human = Lacuna::DB::Result::Ships->type_human($ship_group->type); + my $summation = { + type => $ship_group->type, + type_human => $type_human, + speed => int($ship_group->speed), + stealth => int($ship_group->stealth), + combat => int($ship_group->combat), + quantity => $ship_group->get_column('quantity'), + estimated_travel_time => $travel_time, + }; + push @$summary, $summation; + } + my %out = ( + status => $self->format_status($empire, $body), + ships => $summary, + ); + return \%out; +} + sub get_ships_for { my ($self, $session_id, $body_id, $target_params) = @_; my $empire = $self->get_empire_by_session($session_id); @@ -55,12 +99,12 @@ sub get_ships_for { my @incoming; my $incoming_rs = $ships->search({ - task => 'Travelling', - direction => 'out', - 'body.empire_id' => $empire->id, - }, - { join => 'body' } - ); + task => 'Travelling', + direction => 'out', + 'body.empire_id' => $empire->id, + },{ + join => 'body', + }); if ($target->isa('Lacuna::DB::Result::Map::Star')) { $incoming_rs = $incoming_rs->search({foreign_star_id => $target->id}); } @@ -175,6 +219,113 @@ sub send_ship { } } +sub find_arrival { + my ($self, $arrival_params) = @_; + + my $now = DateTime->now; + my $year = $now->year, + my $month = $now->month; + my $mon_end = DateTime->last_day_of_month(year => $year, month => $month); + my $day = $arrival_params->{day}; + my $hour = $arrival_params->{hour}; + my $minute = $arrival_params->{minute}; + my $second = $arrival_params->{second}; + + if (not defined $day or $day < 1 or $day > $mon_end->day) { + confess [1009, 'Invalid day.']; + } + if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { + confess [1002, 'Invalid hour.']; + } + if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { + confess [1002, 'Invalid minute.']; + } + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; + } + if ($day < $now->day) { + # Then it must be a day next month + $mon_end->add( days => $day); + $year = $mon_end->year; + $month = $mon_end->month; + } + my $arrival = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $minute, + second => $second, + ); + return $arrival; +} + +sub send_ship_types { + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + my $arrival = $self->find_arrival($arrival_params); + + # calculate the total ships before the expense of any database operations. + my $total_ships = 0; + map {$total_ships += $_->{quantity}} @$type_params; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + if ($total_ships > $max_ships) { + confess [1009, 'Too many ships for a fleet.']; + } + + my $ship_ref; + my $do_captcha_check = 0; + foreach my $type_param (@$type_params) { + foreach my $arg (qw(speed stealth combat quantity)) { + confess [1002, "$arg cannot be negative."] if $type_param->{$arg} < 0; + confess [1002, "$arg must be an integer."] if $type_param->{$arg} != int($type_param->{$arg}); + } + my $type = $type_param->{type}; + my $speed = $type_param->{speed}; + my $stealth = $type_param->{stealth}; + my $combat = $type_param->{combat}; + my $quantity = $type_param->{quantity}; + confess [1009, "Cannot send more than one excavator"] if ($type eq 'excavator' and $quantity > 1); + + # TODO Must check for valid berth levels + # + my $ships_rs = Lacuna->db->resultset('Ships')->search({ + body_id => $body->id, + task => 'Docked', + type => $type, + speed => $speed, + stealth => $stealth, + combat => $combat, + }); + if ($ships_rs->count < $quantity) { + confess [1009, "Cannot find $quantity of $type ships."]; + } + my @ships = $ships_rs->search(undef,{rows => $quantity}); + my $ship = $ships[0]; + # We only need to check one of the ships + $ship->can_send_to_target($target); + if (not $do_captcha_check and $ship->hostile_action) { + $do_captcha_check = 1; + } + foreach my $ship (@ships) { + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; + } + } + if ($do_captcha_check) { + $empire->current_session->check_captcha; + } + # If we get here without exceptions, then all ships can be sent + foreach my $ship (values %$ship_ref) { + $ship->fleet_speed(1); + $ship->send(target => $target, arrival => $arrival); + } + +} + sub send_fleet { my ($self, $session_id, $ship_ids, $target_params, $set_speed) = @_; $set_speed //= 0; @@ -927,7 +1078,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t new file mode 100644 index 00000000..3e51eef0 --- /dev/null +++ b/t/440_fleets.t @@ -0,0 +1,32 @@ +use lib '../lib'; + +use strict; +use warnings; + +use Test::More tests => 10; +use Test::Deep; +use Data::Dumper; +use 5.010; +use DateTime; + +use TestHelper; +my $tester = TestHelper->new->use_existing_test_empire; +my $session_id = $tester->session->id; +my $empire = $tester->empire; +my $home = $empire->home_planet; +my $command = $home->command; + +my $result; + +my $space_port = Lacuna->db->resultset('Building')->search({ + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $home->id, + },{ + rows => 1, +})->single; + +$result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); + +END { +# TestHelper->clear_all_test_empires; +} -- 2.51.2 From 4c2f2a23735787d00ddccaaf183f756c66dc5b5d Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 02/31] Started adding new fleet action API calls --- docs/SpacePort.pod | 289 +++++++++++++++++++++------ lib/Lacuna/DB/Result/Ships.pm | 20 +- lib/Lacuna/RPC/Building/SpacePort.pm | 167 +++++++++++++++- t/440_fleets.t | 32 +++ 4 files changed, 440 insertions(+), 68 deletions(-) create mode 100644 t/440_fleets.t diff --git a/docs/SpacePort.pod b/docs/SpacePort.pod index a6ff0737..28d8d061 100644 --- a/docs/SpacePort.pod +++ b/docs/SpacePort.pod @@ -61,8 +61,8 @@ Shows you all your ships whatever they are doing. "name" : "Mars" } }, - { - "id" : "id-goes-here", + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -85,11 +85,11 @@ Shows you all your ships whatever they are doing. "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3 + "x" : 4, + "y" : -3 } - }, + }, ... ], "number_of_ships" : 13, @@ -206,7 +206,87 @@ The unique id of the space port. Defaults to page 1. Shows 25 at a time. +=head2 get_fleet_for ( session_id, from_body_id, target ) + +Provides a summary of ships that can be included in a fleet action + + { + "ships" : [ + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 103, + "estimated_travel_time" : "3654", + }, + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 25000, + "quantity" : 26, + "estimated_travel_time" : "3745", + }, + { + "type" : "surveyor", + "type_human" : "Surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 24, + "estimated_travel_time" : "4123", + } + ... + ], + "status" : { ... } + } + +Ships are grouped according to type,speed,stealth and combat, the number of ships in each group is given. + +=head3 session_id + +A session id. + +=head3 from_body_id + +The unique id of the planet that should send the ships. + +=head3 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. =head2 get_ships_for ( session_id, from_body_id, target ) @@ -258,27 +338,27 @@ Provides a list of incoming ships and ships that are available to send to a spec ... ], "unavailable" : [ - { + { "reason" : [1009, "You can't send a detonator to a star."], - "ship" : { - "id" : "id-goes-here", - "name" : "D13", - "type_human" : "Detonator", - "type" : "detonator", - "task" : "Docked", - "speed" : "700", + "ship" : { + "id" : "id-goes-here", + "name" : "D13", + "type_human" : "Detonator", + "type" : "detonator", + "task" : "Docked", + "speed" : "700", "fleet_speed" : "0", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "01 31 2010 13:09:05 +0600" + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "01 31 2010 13:09:05 +0600" } }, ... ], - "orbiting" : [ - { - "id" : "id-goes-here", + "orbiting" : [ + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -299,13 +379,13 @@ Provides a list of incoming ships and ships that are available to send to a spec "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3, + "x" : 4, + "y" : -3, } - }, - ... - ], + }, + ... + ], "mining_platforms" : [ { empire_id => "id-goes-here", @@ -362,7 +442,6 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. - =head2 send_ship ( session_id, ship_id, target ) Sends a ship to a specified body or star. Use with C. @@ -440,44 +519,138 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. +=head2 send_ship_types ( session_id, from_body_id, target, types, arrival ) + +Sends a quantity of ships, of a specific type (type, speed, combat, stealth) to a target. + +Look at B for a summary of what ships can be sent. + +Returns the same as B showing how many ships are remaining to be sent. + +Throws 1002,1009,1010,1019 + +=head4 session_id + +A session ID. + +=head4 from_body_id + +The Unique ID of the body that should send the ships + +=head4 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id + +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. + +=head4 types + +An array reference that contains the specification of the ships to send and the quantity. + + [ + { + "type" : "sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 100 + }, + { + "type" : "surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 10 + } + ] + +=head4 arrival + +A hash reference of the required arrival time. + + { + "day" : "23", + "hour" : "12", + "minute" : "01", + "second" : "30" + } + +So long as the sending body has that quantity of ships with those specifications, then the +ships will be sent. + +Ships will be set to arrive at the B time and date, which can be up to 28 days in +the future. B is the day of the month, either the remainder of the current month, or +the start of next month. e.g. if the current date is 23rd of January, then a B of 23 +will refer to today whereas 3 would refer to 3rd of February. + +If an arrival time is set which is prior to the earliest arrival time of the slowest ship, +then an exception is raised. =head2 send_fleet ( session_id, ship_ids, target, [ set_speed ] ) Sends a fleet of ships to a specified body or star. Use with C. - { + { "status" : { ... }, - "fleet" : [ - "ship" : { - "id" : "id-goes-here", - "name" : "P13", - "type_human" : "Probe", - "type" : "probe", - "task" : "Travelling", - "speed" : "1200", - "fleet_speed" : "250", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "02 01 2010 10:08:33 +0600", - "date_arrives" : "02 01 2010 10:08:33 +0600", - "can_recall" : "0", - "can_scuttle" : "0", - "from" : { - "id" : "id-goes-here", - "type" : "body", - "name" : "Earth" - }, - "to" : { - "id" : "id-goes-here", - "type" : "star", - "name" : "Sol" - } - }, - ... - ] - } + "fleet" : [ + "ship" : { + "id" : "id-goes-here", + "name" : "P13", + "type_human" : "Probe", + "type" : "probe", + "task" : "Travelling", + "speed" : "1200", + "fleet_speed" : "250", + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "02 01 2010 10:08:33 +0600", + "date_arrives" : "02 01 2010 10:08:33 +0600", + "can_recall" : "0", + "can_scuttle" : "0", + "from" : { + "id" : "id-goes-here", + "type" : "body", + "name" : "Earth" + }, + "to" : { + "id" : "id-goes-here", + "type" : "star", + "name" : "Sol" + } + }, + ... + ] +} Throws 1002, 1009, 1010, 1016. @@ -485,7 +658,7 @@ Throws 1002, 1009, 1010, 1016. A session id. -=head3 ship_id +=head3 ship_ids An array reference of ship ids to send. diff --git a/lib/Lacuna/DB/Result/Ships.pm b/lib/Lacuna/DB/Result/Ships.pm index b2637bef..f6941df7 100644 --- a/lib/Lacuna/DB/Result/Ships.pm +++ b/lib/Lacuna/DB/Result/Ships.pm @@ -174,7 +174,13 @@ sub can_recall { sub type_formatted { my $self = shift; - my $type = $self->type; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + $type =~ s/_/ /g; $type =~ s/\b(\w)/\u$1/g; return $type; @@ -279,7 +285,9 @@ sub send { $self->payload($options{payload} || {}); $self->roundtrip($options{roundtrip} || 0); $self->direction($options{direction} || 'out'); - $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($options{target}))); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { $self->foreign_body_id($options{target}->id); $self->foreign_body($options{target}); @@ -339,11 +347,19 @@ sub land { sub calculate_travel_time { my ($self, $target) = @_; + my $distance = $self->body->calculate_distance_to_target($target); my $speed = $self->speed; if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { $speed = $self->fleet_speed; } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); $speed ||= 1; my $hours = $distance / $speed; my $seconds = 60 * 60 * $hours; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f0e78911..bdfe3685 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -41,11 +41,55 @@ sub find_target { } } unless (defined $target) { - confess [ 1002, 'Could not find the target.', $target]; + confess [ 1002, 'Could not find the target.', $target]; } return $target; } +sub get_fleet_for { + my ($self, $session_id, $body_id, $target_params) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + + my $berth = Lacuna->db->resultset('Lacuna::DB::Result::Building')->search( { + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $body_id, + efficiency => 100, + } )->get_column('level')->max; + my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( + { + body_id => $body->id, + task => 'docked', + },{ + '+select' => [{count => 'id'}], + '+as' => [ qw(quantity) ], + group_by => [ qw(type speed stealth combat hold_size) ], + }, + ); + my $summary; + while (my $ship_group = $ships->next) { + my $travel_time = Lacuna::DB::Result::Ships->travel_time($body,$target,$ship_group->speed); + my $type_human = Lacuna::DB::Result::Ships->type_human($ship_group->type); + my $summation = { + type => $ship_group->type, + type_human => $type_human, + speed => int($ship_group->speed), + stealth => int($ship_group->stealth), + combat => int($ship_group->combat), + quantity => $ship_group->get_column('quantity'), + estimated_travel_time => $travel_time, + }; + push @$summary, $summation; + } + my %out = ( + status => $self->format_status($empire, $body), + ships => $summary, + ); + return \%out; +} + sub get_ships_for { my ($self, $session_id, $body_id, $target_params) = @_; my $empire = $self->get_empire_by_session($session_id); @@ -55,12 +99,12 @@ sub get_ships_for { my @incoming; my $incoming_rs = $ships->search({ - task => 'Travelling', - direction => 'out', - 'body.empire_id' => $empire->id, - }, - { join => 'body' } - ); + task => 'Travelling', + direction => 'out', + 'body.empire_id' => $empire->id, + },{ + join => 'body', + }); if ($target->isa('Lacuna::DB::Result::Map::Star')) { $incoming_rs = $incoming_rs->search({foreign_star_id => $target->id}); } @@ -175,6 +219,113 @@ sub send_ship { } } +sub find_arrival { + my ($self, $arrival_params) = @_; + + my $now = DateTime->now; + my $year = $now->year, + my $month = $now->month; + my $mon_end = DateTime->last_day_of_month(year => $year, month => $month); + my $day = $arrival_params->{day}; + my $hour = $arrival_params->{hour}; + my $minute = $arrival_params->{minute}; + my $second = $arrival_params->{second}; + + if (not defined $day or $day < 1 or $day > $mon_end->day) { + confess [1009, 'Invalid day.']; + } + if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { + confess [1002, 'Invalid hour.']; + } + if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { + confess [1002, 'Invalid minute.']; + } + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; + } + if ($day < $now->day) { + # Then it must be a day next month + $mon_end->add( days => $day); + $year = $mon_end->year; + $month = $mon_end->month; + } + my $arrival = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $minute, + second => $second, + ); + return $arrival; +} + +sub send_ship_types { + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + my $arrival = $self->find_arrival($arrival_params); + + # calculate the total ships before the expense of any database operations. + my $total_ships = 0; + map {$total_ships += $_->{quantity}} @$type_params; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + if ($total_ships > $max_ships) { + confess [1009, 'Too many ships for a fleet.']; + } + + my $ship_ref; + my $do_captcha_check = 0; + foreach my $type_param (@$type_params) { + foreach my $arg (qw(speed stealth combat quantity)) { + confess [1002, "$arg cannot be negative."] if $type_param->{$arg} < 0; + confess [1002, "$arg must be an integer."] if $type_param->{$arg} != int($type_param->{$arg}); + } + my $type = $type_param->{type}; + my $speed = $type_param->{speed}; + my $stealth = $type_param->{stealth}; + my $combat = $type_param->{combat}; + my $quantity = $type_param->{quantity}; + confess [1009, "Cannot send more than one excavator"] if ($type eq 'excavator' and $quantity > 1); + + # TODO Must check for valid berth levels + # + my $ships_rs = Lacuna->db->resultset('Ships')->search({ + body_id => $body->id, + task => 'Docked', + type => $type, + speed => $speed, + stealth => $stealth, + combat => $combat, + }); + if ($ships_rs->count < $quantity) { + confess [1009, "Cannot find $quantity of $type ships."]; + } + my @ships = $ships_rs->search(undef,{rows => $quantity}); + my $ship = $ships[0]; + # We only need to check one of the ships + $ship->can_send_to_target($target); + if (not $do_captcha_check and $ship->hostile_action) { + $do_captcha_check = 1; + } + foreach my $ship (@ships) { + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; + } + } + if ($do_captcha_check) { + $empire->current_session->check_captcha; + } + # If we get here without exceptions, then all ships can be sent + foreach my $ship (values %$ship_ref) { + $ship->fleet_speed(1); + $ship->send(target => $target, arrival => $arrival); + } + +} + sub send_fleet { my ($self, $session_id, $ship_ids, $target_params, $set_speed) = @_; $set_speed //= 0; @@ -927,7 +1078,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t new file mode 100644 index 00000000..3e51eef0 --- /dev/null +++ b/t/440_fleets.t @@ -0,0 +1,32 @@ +use lib '../lib'; + +use strict; +use warnings; + +use Test::More tests => 10; +use Test::Deep; +use Data::Dumper; +use 5.010; +use DateTime; + +use TestHelper; +my $tester = TestHelper->new->use_existing_test_empire; +my $session_id = $tester->session->id; +my $empire = $tester->empire; +my $home = $empire->home_planet; +my $command = $home->command; + +my $result; + +my $space_port = Lacuna->db->resultset('Building')->search({ + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $home->id, + },{ + rows => 1, +})->single; + +$result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); + +END { +# TestHelper->clear_all_test_empires; +} -- 2.51.2 From 33662c408d87f1bbda263be3766a433edafdd92f Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 13:48:35 -0400 Subject: [PATCH 03/31] Minor changes --- lib/Lacuna/RPC/Building/SpacePort.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index bdfe3685..70adba11 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -261,7 +261,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -323,7 +323,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - + return $self->get_fleet_for($session, $body_id, $target_params); } sub send_fleet { -- 2.51.2 From 85e7bb7caa3851b2bca7c6565b2d28c55358388f Mon Sep 17 00:00:00 2001 From: ian docherty Date: Tue, 15 May 2012 05:09:30 -0400 Subject: [PATCH 04/31] Fix error checking for send_ship_types --- lib/Lacuna/RPC/Building/SpacePort.pm | 16 +++++++++------- t/440_fleets.t | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 70adba11..2ad54116 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -6,6 +6,8 @@ no warnings qw(uninitialized); extends 'Lacuna::RPC::Building'; use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); +use Data::Dumper; + use feature "switch"; sub app_url { @@ -232,7 +234,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { - confess [1009, 'Invalid day.']; + confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -240,8 +242,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; + if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { + confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; } if ($day < $now->day) { # Then it must be a day next month @@ -261,7 +263,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -323,7 +325,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - return $self->get_fleet_for($session, $body_id, $target_params); + return $self->get_fleet_for($session_id, $body_id, $target_params); } sub send_fleet { @@ -331,7 +333,7 @@ sub send_fleet { $set_speed //= 0; my $empire = $self->get_empire_by_session($session_id); my $target = $self->find_target($target_params); - my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 50; if (@$ship_ids > $max_ships) { confess [1009, 'Too many ships for a fleet.']; } @@ -1078,7 +1080,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(send_ship_types get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t index 3e51eef0..d4113cd9 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -27,6 +27,23 @@ my $space_port = Lacuna->db->resultset('Building')->search({ $result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); +my ($sweepers) = grep {$_->{type} eq 'sweeper'} @{$result->{result}{ships}}; + +diag Dumper(\$sweepers); + +Lacuna->cache->set('captcha', $session_id, { guid => 1111, solution => 1111 }, 60 * 30 ); +$result = $tester->post('captcha','solve', [$session_id, 1111, 1111]); +is($result->{result}, 1, 'Solved captcha'); + + +$result = $tester->post('spaceport','send_ship_types', [ + $session_id, + $home->id, + {body_name => 'DeLambert-5-28'}, + [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], + {day => 10, hour => 1, minute => 1, second => 15}, +]); + END { # TestHelper->clear_all_test_empires; } -- 2.51.2 From 5c802fe6040364591c0b84bbd10df6b580646d51 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Thu, 17 May 2012 14:30:27 -0400 Subject: [PATCH 05/31] Send all ships in the fleet, not just one. --- lib/Lacuna/RPC/Building/SpacePort.pm | 3 +-- t/440_fleets.t | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 2ad54116..63baa8d7 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -313,8 +313,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; + $ship_ref->{$ship->id} = $ship; } } if ($do_captcha_check) { diff --git a/t/440_fleets.t b/t/440_fleets.t index d4113cd9..787056fe 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -41,7 +41,7 @@ $result = $tester->post('spaceport','send_ship_types', [ $home->id, {body_name => 'DeLambert-5-28'}, [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], - {day => 10, hour => 1, minute => 1, second => 15}, + {day => 10, hour => 0, minute => 0, second => 0}, ]); END { -- 2.51.2 From 95853733b96a871f8a76fada16e3f32f85374881 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 06/31] Started adding new fleet action API calls --- docs/SpacePort.pod | 289 +++++++++++++++++++++------ lib/Lacuna/DB/Result/Ships.pm | 20 +- lib/Lacuna/RPC/Building/SpacePort.pm | 167 +++++++++++++++- t/440_fleets.t | 32 +++ 4 files changed, 440 insertions(+), 68 deletions(-) create mode 100644 t/440_fleets.t diff --git a/docs/SpacePort.pod b/docs/SpacePort.pod index a6ff0737..28d8d061 100644 --- a/docs/SpacePort.pod +++ b/docs/SpacePort.pod @@ -61,8 +61,8 @@ Shows you all your ships whatever they are doing. "name" : "Mars" } }, - { - "id" : "id-goes-here", + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -85,11 +85,11 @@ Shows you all your ships whatever they are doing. "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3 + "x" : 4, + "y" : -3 } - }, + }, ... ], "number_of_ships" : 13, @@ -206,7 +206,87 @@ The unique id of the space port. Defaults to page 1. Shows 25 at a time. +=head2 get_fleet_for ( session_id, from_body_id, target ) + +Provides a summary of ships that can be included in a fleet action + + { + "ships" : [ + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 103, + "estimated_travel_time" : "3654", + }, + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 25000, + "quantity" : 26, + "estimated_travel_time" : "3745", + }, + { + "type" : "surveyor", + "type_human" : "Surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 24, + "estimated_travel_time" : "4123", + } + ... + ], + "status" : { ... } + } + +Ships are grouped according to type,speed,stealth and combat, the number of ships in each group is given. + +=head3 session_id + +A session id. + +=head3 from_body_id + +The unique id of the planet that should send the ships. + +=head3 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. =head2 get_ships_for ( session_id, from_body_id, target ) @@ -258,27 +338,27 @@ Provides a list of incoming ships and ships that are available to send to a spec ... ], "unavailable" : [ - { + { "reason" : [1009, "You can't send a detonator to a star."], - "ship" : { - "id" : "id-goes-here", - "name" : "D13", - "type_human" : "Detonator", - "type" : "detonator", - "task" : "Docked", - "speed" : "700", + "ship" : { + "id" : "id-goes-here", + "name" : "D13", + "type_human" : "Detonator", + "type" : "detonator", + "task" : "Docked", + "speed" : "700", "fleet_speed" : "0", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "01 31 2010 13:09:05 +0600" + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "01 31 2010 13:09:05 +0600" } }, ... ], - "orbiting" : [ - { - "id" : "id-goes-here", + "orbiting" : [ + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -299,13 +379,13 @@ Provides a list of incoming ships and ships that are available to send to a spec "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3, + "x" : 4, + "y" : -3, } - }, - ... - ], + }, + ... + ], "mining_platforms" : [ { empire_id => "id-goes-here", @@ -362,7 +442,6 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. - =head2 send_ship ( session_id, ship_id, target ) Sends a ship to a specified body or star. Use with C. @@ -440,44 +519,138 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. +=head2 send_ship_types ( session_id, from_body_id, target, types, arrival ) + +Sends a quantity of ships, of a specific type (type, speed, combat, stealth) to a target. + +Look at B for a summary of what ships can be sent. + +Returns the same as B showing how many ships are remaining to be sent. + +Throws 1002,1009,1010,1019 + +=head4 session_id + +A session ID. + +=head4 from_body_id + +The Unique ID of the body that should send the ships + +=head4 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id + +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. + +=head4 types + +An array reference that contains the specification of the ships to send and the quantity. + + [ + { + "type" : "sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 100 + }, + { + "type" : "surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 10 + } + ] + +=head4 arrival + +A hash reference of the required arrival time. + + { + "day" : "23", + "hour" : "12", + "minute" : "01", + "second" : "30" + } + +So long as the sending body has that quantity of ships with those specifications, then the +ships will be sent. + +Ships will be set to arrive at the B time and date, which can be up to 28 days in +the future. B is the day of the month, either the remainder of the current month, or +the start of next month. e.g. if the current date is 23rd of January, then a B of 23 +will refer to today whereas 3 would refer to 3rd of February. + +If an arrival time is set which is prior to the earliest arrival time of the slowest ship, +then an exception is raised. =head2 send_fleet ( session_id, ship_ids, target, [ set_speed ] ) Sends a fleet of ships to a specified body or star. Use with C. - { + { "status" : { ... }, - "fleet" : [ - "ship" : { - "id" : "id-goes-here", - "name" : "P13", - "type_human" : "Probe", - "type" : "probe", - "task" : "Travelling", - "speed" : "1200", - "fleet_speed" : "250", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "02 01 2010 10:08:33 +0600", - "date_arrives" : "02 01 2010 10:08:33 +0600", - "can_recall" : "0", - "can_scuttle" : "0", - "from" : { - "id" : "id-goes-here", - "type" : "body", - "name" : "Earth" - }, - "to" : { - "id" : "id-goes-here", - "type" : "star", - "name" : "Sol" - } - }, - ... - ] - } + "fleet" : [ + "ship" : { + "id" : "id-goes-here", + "name" : "P13", + "type_human" : "Probe", + "type" : "probe", + "task" : "Travelling", + "speed" : "1200", + "fleet_speed" : "250", + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "02 01 2010 10:08:33 +0600", + "date_arrives" : "02 01 2010 10:08:33 +0600", + "can_recall" : "0", + "can_scuttle" : "0", + "from" : { + "id" : "id-goes-here", + "type" : "body", + "name" : "Earth" + }, + "to" : { + "id" : "id-goes-here", + "type" : "star", + "name" : "Sol" + } + }, + ... + ] +} Throws 1002, 1009, 1010, 1016. @@ -485,7 +658,7 @@ Throws 1002, 1009, 1010, 1016. A session id. -=head3 ship_id +=head3 ship_ids An array reference of ship ids to send. diff --git a/lib/Lacuna/DB/Result/Ships.pm b/lib/Lacuna/DB/Result/Ships.pm index b2637bef..f6941df7 100644 --- a/lib/Lacuna/DB/Result/Ships.pm +++ b/lib/Lacuna/DB/Result/Ships.pm @@ -174,7 +174,13 @@ sub can_recall { sub type_formatted { my $self = shift; - my $type = $self->type; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + $type =~ s/_/ /g; $type =~ s/\b(\w)/\u$1/g; return $type; @@ -279,7 +285,9 @@ sub send { $self->payload($options{payload} || {}); $self->roundtrip($options{roundtrip} || 0); $self->direction($options{direction} || 'out'); - $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($options{target}))); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { $self->foreign_body_id($options{target}->id); $self->foreign_body($options{target}); @@ -339,11 +347,19 @@ sub land { sub calculate_travel_time { my ($self, $target) = @_; + my $distance = $self->body->calculate_distance_to_target($target); my $speed = $self->speed; if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { $speed = $self->fleet_speed; } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); $speed ||= 1; my $hours = $distance / $speed; my $seconds = 60 * 60 * $hours; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f6ce7b94..15568088 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -41,11 +41,55 @@ sub find_target { } } unless (defined $target) { - confess [ 1002, 'Could not find the target.', $target]; + confess [ 1002, 'Could not find the target.', $target]; } return $target; } +sub get_fleet_for { + my ($self, $session_id, $body_id, $target_params) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + + my $berth = Lacuna->db->resultset('Lacuna::DB::Result::Building')->search( { + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $body_id, + efficiency => 100, + } )->get_column('level')->max; + my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( + { + body_id => $body->id, + task => 'docked', + },{ + '+select' => [{count => 'id'}], + '+as' => [ qw(quantity) ], + group_by => [ qw(type speed stealth combat hold_size) ], + }, + ); + my $summary; + while (my $ship_group = $ships->next) { + my $travel_time = Lacuna::DB::Result::Ships->travel_time($body,$target,$ship_group->speed); + my $type_human = Lacuna::DB::Result::Ships->type_human($ship_group->type); + my $summation = { + type => $ship_group->type, + type_human => $type_human, + speed => int($ship_group->speed), + stealth => int($ship_group->stealth), + combat => int($ship_group->combat), + quantity => $ship_group->get_column('quantity'), + estimated_travel_time => $travel_time, + }; + push @$summary, $summation; + } + my %out = ( + status => $self->format_status($empire, $body), + ships => $summary, + ); + return \%out; +} + sub get_ships_for { my ($self, $session_id, $body_id, $target_params) = @_; my $empire = $self->get_empire_by_session($session_id); @@ -55,12 +99,12 @@ sub get_ships_for { my @incoming; my $incoming_rs = $ships->search({ - task => 'Travelling', - direction => 'out', - 'body.empire_id' => $empire->id, - }, - { join => 'body' } - ); + task => 'Travelling', + direction => 'out', + 'body.empire_id' => $empire->id, + },{ + join => 'body', + }); if ($target->isa('Lacuna::DB::Result::Map::Star')) { $incoming_rs = $incoming_rs->search({foreign_star_id => $target->id}); } @@ -171,6 +215,113 @@ sub send_ship { } } +sub find_arrival { + my ($self, $arrival_params) = @_; + + my $now = DateTime->now; + my $year = $now->year, + my $month = $now->month; + my $mon_end = DateTime->last_day_of_month(year => $year, month => $month); + my $day = $arrival_params->{day}; + my $hour = $arrival_params->{hour}; + my $minute = $arrival_params->{minute}; + my $second = $arrival_params->{second}; + + if (not defined $day or $day < 1 or $day > $mon_end->day) { + confess [1009, 'Invalid day.']; + } + if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { + confess [1002, 'Invalid hour.']; + } + if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { + confess [1002, 'Invalid minute.']; + } + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; + } + if ($day < $now->day) { + # Then it must be a day next month + $mon_end->add( days => $day); + $year = $mon_end->year; + $month = $mon_end->month; + } + my $arrival = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $minute, + second => $second, + ); + return $arrival; +} + +sub send_ship_types { + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + my $arrival = $self->find_arrival($arrival_params); + + # calculate the total ships before the expense of any database operations. + my $total_ships = 0; + map {$total_ships += $_->{quantity}} @$type_params; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + if ($total_ships > $max_ships) { + confess [1009, 'Too many ships for a fleet.']; + } + + my $ship_ref; + my $do_captcha_check = 0; + foreach my $type_param (@$type_params) { + foreach my $arg (qw(speed stealth combat quantity)) { + confess [1002, "$arg cannot be negative."] if $type_param->{$arg} < 0; + confess [1002, "$arg must be an integer."] if $type_param->{$arg} != int($type_param->{$arg}); + } + my $type = $type_param->{type}; + my $speed = $type_param->{speed}; + my $stealth = $type_param->{stealth}; + my $combat = $type_param->{combat}; + my $quantity = $type_param->{quantity}; + confess [1009, "Cannot send more than one excavator"] if ($type eq 'excavator' and $quantity > 1); + + # TODO Must check for valid berth levels + # + my $ships_rs = Lacuna->db->resultset('Ships')->search({ + body_id => $body->id, + task => 'Docked', + type => $type, + speed => $speed, + stealth => $stealth, + combat => $combat, + }); + if ($ships_rs->count < $quantity) { + confess [1009, "Cannot find $quantity of $type ships."]; + } + my @ships = $ships_rs->search(undef,{rows => $quantity}); + my $ship = $ships[0]; + # We only need to check one of the ships + $ship->can_send_to_target($target); + if (not $do_captcha_check and $ship->hostile_action) { + $do_captcha_check = 1; + } + foreach my $ship (@ships) { + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; + } + } + if ($do_captcha_check) { + $empire->current_session->check_captcha; + } + # If we get here without exceptions, then all ships can be sent + foreach my $ship (values %$ship_ref) { + $ship->fleet_speed(1); + $ship->send(target => $target, arrival => $arrival); + } + +} + sub send_fleet { my ($self, $session_id, $ship_ids, $target_params, $set_speed) = @_; $set_speed //= 0; @@ -905,7 +1056,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t new file mode 100644 index 00000000..3e51eef0 --- /dev/null +++ b/t/440_fleets.t @@ -0,0 +1,32 @@ +use lib '../lib'; + +use strict; +use warnings; + +use Test::More tests => 10; +use Test::Deep; +use Data::Dumper; +use 5.010; +use DateTime; + +use TestHelper; +my $tester = TestHelper->new->use_existing_test_empire; +my $session_id = $tester->session->id; +my $empire = $tester->empire; +my $home = $empire->home_planet; +my $command = $home->command; + +my $result; + +my $space_port = Lacuna->db->resultset('Building')->search({ + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $home->id, + },{ + rows => 1, +})->single; + +$result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); + +END { +# TestHelper->clear_all_test_empires; +} -- 2.51.2 From 8a769810c6d44fdcbb1ebb34ed17cc166ac5ccd5 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 13:48:35 -0400 Subject: [PATCH 07/31] Minor changes --- lib/Lacuna/RPC/Building/SpacePort.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 15568088..dfe69c99 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -257,7 +257,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -319,7 +319,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - + return $self->get_fleet_for($session, $body_id, $target_params); } sub send_fleet { -- 2.51.2 From 14f8a72d3f1d4a13075bad407d9ba0c6f5c7133d Mon Sep 17 00:00:00 2001 From: ian docherty Date: Tue, 15 May 2012 05:09:30 -0400 Subject: [PATCH 08/31] Fix error checking for send_ship_types --- lib/Lacuna/RPC/Building/SpacePort.pm | 16 +++++++++------- t/440_fleets.t | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index dfe69c99..12564f1b 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -6,6 +6,8 @@ no warnings qw(uninitialized); extends 'Lacuna::RPC::Building'; use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); +use Data::Dumper; + use feature "switch"; sub app_url { @@ -228,7 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { - confess [1009, 'Invalid day.']; + confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -236,8 +238,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; + if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { + confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; } if ($day < $now->day) { # Then it must be a day next month @@ -257,7 +259,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -319,7 +321,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - return $self->get_fleet_for($session, $body_id, $target_params); + return $self->get_fleet_for($session_id, $body_id, $target_params); } sub send_fleet { @@ -327,7 +329,7 @@ sub send_fleet { $set_speed //= 0; my $empire = $self->get_empire_by_session($session_id); my $target = $self->find_target($target_params); - my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 50; if (@$ship_ids > $max_ships) { confess [1009, 'Too many ships for a fleet.']; } @@ -1056,7 +1058,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(send_ship_types get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t index 3e51eef0..d4113cd9 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -27,6 +27,23 @@ my $space_port = Lacuna->db->resultset('Building')->search({ $result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); +my ($sweepers) = grep {$_->{type} eq 'sweeper'} @{$result->{result}{ships}}; + +diag Dumper(\$sweepers); + +Lacuna->cache->set('captcha', $session_id, { guid => 1111, solution => 1111 }, 60 * 30 ); +$result = $tester->post('captcha','solve', [$session_id, 1111, 1111]); +is($result->{result}, 1, 'Solved captcha'); + + +$result = $tester->post('spaceport','send_ship_types', [ + $session_id, + $home->id, + {body_name => 'DeLambert-5-28'}, + [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], + {day => 10, hour => 1, minute => 1, second => 15}, +]); + END { # TestHelper->clear_all_test_empires; } -- 2.51.2 From 46be3455473a92c58980795555174b9d9c9a3aed Mon Sep 17 00:00:00 2001 From: ian docherty Date: Thu, 17 May 2012 14:30:27 -0400 Subject: [PATCH 09/31] Send all ships in the fleet, not just one. --- lib/Lacuna/RPC/Building/SpacePort.pm | 3 +-- t/440_fleets.t | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 12564f1b..0175be4e 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -309,8 +309,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; + $ship_ref->{$ship->id} = $ship; } } if ($do_captcha_check) { diff --git a/t/440_fleets.t b/t/440_fleets.t index d4113cd9..787056fe 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -41,7 +41,7 @@ $result = $tester->post('spaceport','send_ship_types', [ $home->id, {body_name => 'DeLambert-5-28'}, [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], - {day => 10, hour => 1, minute => 1, second => 15}, + {day => 10, hour => 0, minute => 0, second => 0}, ]); END { -- 2.51.2 From 184aab3034073d373e4c32cadd5130ef464b26d7 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 10/31] Started adding new fleet action API calls --- lib/Lacuna/RPC/Building/SpacePort.pm | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 0175be4e..76e3776f 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,11 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { +<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; +======= + confess [1009, 'Invalid day.']; +>>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -238,8 +242,13 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } +<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; +======= + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; +>>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -259,7 +268,11 @@ sub find_arrival { } sub send_ship_types { +<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; +======= + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; +>>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -309,7 +322,12 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { +<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; +======= + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; +>>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -320,7 +338,11 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } +<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); +======= + +>>>>>>> Started adding new fleet action API calls } sub send_fleet { @@ -1059,7 +1081,6 @@ around 'view' => sub { __PACKAGE__->register_rpc_method_names(qw(send_ship_types get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); - no Moose; __PACKAGE__->meta->make_immutable; -- 2.51.2 From b652ce64c5b9be90a1e09d817ad2d8bc2a9cad9e Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 13:48:35 -0400 Subject: [PATCH 11/31] Minor changes --- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 76e3776f..f2267570 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,11 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { -<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; -======= - confess [1009, 'Invalid day.']; ->>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -242,13 +238,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } -<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; -======= - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; ->>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -268,11 +259,7 @@ sub find_arrival { } sub send_ship_types { -<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; -======= - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; ->>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -322,12 +309,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { -<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; -======= - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; ->>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -338,11 +320,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } -<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); -======= - ->>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From c93683a9e4eea5688bbb364f90452a29dc0720e2 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 04:50:41 -0400 Subject: [PATCH 12/31] Start to convert ships into fleets --- lib/Lacuna/DB/Result/Fleet.pm | 370 ++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 lib/Lacuna/DB/Result/Fleet.pm diff --git a/lib/Lacuna/DB/Result/Fleet.pm b/lib/Lacuna/DB/Result/Fleet.pm new file mode 100644 index 00000000..f6941df7 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet.pm @@ -0,0 +1,370 @@ +package Lacuna::DB::Result::Ships; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result'; +use Lacuna::Util qw(format_date randint); +use DateTime; +use feature "switch"; + +has 'hostile_action' => ( + is => 'rw', + isa => 'Bool', + lazy => 1, + builder => '_build_hostile_action', +); + +sub _build_hostile_action { 0 } + +__PACKAGE__->load_components('DynamicSubclass'); +__PACKAGE__->table('ships'); +__PACKAGE__->add_columns( + body_id => { data_type => 'int', is_nullable => 0 }, + shipyard_id => { data_type => 'int', is_nullable => 0 }, + date_started => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, + date_available => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, + type => { data_type => 'varchar', size => 30, is_nullable => 0 }, # probe, colony_ship, spy_pod, cargo_ship, space_station, smuggler_ship, mining_platform_ship, terraforming_platform_ship, gas_giant_settlement_ship + task => { data_type => 'varchar', size => 30, is_nullable => 0 }, # Docked, Building, Travelling, Mining, Defend, Orbiting + name => { data_type => 'varchar', size => 30, is_nullable => 0 }, + speed => { data_type => 'int', is_nullable => 0 }, + stealth => { data_type => 'int', is_nullable => 0 }, + combat => { data_type => 'int', is_nullable => 0 }, + hold_size => { data_type => 'int', is_nullable => 0 }, + payload => { data_type => 'mediumblob', is_nullable => 1, 'serializer_class' => 'JSON' }, + roundtrip => { data_type => 'bit', default_value => 0 }, + direction => { data_type => 'varchar', size => 3, is_nullable => 0 }, # in || out + foreign_body_id => { data_type => 'int', is_nullable => 1 }, + foreign_star_id => { data_type => 'int', is_nullable => 1 }, + fleet_speed => { data_type => 'int', is_nullable => 0 }, + berth_level => { data_type => 'int', is_nullable => 0 }, +); +__PACKAGE__->typecast_map(type => { + 'probe' => 'Lacuna::DB::Result::Ships::Probe', + 'stake' => 'Lacuna::DB::Result::Ships::Stake', + 'supply_pod' => 'Lacuna::DB::Result::Ships::SupplyPod', + 'supply_pod2' => 'Lacuna::DB::Result::Ships::SupplyPod2', + 'supply_pod3' => 'Lacuna::DB::Result::Ships::SupplyPod3', + 'supply_pod4' => 'Lacuna::DB::Result::Ships::SupplyPod4', + 'placebo' => 'Lacuna::DB::Result::Ships::Placebo', + 'placebo2' => 'Lacuna::DB::Result::Ships::Placebo2', + 'placebo3' => 'Lacuna::DB::Result::Ships::Placebo3', + 'placebo4' => 'Lacuna::DB::Result::Ships::Placebo4', + 'placebo5' => 'Lacuna::DB::Result::Ships::Placebo5', + 'placebo6' => 'Lacuna::DB::Result::Ships::Placebo6', + 'short_range_colony_ship' => 'Lacuna::DB::Result::Ships::ShortRangeColonyShip', + 'colony_ship' => 'Lacuna::DB::Result::Ships::ColonyShip', + 'spy_pod' => 'Lacuna::DB::Result::Ships::SpyPod', + 'cargo_ship' => 'Lacuna::DB::Result::Ships::CargoShip', + 'space_station' => 'Lacuna::DB::Result::Ships::SpaceStation', + 'smuggler_ship' => 'Lacuna::DB::Result::Ships::SmugglerShip', + 'mining_platform_ship' => 'Lacuna::DB::Result::Ships::MiningPlatformShip', + 'terraforming_platform_ship' => 'Lacuna::DB::Result::Ships::TerraformingPlatformShip', + 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Ships::GasGiantSettlementPlatformShip', + 'scanner' => 'Lacuna::DB::Result::Ships::Scanner', + 'surveyor' => 'Lacuna::DB::Result::Ships::Surveyor', + 'detonator' => 'Lacuna::DB::Result::Ships::Detonator', + 'excavator' => 'Lacuna::DB::Result::Ships::Excavator', + 'scow' => 'Lacuna::DB::Result::Ships::Scow', + 'scow_large' => 'Lacuna::DB::Result::Ships::ScowLarge', + 'scow_mega' => 'Lacuna::DB::Result::Ships::ScowMega', + 'scow_fast' => 'Lacuna::DB::Result::Ships::ScowFast', + 'freighter' => 'Lacuna::DB::Result::Ships::Freighter', + 'dory' => 'Lacuna::DB::Result::Ships::Dory', + 'barge' => 'Lacuna::DB::Result::Ships::Barge', + 'galleon' => 'Lacuna::DB::Result::Ships::Galleon', + 'hulk' => 'Lacuna::DB::Result::Ships::Hulk', + 'hulk_huge' => 'Lacuna::DB::Result::Ships::HulkHuge', + 'hulk_fast' => 'Lacuna::DB::Result::Ships::HulkFast', + 'snark' => 'Lacuna::DB::Result::Ships::Snark', + 'snark2' => 'Lacuna::DB::Result::Ships::Snark2', + 'snark3' => 'Lacuna::DB::Result::Ships::Snark3', + 'spy_shuttle' => 'Lacuna::DB::Result::Ships::SpyShuttle', + 'drone' => 'Lacuna::DB::Result::Ships::Drone', + 'fighter' => 'Lacuna::DB::Result::Ships::Fighter', + 'sweeper' => 'Lacuna::DB::Result::Ships::Sweeper', + 'bleeder' => 'Lacuna::DB::Result::Ships::Bleeder', + 'thud' => 'Lacuna::DB::Result::Ships::Thud', + 'observatory_seeker' => 'Lacuna::DB::Result::Ships::ObservatorySeeker', + 'spaceport_seeker' => 'Lacuna::DB::Result::Ships::SpacePortSeeker', + 'security_ministry_seeker' => 'Lacuna::DB::Result::Ships::SecurityMinistrySeeker', +}); + +with 'Lacuna::Role::Container'; + +__PACKAGE__->belongs_to('body', 'Lacuna::DB::Result::Map::Body', 'body_id'); +__PACKAGE__->belongs_to('foreign_star', 'Lacuna::DB::Result::Map::Star', 'foreign_star_id'); +__PACKAGE__->belongs_to('foreign_body', 'Lacuna::DB::Result::Map::Body', 'foreign_body_id'); + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::University', level => 1 } ]; +use constant base_food_cost => 1; +use constant base_water_cost => 1; +use constant base_energy_cost => 1; +use constant base_ore_cost => 1; +use constant base_time_cost => 1; +use constant base_waste_cost => 1; +use constant base_speed => 1; +use constant base_combat => 0; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant base_berth_level => 1; +use constant pilotable => 0; +use constant target_building => []; +use constant build_tags => []; +use constant splash_radius => 0; + +sub max_occupants { + my $self = shift; + return 0 unless $self->pilotable; + return int($self->hold_size / 350); +} + +sub arrive { + my $self = shift; + eval {$self->handle_arrival_procedures}; # throws exceptions to stop subsequent actions from happening + my $reason = $@; + if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { + # this is an expected exception, it means one of the roles took over + return; + } + elsif ($reason) { + # this is unexpected, so let's rethrow + confess $reason; + } + + # no exceptions, so we either need to go home or land + if ($self->direction eq 'out') { + $self->turn_around->update; + } + else { + $self->land->update; + } +} + +sub handle_arrival_procedures { + my $self = shift; + $self->note_arrival; +} + +sub note_arrival { + my $self = shift; + Lacuna->cache->increment($self->type.'_arrive_'.$self->foreign_body_id.$self->foreign_star_id, $self->body->empire_id,1, 60*60*24*30); +} + +sub is_available { + my ($self) = @_; + return ($self->task eq 'Docked'); +} + +sub can_send_to_target { + my $self = shift; + unless ($self->task eq 'Docked') { + confess [1010, 'That ship is busy.']; + } + return 1; +} + +sub can_recall { + my $self = shift; + unless ($self->task ~~ [qw(Defend Orbiting)]) { + confess [1010, 'That ship is busy.']; + } + return 1; +} + +sub type_formatted { + my $self = shift; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + + $type =~ s/_/ /g; + $type =~ s/\b(\w)/\u$1/g; + return $type; +} + +sub date_started_formatted { + my $self = shift; + return format_date($self->date_started); +} + +sub date_available_formatted { + my $self = shift; + return format_date($self->date_available); +} + +sub get_status { + my ($self, $target) = @_; + my %status = ( + id => $self->id, + name => $self->name, + type_human => $self->type_formatted, + type => $self->type, + task => $self->task, + speed => $self->speed, + fleet_speed => $self->fleet_speed, + stealth => $self->stealth, + combat => $self->combat, + hold_size => $self->hold_size, + berth_level => $self->berth_level, + date_started => $self->date_started_formatted, + date_available => $self->date_available_formatted, + max_occupants => $self->max_occupants, + payload => $self->format_description_of_payload, + can_scuttle => ($self->task eq 'Docked') ? 1 : 0, + can_recall => ($self->task ~~ [qw(Defend Orbiting)]) ? 1 : 0, + ); + if ($target) { + $status{estimated_travel_time} = $self->calculate_travel_time($target); + } + if ($self->task eq 'Travelling') { + my $body = $self->body; + my $target = ($self->foreign_body_id) ? $self->foreign_body : $self->foreign_star; + my $from = { + id => $body->id, + name => $body->name, + type => 'body', + }; + my $to = { + id => $target->id, + name => $target->name, + type => (ref $target eq 'Lacuna::DB::Result::Map::Star') ? 'star' : 'body', + }; + if ($self->direction ne 'out') { + my $temp = $from; + $from = $to; + $to = $temp; + } + $status{to} = $to; + $status{from} = $from; + $status{date_arrives} = $status{date_available}; + } + elsif ($self->task ~~ [qw(Defend Orbiting)]) { + my $body = $self->body; + my $from = { + id => $body->id, + name => $body->name, + type => 'body', + }; + my $orbiting = { + id => $self->foreign_body_id, + name => $self->foreign_body->name, + type => 'body', + x => $self->foreign_body->x, + y => $self->foreign_body->y, + }; + $status{from} = $from; + $status{orbiting} = $orbiting; + } + return \%status; +} + +sub seconds_remaining { + my $self = shift; + return time - $self->date_available->epoch; +} + +sub turn_around { + my $self = shift; + $self->direction( ($self->direction eq 'out') ? 'in' : 'out' ); +# $self->date_available(DateTime->now->add_duration( $self->date_available - $self->date_started )); + $self->fleet_speed(0); + my $target = ($self->foreign_body_id) ? $self->foreign_body : $self->foreign_star; + $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($target))); + $self->date_started(DateTime->now); + return $self; +} + +sub send { + my ($self, %options ) = @_; + $self->date_started(DateTime->now); + $self->task('Travelling'); + $self->payload($options{payload} || {}); + $self->roundtrip($options{roundtrip} || 0); + $self->direction($options{direction} || 'out'); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { + $self->foreign_body_id($options{target}->id); + $self->foreign_body($options{target}); + $self->foreign_star_id(undef); + $self->foreign_star(undef); + } + elsif ($options{target}->isa('Lacuna::DB::Result::Map::Star')) { + $self->foreign_star_id($options{target}->id); + $self->foreign_star($options{target}); + $self->foreign_body_id(undef); + $self->foreign_body(undef); + } + else { + confess [1002, 'You cannot send a ship to a non-existant target.']; + } + $self->update; + return $self; +} + +sub finish_construction { + my ($self) = @_; + $self->body->empire->add_medal($self->type); + $self->task('Docked'); + $self->date_available(DateTime->now); + $self->update; +} + +sub orbit { + my ($self) = @_; + $self->task('Orbiting'); + $self->date_available(DateTime->now); + return $self; +} + +sub defend { + my ($self) = @_; + $self->task('Defend'); + $self->date_available(DateTime->now); + return $self; +} + +sub land { + my ($self) = @_; + $self->task('Docked'); + $self->fleet_speed(0); + $self->date_available(DateTime->now); + $self->payload({}); + return $self; +} + + + + +# DISTANCE + + + +sub calculate_travel_time { + my ($self, $target) = @_; + + my $distance = $self->body->calculate_distance_to_target($target); + my $speed = $self->speed; + if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { + $speed = $self->fleet_speed; + } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); + $speed ||= 1; + my $hours = $distance / $speed; + my $seconds = 60 * 60 * $hours; + return sprintf('%.0f', $seconds); +} + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); -- 2.51.2 From f881f7c4f648c30447839735b72f4a66c9b93eac Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 05:24:48 -0400 Subject: [PATCH 13/31] Added Fleet SQL --- lib/Lacuna/DB/Result/Fleet.pm | 133 +++++++++++++++++----------------- var/upgrades/3.fleet.sql | 31 ++++++++ 2 files changed, 98 insertions(+), 66 deletions(-) create mode 100644 var/upgrades/3.fleet.sql diff --git a/lib/Lacuna/DB/Result/Fleet.pm b/lib/Lacuna/DB/Result/Fleet.pm index f6941df7..5557e8a4 100644 --- a/lib/Lacuna/DB/Result/Fleet.pm +++ b/lib/Lacuna/DB/Result/Fleet.pm @@ -1,4 +1,4 @@ -package Lacuna::DB::Result::Ships; +package Lacuna::DB::Result::Fleet; use Moose; use utf8; @@ -18,14 +18,15 @@ has 'hostile_action' => ( sub _build_hostile_action { 0 } __PACKAGE__->load_components('DynamicSubclass'); -__PACKAGE__->table('ships'); +__PACKAGE__->table('fleet'); __PACKAGE__->add_columns( body_id => { data_type => 'int', is_nullable => 0 }, + mark => { data_type => 'varchar', size => 10, is_nullable => 0 }, shipyard_id => { data_type => 'int', is_nullable => 0 }, date_started => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, date_available => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, - type => { data_type => 'varchar', size => 30, is_nullable => 0 }, # probe, colony_ship, spy_pod, cargo_ship, space_station, smuggler_ship, mining_platform_ship, terraforming_platform_ship, gas_giant_settlement_ship - task => { data_type => 'varchar', size => 30, is_nullable => 0 }, # Docked, Building, Travelling, Mining, Defend, Orbiting + type => { data_type => 'varchar', size => 30, is_nullable => 0 }, + task => { data_type => 'varchar', size => 30, is_nullable => 0 }, name => { data_type => 'varchar', size => 30, is_nullable => 0 }, speed => { data_type => 'int', is_nullable => 0 }, stealth => { data_type => 'int', is_nullable => 0 }, @@ -40,54 +41,54 @@ __PACKAGE__->add_columns( berth_level => { data_type => 'int', is_nullable => 0 }, ); __PACKAGE__->typecast_map(type => { - 'probe' => 'Lacuna::DB::Result::Ships::Probe', - 'stake' => 'Lacuna::DB::Result::Ships::Stake', - 'supply_pod' => 'Lacuna::DB::Result::Ships::SupplyPod', - 'supply_pod2' => 'Lacuna::DB::Result::Ships::SupplyPod2', - 'supply_pod3' => 'Lacuna::DB::Result::Ships::SupplyPod3', - 'supply_pod4' => 'Lacuna::DB::Result::Ships::SupplyPod4', - 'placebo' => 'Lacuna::DB::Result::Ships::Placebo', - 'placebo2' => 'Lacuna::DB::Result::Ships::Placebo2', - 'placebo3' => 'Lacuna::DB::Result::Ships::Placebo3', - 'placebo4' => 'Lacuna::DB::Result::Ships::Placebo4', - 'placebo5' => 'Lacuna::DB::Result::Ships::Placebo5', - 'placebo6' => 'Lacuna::DB::Result::Ships::Placebo6', - 'short_range_colony_ship' => 'Lacuna::DB::Result::Ships::ShortRangeColonyShip', - 'colony_ship' => 'Lacuna::DB::Result::Ships::ColonyShip', - 'spy_pod' => 'Lacuna::DB::Result::Ships::SpyPod', - 'cargo_ship' => 'Lacuna::DB::Result::Ships::CargoShip', - 'space_station' => 'Lacuna::DB::Result::Ships::SpaceStation', - 'smuggler_ship' => 'Lacuna::DB::Result::Ships::SmugglerShip', - 'mining_platform_ship' => 'Lacuna::DB::Result::Ships::MiningPlatformShip', - 'terraforming_platform_ship' => 'Lacuna::DB::Result::Ships::TerraformingPlatformShip', - 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Ships::GasGiantSettlementPlatformShip', - 'scanner' => 'Lacuna::DB::Result::Ships::Scanner', - 'surveyor' => 'Lacuna::DB::Result::Ships::Surveyor', - 'detonator' => 'Lacuna::DB::Result::Ships::Detonator', - 'excavator' => 'Lacuna::DB::Result::Ships::Excavator', - 'scow' => 'Lacuna::DB::Result::Ships::Scow', - 'scow_large' => 'Lacuna::DB::Result::Ships::ScowLarge', - 'scow_mega' => 'Lacuna::DB::Result::Ships::ScowMega', - 'scow_fast' => 'Lacuna::DB::Result::Ships::ScowFast', - 'freighter' => 'Lacuna::DB::Result::Ships::Freighter', - 'dory' => 'Lacuna::DB::Result::Ships::Dory', - 'barge' => 'Lacuna::DB::Result::Ships::Barge', - 'galleon' => 'Lacuna::DB::Result::Ships::Galleon', - 'hulk' => 'Lacuna::DB::Result::Ships::Hulk', - 'hulk_huge' => 'Lacuna::DB::Result::Ships::HulkHuge', - 'hulk_fast' => 'Lacuna::DB::Result::Ships::HulkFast', - 'snark' => 'Lacuna::DB::Result::Ships::Snark', - 'snark2' => 'Lacuna::DB::Result::Ships::Snark2', - 'snark3' => 'Lacuna::DB::Result::Ships::Snark3', - 'spy_shuttle' => 'Lacuna::DB::Result::Ships::SpyShuttle', - 'drone' => 'Lacuna::DB::Result::Ships::Drone', - 'fighter' => 'Lacuna::DB::Result::Ships::Fighter', - 'sweeper' => 'Lacuna::DB::Result::Ships::Sweeper', - 'bleeder' => 'Lacuna::DB::Result::Ships::Bleeder', - 'thud' => 'Lacuna::DB::Result::Ships::Thud', - 'observatory_seeker' => 'Lacuna::DB::Result::Ships::ObservatorySeeker', - 'spaceport_seeker' => 'Lacuna::DB::Result::Ships::SpacePortSeeker', - 'security_ministry_seeker' => 'Lacuna::DB::Result::Ships::SecurityMinistrySeeker', + 'probe' => 'Lacuna::DB::Result::Fleet::Probe', + 'stake' => 'Lacuna::DB::Result::Fleet::Stake', + 'supply_pod' => 'Lacuna::DB::Result::Fleet::SupplyPod', + 'supply_pod2' => 'Lacuna::DB::Result::Fleet::SupplyPod2', + 'supply_pod3' => 'Lacuna::DB::Result::Fleet::SupplyPod3', + 'supply_pod4' => 'Lacuna::DB::Result::Fleet::SupplyPod4', + 'placebo' => 'Lacuna::DB::Result::Fleet::Placebo', + 'placebo2' => 'Lacuna::DB::Result::Fleet::Placebo2', + 'placebo3' => 'Lacuna::DB::Result::Fleet::Placebo3', + 'placebo4' => 'Lacuna::DB::Result::Fleet::Placebo4', + 'placebo5' => 'Lacuna::DB::Result::Fleet::Placebo5', + 'placebo6' => 'Lacuna::DB::Result::Fleet::Placebo6', + 'short_range_colony_ship' => 'Lacuna::DB::Result::Fleet::ShortRangeColonyShip', + 'colony_ship' => 'Lacuna::DB::Result::Fleet::ColonyShip', + 'spy_pod' => 'Lacuna::DB::Result::Fleet::SpyPod', + 'cargo_ship' => 'Lacuna::DB::Result::Fleet::CargoShip', + 'space_station' => 'Lacuna::DB::Result::Fleet::SpaceStation', + 'smuggler_ship' => 'Lacuna::DB::Result::Fleet::SmugglerShip', + 'mining_platform_ship' => 'Lacuna::DB::Result::Fleet::MiningPlatformShip', + 'terraforming_platform_ship' => 'Lacuna::DB::Result::Fleet::TerraformingPlatformShip', + 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Fleet::GasGiantSettlementPlatformShip', + 'scanner' => 'Lacuna::DB::Result::Fleet::Scanner', + 'surveyor' => 'Lacuna::DB::Result::Fleet::Surveyor', + 'detonator' => 'Lacuna::DB::Result::Fleet::Detonator', + 'excavator' => 'Lacuna::DB::Result::Fleet::Excavator', + 'scow' => 'Lacuna::DB::Result::Fleet::Scow', + 'scow_large' => 'Lacuna::DB::Result::Fleet::ScowLarge', + 'scow_mega' => 'Lacuna::DB::Result::Fleet::ScowMega', + 'scow_fast' => 'Lacuna::DB::Result::Fleet::ScowFast', + 'freighter' => 'Lacuna::DB::Result::Fleet::Freighter', + 'dory' => 'Lacuna::DB::Result::Fleet::Dory', + 'barge' => 'Lacuna::DB::Result::Fleet::Barge', + 'galleon' => 'Lacuna::DB::Result::Fleet::Galleon', + 'hulk' => 'Lacuna::DB::Result::Fleet::Hulk', + 'hulk_huge' => 'Lacuna::DB::Result::Fleet::HulkHuge', + 'hulk_fast' => 'Lacuna::DB::Result::Fleet::HulkFast', + 'snark' => 'Lacuna::DB::Result::Fleet::Snark', + 'snark2' => 'Lacuna::DB::Result::Fleet::Snark2', + 'snark3' => 'Lacuna::DB::Result::Fleet::Snark3', + 'spy_shuttle' => 'Lacuna::DB::Result::Fleet::SpyShuttle', + 'drone' => 'Lacuna::DB::Result::Fleet::Drone', + 'fighter' => 'Lacuna::DB::Result::Fleet::Fighter', + 'sweeper' => 'Lacuna::DB::Result::Fleet::Sweeper', + 'bleeder' => 'Lacuna::DB::Result::Fleet::Bleeder', + 'thud' => 'Lacuna::DB::Result::Fleet::Thud', + 'observatory_seeker' => 'Lacuna::DB::Result::Fleet::ObservatorySeeker', + 'spaceport_seeker' => 'Lacuna::DB::Result::Fleet::SpacePortSeeker', + 'security_ministry_seeker' => 'Lacuna::DB::Result::Fleet::SecurityMinistrySeeker', }); with 'Lacuna::Role::Container'; @@ -122,7 +123,7 @@ sub max_occupants { sub arrive { my $self = shift; eval {$self->handle_arrival_procedures}; # throws exceptions to stop subsequent actions from happening - my $reason = $@; + my $reason = $@; if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { # this is an expected exception, it means one of the roles took over return; @@ -166,7 +167,7 @@ sub can_send_to_target { sub can_recall { my $self = shift; - unless ($self->task ~~ [qw(Defend Orbiting)]) { + unless ($self->task ~~ [qw(Defend Orbiting)]) { confess [1010, 'That ship is busy.']; } return 1; @@ -249,16 +250,16 @@ sub get_status { name => $body->name, type => 'body', }; - my $orbiting = { - id => $self->foreign_body_id, + my $orbiting = { + id => $self->foreign_body_id, name => $self->foreign_body->name, - type => 'body', - x => $self->foreign_body->x, - y => $self->foreign_body->y, + type => 'body', + x => $self->foreign_body->x, + y => $self->foreign_body->y, }; - $status{from} = $from; - $status{orbiting} = $orbiting; - } + $status{from} = $from; + $status{orbiting} = $orbiting; + } return \%status; } @@ -316,15 +317,15 @@ sub finish_construction { } sub orbit { - my ($self) = @_; - $self->task('Orbiting'); + my ($self) = @_; + $self->task('Orbiting'); $self->date_available(DateTime->now); return $self; } sub defend { - my ($self) = @_; - $self->task('Defend'); + my ($self) = @_; + $self->task('Defend'); $self->date_available(DateTime->now); return $self; } diff --git a/var/upgrades/3.fleet.sql b/var/upgrades/3.fleet.sql new file mode 100644 index 00000000..da71e190 --- /dev/null +++ b/var/upgrades/3.fleet.sql @@ -0,0 +1,31 @@ + +create table fleet ( + id int(11) not null auto_increment, + body_id int(11) not null, + shipyard_id int(11) not null, + date_started datetime not null, + date_available datetime not null, + mark varchar(10) not null, + type varchar(30) not null, + task varchar(30) not null, + name varchar(30) not null, + speed int(11) not null, + stealth int(11) not null, + combat int(11) not null, + hold_size int(11) not null, + payload mediumblob, + roundtrip tinyint(4) not null default 0, + direction varchar(3) not null, + foreign_body_id int(11), + foreign_star_id int(11), + berth_level tinyint(4) default 1, + primary key (id), + key f_mark (mark), + key f_idx_body_id (body_id), + key f_idx_foreign_body_id (foreign_body_id), + key f_idx_foreign_star_id (foreign_star_id), + constraint wc_f_body_id foreign key (body_id) references body (id), + constraint wc_f_foreign_body_id foreign key (foreign_body_id) references body (id), + constraint wc_f_foreign_star_id foreign key (foreign_star_id) references star (id) +); + -- 2.51.2 From 57c3db7ae6d45b4e0ef9e8115ba3b74aa4c25e8f Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 14/31] Started adding new fleet action API calls --- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f2267570..76e3776f 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,11 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { +<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; +======= + confess [1009, 'Invalid day.']; +>>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -238,8 +242,13 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } +<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; +======= + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; +>>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -259,7 +268,11 @@ sub find_arrival { } sub send_ship_types { +<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; +======= + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; +>>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -309,7 +322,12 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { +<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; +======= + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; +>>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -320,7 +338,11 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } +<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); +======= + +>>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From f95ea619ffe2e54f1498715599442e1626fad09e Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 06:25:13 -0400 Subject: [PATCH 15/31] Added Fleet files --- bin/convert_ships_to_fleets.pl | 81 +++++++++++++++++++ lib/Lacuna/DB/Result/Fleet/Barge.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Bleeder.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/CargoShip.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/ColonyShip.pm | 30 +++++++ lib/Lacuna/DB/Result/Fleet/Detonator.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Dory.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Drone.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Excavator.pm | 25 ++++++ lib/Lacuna/DB/Result/Fleet/Fighter.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Freighter.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Galleon.pm | 26 ++++++ .../Fleet/GasGiantSettlementPlatformShip.pm | 26 ++++++ lib/Lacuna/DB/Result/Fleet/Hulk.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/HulkFast.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/HulkHuge.pm | 28 +++++++ .../DB/Result/Fleet/MiningPlatformShip.pm | 27 +++++++ .../DB/Result/Fleet/ObservatorySeeker.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo2.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo3.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo4.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo5.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo6.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Probe.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Scanner.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/Scow.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/ScowFast.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/ScowLarge.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/ScowMega.pm | 28 +++++++ .../DB/Result/Fleet/SecurityMinistrySeeker.pm | 29 +++++++ .../DB/Result/Fleet/ShortRangeColonyShip.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Snark.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Snark2.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/Snark3.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SpaceStation.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SpyPod.pm | 32 ++++++++ lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/Stake.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Surveyor.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/Sweeper.pm | 27 +++++++ .../Result/Fleet/TerraformingPlatformShip.pm | 25 ++++++ lib/Lacuna/DB/Result/Fleet/Thud.pm | 29 +++++++ 49 files changed, 1436 insertions(+) create mode 100644 bin/convert_ships_to_fleets.pl create mode 100644 lib/Lacuna/DB/Result/Fleet/Barge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Bleeder.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/CargoShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ColonyShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Detonator.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Dory.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Drone.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Excavator.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Fighter.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Freighter.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Galleon.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Hulk.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/HulkFast.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/HulkHuge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo4.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo5.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo6.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Probe.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Scanner.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Scow.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowFast.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowLarge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowMega.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpaceStation.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpyPod.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Stake.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Surveyor.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Sweeper.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Thud.pm diff --git a/bin/convert_ships_to_fleets.pl b/bin/convert_ships_to_fleets.pl new file mode 100644 index 00000000..9c3c3c9c --- /dev/null +++ b/bin/convert_ships_to_fleets.pl @@ -0,0 +1,81 @@ +use 5.010; +use strict; +use feature "switch"; +use lib '/data/Lacuna-Server/lib'; +use Lacuna::DB; +use Lacuna; +use Lacuna::Util qw(randint format_date); +use Getopt::Long; +$|=1; +our $quiet; +GetOptions( + 'quiet' => \$quiet, +); + +out('Started'); +my $start = time; + +out('Loading DB'); +our $db = Lacuna->db; + +out('Complete all ships being built'); +my $ships = $db->resultset('Lacuna::DB::Result::Ships')->search({ + task => 'Building', +}); +my $now = DateTime->now; +while (my $ship = $ships->next) { + $ship->update({ + task => 'Docked', + date_available => $now, + }); +} + +out('Zip all ships to their destination'); +my $ships = $db->resultset('Lacuna::DB::Result::Ships')->search({ + task => 'Travelling' +}); +while (my $ship = $ships->next) { + out('Zooming ship '.$ship->id); + $ship->update({ + date_available => $now, + }); +} + +out('Do a final tick of all planets'); +my $planets_rs = $db->resultset('Lacuna::DB::Result::Map::Body'); +my $planets = $planets_rs->search({ empire_id => {'!=' => 0} }); +while (my $planet = $planets->next) { + out('Ticking '.$planet->name); + eval{$planet->tick}; + my $reason = $@; + if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { + # this is an expected exception, it means one of the roles took over + } + elsif ( ref $reason eq 'ARRAY') { + out(sprintf("Ticking %s resulted in errno: %d, %s\n", $planet->name, $reason->[0], $reason->[1])); + } + elsif ( $reason ) { + out(sprintf("Ticking %s resulted in: %s\n", $planet->name, $reason)); + } +} + +$ships = $db->resultset('Lacuna::DB::Result::Ships')->search({},{ + group_by => [qw(body_id type task name speed stealth combat hold_size)], +}); + +my $finish = time; +out('Finished'); +out((($finish - $start)/60)." minutes have elapsed"); + + +############### +## SUBROUTINES +############### + +sub out { + my ($message) = @_; + unless ($quiet) { + say format_date(DateTime->now), " ", $message; + } +} + diff --git a/lib/Lacuna/DB/Result/Fleet/Barge.pm b/lib/Lacuna/DB/Result/Fleet/Barge.pm new file mode 100644 index 00000000..4149490e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Barge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Barge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 5 } ]; +use constant base_food_cost => 650; +use constant base_water_cost => 1900; +use constant base_energy_cost => 6100; +use constant base_ore_cost => 10300; +use constant base_time_cost => 5000; +use constant base_waste_cost => 900; +use constant base_speed => 1100; +use constant base_stealth => 2450; +use constant base_hold_size => 800; +use constant base_berth_level => 1; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Bleeder.pm b/lib/Lacuna/DB/Result/Fleet/Bleeder.pm new file mode 100644 index 00000000..af4cab2f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Bleeder.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Bleeder; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 12 } ]; +use constant base_food_cost => 8000; +use constant base_water_cost => 21000; +use constant base_energy_cost => 69010; +use constant base_ore_cost => 95020; +use constant base_time_cost => 60 * 60 * 13; +use constant base_waste_cost => 12200; +use constant base_speed => 600; +use constant base_stealth => 2850; +use constant base_combat => 1700; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployBleeder"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/CargoShip.pm b/lib/Lacuna/DB/Result/Fleet/CargoShip.pm new file mode 100644 index 00000000..36711848 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/CargoShip.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::CargoShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 10 } ]; +use constant base_food_cost => 1200; +use constant base_water_cost => 3600; +use constant base_energy_cost => 12000; +use constant base_ore_cost => 20400; +use constant base_time_cost => 7200; +use constant base_waste_cost => 1500; +use constant base_speed => 1050; +use constant base_stealth => 1500; +use constant base_hold_size => 1700; +use constant base_berth_level => 5; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm b/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm new file mode 100644 index 00000000..41505e9a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm @@ -0,0 +1,30 @@ +package Lacuna::DB::Result::Fleet::ColonyShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 5 } ]; +use constant base_food_cost => 45000; +use constant base_water_cost => 45000; +use constant base_energy_cost => 45000; +use constant base_ore_cost => 45000; +use constant base_time_cost => 60 * 60 * 24; +use constant base_waste_cost => 10000; +use constant base_combat => 1000; +use constant base_speed => 455; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::Colonize"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Detonator.pm b/lib/Lacuna/DB/Result/Fleet/Detonator.pm new file mode 100644 index 00000000..6e7cd68d --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Detonator.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Detonator; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 1 } ]; +use constant base_food_cost => 6000; +use constant base_water_cost => 15600; +use constant base_energy_cost => 113600; +use constant base_ore_cost => 97200; +use constant base_time_cost => 86400; +use constant base_waste_cost => 25200; +use constant base_combat => 1850; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::AsteroidStarUninhabited"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DestroyProbes"; +with "Lacuna::Role::Ship::Arrive::DestroyMinersExcavators"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Dory.pm b/lib/Lacuna/DB/Result/Fleet/Dory.pm new file mode 100644 index 00000000..c6419c74 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Dory.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Dory; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 1 } ]; +use constant base_food_cost => 350; +use constant base_water_cost => 700; +use constant base_energy_cost => 3250; +use constant base_ore_cost => 5500; +use constant base_time_cost => 3800; +use constant base_waste_cost => 400; +use constant base_speed => 1250; +use constant base_stealth => 4100; +use constant base_hold_size => 400; +use constant base_berth_level => 1; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Drone.pm b/lib/Lacuna/DB/Result/Fleet/Drone.pm new file mode 100644 index 00000000..28069c9a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Drone.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Drone; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Security', level => 1 } ]; +use constant base_food_cost => 250; +use constant base_water_cost => 650; +use constant base_energy_cost => 4050; +use constant base_ore_cost => 3550; +use constant base_time_cost => 3650; +use constant base_waste_cost => 1050; +use constant base_speed => 0; +use constant base_combat => 6000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::NotAllowed"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Excavator.pm b/lib/Lacuna/DB/Result/Fleet/Excavator.pm new file mode 100644 index 00000000..2abf774e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Excavator.pm @@ -0,0 +1,25 @@ +package Lacuna::DB::Result::Fleet::Excavator; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Archaeology', level => 11 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 5000; +use constant base_energy_cost => 20000; +use constant base_ore_cost => 80000; +use constant base_time_cost => 8 * 60 * 60; +use constant base_waste_cost => 10000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['Exploration']; + +with "Lacuna::Role::Ship::Send::AsteroidAndUninhabited"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployExcavator"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Fighter.pm b/lib/Lacuna/DB/Result/Fleet/Fighter.pm new file mode 100644 index 00000000..8f53cc36 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Fighter.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Fighter; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PilotTraining', level => 1 } ]; +use constant base_food_cost => 1000; +use constant base_water_cost => 2600; +use constant base_energy_cost => 16200; +use constant base_ore_cost => 14200; +use constant base_time_cost => 60 * 60 * 4; +use constant base_waste_cost => 4200; +use constant base_combat => 4000; +use constant base_speed => 2000; +use constant pilotable => 1; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Body"; +with "Lacuna::Role::Ship::Arrive::Defend"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Freighter.pm b/lib/Lacuna/DB/Result/Fleet/Freighter.pm new file mode 100644 index 00000000..20ecde1a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Freighter.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Freighter; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 20 } ]; +use constant base_food_cost => 3600; +use constant base_water_cost => 10800; +use constant base_energy_cost => 36000; +use constant base_ore_cost => 61000; +use constant base_time_cost => 15000; +use constant base_waste_cost => 4800; +use constant base_speed => 900; +use constant base_stealth => 0; +use constant base_hold_size => 4000; +use constant base_berth_level => 15; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Galleon.pm b/lib/Lacuna/DB/Result/Fleet/Galleon.pm new file mode 100644 index 00000000..436b69cb --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Galleon.pm @@ -0,0 +1,26 @@ +package Lacuna::DB::Result::Fleet::Galleon; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 15 } ]; +use constant base_food_cost => 2500; +use constant base_water_cost => 7500; +use constant base_energy_cost => 25000; +use constant base_ore_cost => 40200; +use constant base_time_cost => 11200; +use constant base_waste_cost => 3200; +use constant base_speed => 1250; +use constant base_stealth => 0; +use constant base_hold_size => 1750; +use constant base_berth_level => 10; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm new file mode 100644 index 00000000..42e21e55 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm @@ -0,0 +1,26 @@ +package Lacuna::DB::Result::Fleet::GasGiantSettlementPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::GasGiantLab', level => 1 } ]; +use constant base_food_cost => 36000; +use constant base_water_cost => 90000; +use constant base_energy_cost => 340000; +use constant base_ore_cost => 250000; +use constant base_time_cost => 48000; +use constant base_waste_cost => 53000; +use constant base_speed => 500; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::GasGiant"; +with "Lacuna::Role::Ship::Arrive::AddGasGiantPlatform"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Hulk.pm b/lib/Lacuna/DB/Result/Fleet/Hulk.pm new file mode 100644 index 00000000..017bdc88 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Hulk.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Hulk; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 25 }]; +use constant base_food_cost => 7300; +use constant base_water_cost => 23000; +use constant base_energy_cost => 75000; +use constant base_ore_cost => 124000; +use constant base_time_cost => 20000; +use constant base_waste_cost => 11000; +use constant base_speed => 600; +use constant base_stealth => 0; +use constant base_hold_size => 7900; +use constant base_berth_level => 20; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/HulkFast.pm b/lib/Lacuna/DB/Result/Fleet/HulkFast.pm new file mode 100644 index 00000000..d08a8dee --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/HulkFast.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::HulkFast; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 25 }, + { class=> 'Lacuna::DB::Result::Building::Propulsion', level => 30 } ]; +use constant base_food_cost => 15000; +use constant base_water_cost => 30000; +use constant base_energy_cost => 500000; +use constant base_ore_cost => 1000000; +use constant base_time_cost => 43200; +use constant base_waste_cost => 100000; +use constant base_speed => 750; +use constant base_stealth => 0; +use constant base_hold_size => 10000; +use constant base_berth_level => 25; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm b/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm new file mode 100644 index 00000000..c57e6bea --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::HulkHuge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 30 } ]; +use constant base_food_cost => 90000; +use constant base_water_cost => 150000; +use constant base_energy_cost => 15000000; +use constant base_ore_cost => 10000000; +use constant base_time_cost => 256000; +use constant base_waste_cost => 1000000; +use constant base_speed => 350; +use constant base_stealth => 0; +use constant base_hold_size => 170100; +use constant base_berth_level => 30; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm new file mode 100644 index 00000000..c02f702f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::MiningPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Ore::Ministry', level => 1 }]; +use constant base_food_cost => 4800; +use constant base_water_cost => 14400; +use constant base_energy_cost => 96000; +use constant base_ore_cost => 81600; +use constant base_time_cost => 28800; +use constant base_waste_cost => 12000; +use constant base_combat => 600; +use constant base_speed => 600; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Mining']; + +with "Lacuna::Role::Ship::Send::Asteroid"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployMiningPlatform"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm b/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm new file mode 100644 index 00000000..f516a4d2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::ObservatorySeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 10 }]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 170000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 2500; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::Observatory']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo.pm b/lib/Lacuna/DB/Result/Fleet/Placebo.pm new file mode 100644 index 00000000..fd59e7bc --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Placebo; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 5 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 4000; +use constant base_ore_cost => 4000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 400; +use constant base_speed => 500; +use constant base_combat => 0; +use constant base_stealth => 2500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo2.pm b/lib/Lacuna/DB/Result/Fleet/Placebo2.pm new file mode 100644 index 00000000..ef2a8ee3 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo2.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 10 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 5000; +use constant base_ore_cost => 5000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 500; +use constant base_speed => 1000; +use constant base_combat => 0; +use constant base_stealth => 4000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo II'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo3.pm b/lib/Lacuna/DB/Result/Fleet/Placebo3.pm new file mode 100644 index 00000000..ff95f603 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo3.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 15 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 6000; +use constant base_ore_cost => 6000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 600; +use constant base_speed => 1500; +use constant base_combat => 0; +use constant base_stealth => 5500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo III'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo4.pm b/lib/Lacuna/DB/Result/Fleet/Placebo4.pm new file mode 100644 index 00000000..32149049 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo4.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo4; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 20 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 7000; +use constant base_ore_cost => 7000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 700; +use constant base_speed => 2000; +use constant base_combat => 0; +use constant base_stealth => 7000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo IV'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo5.pm b/lib/Lacuna/DB/Result/Fleet/Placebo5.pm new file mode 100644 index 00000000..8e798b56 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo5.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo5; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 25 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 8000; +use constant base_ore_cost => 8000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 800; +use constant base_speed => 2500; +use constant base_combat => 0; +use constant base_stealth => 8500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo V'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo6.pm b/lib/Lacuna/DB/Result/Fleet/Placebo6.pm new file mode 100644 index 00000000..3d5e2fd6 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo6.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo6; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 30 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 9000; +use constant base_ore_cost => 9000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 900; +use constant base_speed => 3000; +use constant base_combat => 0; +use constant base_stealth => 10000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo VI'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Probe.pm b/lib/Lacuna/DB/Result/Fleet/Probe.pm new file mode 100644 index 00000000..5dbffcd2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Probe.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Probe; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Observatory', level => 1 }]; +use constant base_food_cost => 100; +use constant base_water_cost => 300; +use constant base_energy_cost => 2000; +use constant base_ore_cost => 1700; +use constant base_time_cost => 3600; +use constant base_waste_cost => 500; +use constant base_speed => 5000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Star"; +with "Lacuna::Role::Ship::Arrive::DeployProbe"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Scanner.pm b/lib/Lacuna/DB/Result/Fleet/Scanner.pm new file mode 100644 index 00000000..aa101d90 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Scanner.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Scanner; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Intelligence', level => 5 }]; +use constant base_food_cost => 150; +use constant base_water_cost => 250; +use constant base_energy_cost => 2500; +use constant base_ore_cost => 2900; +use constant base_time_cost => 3600; +use constant base_waste_cost => 520; +use constant base_speed => 3000; +use constant base_combat => 200; +use constant base_stealth => 1850; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::ScanSurface"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Scow.pm b/lib/Lacuna/DB/Result/Fleet/Scow.pm new file mode 100644 index 00000000..d1a6a1ca --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Scow.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Scow; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 10 } ]; +use constant base_food_cost => 2000; +use constant base_water_cost => 5200; +use constant base_energy_cost => 32400; +use constant base_ore_cost => 28400; +use constant base_time_cost => 14600; +use constant base_waste_cost => 8400; +use constant base_speed => 420; +use constant base_combat => 500; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowFast.pm b/lib/Lacuna/DB/Result/Fleet/ScowFast.pm new file mode 100644 index 00000000..8a2d8c78 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowFast.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::ScowFast; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 25 }, + { class=> 'Lacuna::DB::Result::Building::Propulsion', level => 25 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 10000; +use constant base_energy_cost => 100000; +use constant base_ore_cost => 60000; +use constant base_time_cost => 21600; +use constant base_waste_cost => 25000; +use constant base_speed => 700; +use constant base_combat => 500; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant base_berth_level => 20; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm b/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm new file mode 100644 index 00000000..55bd8e5a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::ScowLarge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 20 } ]; +use constant base_food_cost => 10000; +use constant base_water_cost => 32000; +use constant base_energy_cost => 170000; +use constant base_ore_cost => 120000; +use constant base_time_cost => 32000; +use constant base_waste_cost => 50000; +use constant base_speed => 325; +use constant base_combat => 600; +use constant base_stealth => 0; +use constant base_hold_size => 12000; +use constant base_berth_level => 15; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowMega.pm b/lib/Lacuna/DB/Result/Fleet/ScowMega.pm new file mode 100644 index 00000000..84443cd2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowMega.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::ScowMega; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 30 } ]; +use constant base_food_cost => 60000; +use constant base_water_cost => 180000; +use constant base_energy_cost => 6000000; +use constant base_ore_cost => 1500000; +use constant base_time_cost => 98000; +use constant base_waste_cost => 25000000; +use constant base_speed => 100; +use constant base_combat => 0; +use constant base_stealth => 0; +use constant base_hold_size => 300000; +use constant base_berth_level => 25; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm b/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm new file mode 100644 index 00000000..4b7d61fa --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SecurityMinistrySeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 20 } ]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 180000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 3500; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::Security','Lacuna::DB::Result::Building::Module::PoliceStation']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm b/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm new file mode 100644 index 00000000..70a3545f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::ShortRangeColonyShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 3 } ]; +use constant base_food_cost => 15000; +use constant base_water_cost => 15000; +use constant base_energy_cost => 15000; +use constant base_ore_cost => 15000; +use constant base_time_cost => 60 * 60 * 8; +use constant base_waste_cost => 7000; +use constant base_combat => 1000; +use constant base_speed => 700; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Range"; +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::Colonize"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm b/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm new file mode 100644 index 00000000..c1a85463 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::SmugglerShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 1 } ]; +use constant base_food_cost => 1500; +use constant base_water_cost => 3900; +use constant base_energy_cost => 27000; +use constant base_ore_cost => 16800; +use constant base_time_cost => 28800; +use constant base_waste_cost => 1800; +use constant base_speed => 1700; +use constant base_stealth => 5000; +use constant base_hold_size => 520; +use constant base_berth_level => 10; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark.pm b/lib/Lacuna/DB/Result/Fleet/Snark.pm new file mode 100644 index 00000000..3fbf66ce --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Snark; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 5 } ]; +use constant base_food_cost => 18000; +use constant base_water_cost => 46800; +use constant base_energy_cost => 145000; +use constant base_ore_cost => 195030; +use constant base_time_cost => 60 * 60 * 16; +use constant base_waste_cost => 39600; +use constant base_speed => 1000; +use constant base_stealth => 2400; +use constant base_combat => 2000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark2.pm b/lib/Lacuna/DB/Result/Fleet/Snark2.pm new file mode 100644 index 00000000..cd24da8a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark2.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::Snark2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 18 } ]; +use constant base_food_cost => 37000; +use constant base_water_cost => 64600; +use constant base_energy_cost => 194000; +use constant base_ore_cost => 252230; +use constant base_time_cost => 58400; +use constant base_waste_cost => 59500; +use constant base_speed => 1000; +use constant base_stealth => 2600; +use constant base_combat => 4000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; +use constant type_formatted => 'Snark II'; +use constant splash_radius => 1; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark3.pm b/lib/Lacuna/DB/Result/Fleet/Snark3.pm new file mode 100644 index 00000000..62db2a19 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark3.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::Snark3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 25 } ]; +use constant base_food_cost => 47000; +use constant base_water_cost => 84600; +use constant base_energy_cost => 224000; +use constant base_ore_cost => 352230; +use constant base_time_cost => 58400; +use constant base_waste_cost => 69500; +use constant base_speed => 1000; +use constant base_stealth => 3000; +use constant base_combat => 5000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; +use constant type_formatted => 'Snark III'; +use constant splash_radius => 2; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm b/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm new file mode 100644 index 00000000..0f53ee1b --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SpacePortSeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 15 } ]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 160000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 3000; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::SpacePort']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm b/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm new file mode 100644 index 00000000..fc809839 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::SpaceStation; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Embassy', level => 20 } ]; +use constant base_food_cost => 8000000; +use constant base_water_cost => 8000000; +use constant base_energy_cost => 8000000; +use constant base_ore_cost => 8000000; +use constant base_time_cost => 60 * 60 * 72; +use constant base_waste_cost => 1000000; +use constant base_speed => 10; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => [qw(War Intelligence)]; +use constant type_formatted => 'Space Station Hull'; + +with "Lacuna::Role::Ship::Send::Planet"; +with 'Lacuna::Role::Ship::Send::Uninhabited'; +with 'Lacuna::Role::Ship::Send::MemberOfAlliance'; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::ConvertToStation"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpyPod.pm b/lib/Lacuna/DB/Result/Fleet/SpyPod.pm new file mode 100644 index 00000000..474a2933 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpyPod.pm @@ -0,0 +1,32 @@ +package Lacuna::DB::Result::Fleet::SpyPod; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Espionage', level => 1 } ]; +use constant base_food_cost => 200; +use constant base_water_cost => 600; +use constant base_energy_cost => 4000; +use constant base_ore_cost => 3400; +use constant base_time_cost => 3600; +use constant base_waste_cost => 1000; +use constant base_speed => 2000; +use constant base_stealth => 7000; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Intelligence']; +use constant max_occupants => 1; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::LoadWithSpies"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm b/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm new file mode 100644 index 00000000..59b8bfa1 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::SpyShuttle; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Espionage', level => 15 } ]; +use constant base_food_cost => 750; +use constant base_water_cost => 2300; +use constant base_energy_cost => 15000; +use constant base_ore_cost => 13000; +use constant base_time_cost => 7200; +use constant base_waste_cost => 5000; +use constant base_speed => 2000; +use constant base_stealth => 6200; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Intelligence']; +use constant max_occupants => 4; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::LoadWithSpies"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::Orbit"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Stake.pm b/lib/Lacuna/DB/Result/Fleet/Stake.pm new file mode 100644 index 00000000..90fa6759 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Stake.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Stake; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 10 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 4000; +use constant base_energy_cost => 10000; +use constant base_ore_cost => 10000; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 3500; +use constant base_speed => 3000; +use constant base_combat => 250; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 0; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::StakeAClaim"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm new file mode 100644 index 00000000..5ddd165e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::SupplyPod; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 10 } ]; +use constant base_food_cost => 1800; +use constant base_water_cost => 1900; +use constant base_energy_cost => 4500; +use constant base_ore_cost => 4500; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 5000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 400; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 5; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm new file mode 100644 index 00000000..36ff6d8b --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 15 } ]; +use constant base_food_cost => 29000; +use constant base_water_cost => 30000; +use constant base_energy_cost => 74000; +use constant base_ore_cost => 74000; +use constant base_time_cost => 60 * 60 * 4; +use constant base_waste_cost => 30000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 900; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 10; +use constant type_formatted => 'Supply Pod II'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm new file mode 100644 index 00000000..c895ea91 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 20 } ]; +use constant base_food_cost => 480000; +use constant base_water_cost => 500000; +use constant base_energy_cost => 1200000; +use constant base_ore_cost => 1200000; +use constant base_time_cost => 60 * 60 * 6; +use constant base_waste_cost => 450000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 15; +use constant type_formatted => 'Supply Pod III'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm new file mode 100644 index 00000000..5d0ef75a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod4; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 25 } ]; +use constant base_food_cost => 8000000; +use constant base_water_cost => 8500000; +use constant base_energy_cost => 20000000; +use constant base_ore_cost => 20000000; +use constant base_time_cost => 60 * 60 * 8; +use constant base_waste_cost => 2000000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 3800; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 20; +use constant type_formatted => 'Supply Pod IV'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Surveyor.pm b/lib/Lacuna/DB/Result/Fleet/Surveyor.pm new file mode 100644 index 00000000..838f2b58 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Surveyor.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Surveyor; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Intelligence', level => 10 } ]; +use constant base_food_cost => 1500; +use constant base_water_cost => 2500; +use constant base_energy_cost => 25000; +use constant base_ore_cost => 29000; +use constant base_time_cost => 60 * 60 * 6; +use constant base_waste_cost => 5200; +use constant base_speed => 3000; +use constant base_combat => 1000; +use constant base_stealth => 3000; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::SurveySurface"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Sweeper.pm b/lib/Lacuna/DB/Result/Fleet/Sweeper.pm new file mode 100644 index 00000000..97329ed1 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Sweeper.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Sweeper; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 16 } ]; +use constant base_food_cost => 5000; +use constant base_water_cost => 12000; +use constant base_energy_cost => 70000; +use constant base_ore_cost => 75000; +use constant base_time_cost => 60 * 60 * 7; +use constant base_waste_cost => 20000; +use constant base_combat => 8100; +use constant base_speed => 2600; +use constant base_stealth => 2800; +use constant pilotable => 1; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Body"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm new file mode 100644 index 00000000..de1d8faa --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm @@ -0,0 +1,25 @@ +package Lacuna::DB::Result::Fleet::TerraformingPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::TerraformingLab', level => 1 } ]; +use constant base_food_cost => 96000; +use constant base_water_cost => 180000; +use constant base_energy_cost => 310000; +use constant base_ore_cost => 226000; +use constant base_time_cost => 45000; +use constant base_waste_cost => 45000; +use constant base_speed => 550; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Arrive::AddTerraformingPlatform"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Thud.pm b/lib/Lacuna/DB/Result/Fleet/Thud.pm new file mode 100644 index 00000000..5949b0dc --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Thud.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Thud; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 3 } ]; +use constant base_food_cost => 7000; +use constant base_water_cost => 8000; +use constant base_energy_cost => 23000; +use constant base_ore_cost => 45000; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 8400; +use constant base_speed => 700; +use constant base_stealth => 1600; +use constant base_combat => 2100; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeploySmolderingCrater"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); -- 2.51.2 From cc38529d81c7a1751d69e0801a69250469730d9b Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 16/31] Started adding new fleet action API calls --- docs/SpacePort.pod | 289 +++++++++++++++++++++------ lib/Lacuna/DB/Result/Ships.pm | 20 +- lib/Lacuna/RPC/Building/SpacePort.pm | 167 +++++++++++++++- t/440_fleets.t | 32 +++ 4 files changed, 440 insertions(+), 68 deletions(-) create mode 100644 t/440_fleets.t diff --git a/docs/SpacePort.pod b/docs/SpacePort.pod index a6ff0737..28d8d061 100644 --- a/docs/SpacePort.pod +++ b/docs/SpacePort.pod @@ -61,8 +61,8 @@ Shows you all your ships whatever they are doing. "name" : "Mars" } }, - { - "id" : "id-goes-here", + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -85,11 +85,11 @@ Shows you all your ships whatever they are doing. "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3 + "x" : 4, + "y" : -3 } - }, + }, ... ], "number_of_ships" : 13, @@ -206,7 +206,87 @@ The unique id of the space port. Defaults to page 1. Shows 25 at a time. +=head2 get_fleet_for ( session_id, from_body_id, target ) + +Provides a summary of ships that can be included in a fleet action + + { + "ships" : [ + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 103, + "estimated_travel_time" : "3654", + }, + { + "type" : "sweeper", + "type_human" : "Sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 25000, + "quantity" : 26, + "estimated_travel_time" : "3745", + }, + { + "type" : "surveyor", + "type_human" : "Surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 24, + "estimated_travel_time" : "4123", + } + ... + ], + "status" : { ... } + } + +Ships are grouped according to type,speed,stealth and combat, the number of ships in each group is given. + +=head3 session_id + +A session id. + +=head3 from_body_id + +The unique id of the planet that should send the ships. + +=head3 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. =head2 get_ships_for ( session_id, from_body_id, target ) @@ -258,27 +338,27 @@ Provides a list of incoming ships and ships that are available to send to a spec ... ], "unavailable" : [ - { + { "reason" : [1009, "You can't send a detonator to a star."], - "ship" : { - "id" : "id-goes-here", - "name" : "D13", - "type_human" : "Detonator", - "type" : "detonator", - "task" : "Docked", - "speed" : "700", + "ship" : { + "id" : "id-goes-here", + "name" : "D13", + "type_human" : "Detonator", + "type" : "detonator", + "task" : "Docked", + "speed" : "700", "fleet_speed" : "0", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "01 31 2010 13:09:05 +0600" + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "01 31 2010 13:09:05 +0600" } }, ... ], - "orbiting" : [ - { - "id" : "id-goes-here", + "orbiting" : [ + { + "id" : "id-goes-here", "name" : "F13", "type_human" : "Fighter", "type" : "fighter", @@ -299,13 +379,13 @@ Provides a list of incoming ships and ships that are available to send to a spec "id" : "id-goes-here", "type" : "body", "name" : "Mars", - "x" : 4, - "y" : -3, + "x" : 4, + "y" : -3, } - }, - ... - ], + }, + ... + ], "mining_platforms" : [ { empire_id => "id-goes-here", @@ -362,7 +442,6 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. - =head2 send_ship ( session_id, ship_id, target ) Sends a ship to a specified body or star. Use with C. @@ -440,44 +519,138 @@ The unique id of the star. A set of x,y coordinates to locate the star or body. +=head2 send_ship_types ( session_id, from_body_id, target, types, arrival ) + +Sends a quantity of ships, of a specific type (type, speed, combat, stealth) to a target. + +Look at B for a summary of what ships can be sent. + +Returns the same as B showing how many ships are remaining to be sent. + +Throws 1002,1009,1010,1019 + +=head4 session_id + +A session ID. + +=head4 from_body_id + +The Unique ID of the body that should send the ships + +=head4 target + +A hash reference that can contain one of five items to identify a star or body. + + { "body_name" : "Earth" } + + { "body_id" : "id-goes-here" } + + { "star_name" : "Sol" } + + { "star_id" : "id-goes-here" } + + { "x" : 4, "y" : -3 } + +=head4 body_name + +A string with the body's name. Case insensitive, but will throw an exception for misspelling. + +=head4 body_id + +The unique id of the body. + +=head4 star_name + +A string with the star's name. Case insensitive, but will throw an exception for misspelling. + +=head4 star_id + +The unique id of the star. + +=head4 x | y + +A set of x,y coordinates to locate the star or body. + +=head4 types + +An array reference that contains the specification of the ships to send and the quantity. + + [ + { + "type" : "sweeper", + "speed" : 10166, + "stealth" : 10948, + "combat" : 33372, + "quantity" : 100 + }, + { + "type" : "surveyor", + "speed" : 9030, + "stealth" : 9030, + "combat" : 3220, + "quantity" : 10 + } + ] + +=head4 arrival + +A hash reference of the required arrival time. + + { + "day" : "23", + "hour" : "12", + "minute" : "01", + "second" : "30" + } + +So long as the sending body has that quantity of ships with those specifications, then the +ships will be sent. + +Ships will be set to arrive at the B time and date, which can be up to 28 days in +the future. B is the day of the month, either the remainder of the current month, or +the start of next month. e.g. if the current date is 23rd of January, then a B of 23 +will refer to today whereas 3 would refer to 3rd of February. + +If an arrival time is set which is prior to the earliest arrival time of the slowest ship, +then an exception is raised. =head2 send_fleet ( session_id, ship_ids, target, [ set_speed ] ) Sends a fleet of ships to a specified body or star. Use with C. - { + { "status" : { ... }, - "fleet" : [ - "ship" : { - "id" : "id-goes-here", - "name" : "P13", - "type_human" : "Probe", - "type" : "probe", - "task" : "Travelling", - "speed" : "1200", - "fleet_speed" : "250", - "stealth" : "0", - "hold_size" : "0", - "date_started" : "01 31 2010 13:09:05 +0600", - "date_available" : "02 01 2010 10:08:33 +0600", - "date_arrives" : "02 01 2010 10:08:33 +0600", - "can_recall" : "0", - "can_scuttle" : "0", - "from" : { - "id" : "id-goes-here", - "type" : "body", - "name" : "Earth" - }, - "to" : { - "id" : "id-goes-here", - "type" : "star", - "name" : "Sol" - } - }, - ... - ] - } + "fleet" : [ + "ship" : { + "id" : "id-goes-here", + "name" : "P13", + "type_human" : "Probe", + "type" : "probe", + "task" : "Travelling", + "speed" : "1200", + "fleet_speed" : "250", + "stealth" : "0", + "hold_size" : "0", + "date_started" : "01 31 2010 13:09:05 +0600", + "date_available" : "02 01 2010 10:08:33 +0600", + "date_arrives" : "02 01 2010 10:08:33 +0600", + "can_recall" : "0", + "can_scuttle" : "0", + "from" : { + "id" : "id-goes-here", + "type" : "body", + "name" : "Earth" + }, + "to" : { + "id" : "id-goes-here", + "type" : "star", + "name" : "Sol" + } + }, + ... + ] +} Throws 1002, 1009, 1010, 1016. @@ -485,7 +658,7 @@ Throws 1002, 1009, 1010, 1016. A session id. -=head3 ship_id +=head3 ship_ids An array reference of ship ids to send. diff --git a/lib/Lacuna/DB/Result/Ships.pm b/lib/Lacuna/DB/Result/Ships.pm index b2637bef..f6941df7 100644 --- a/lib/Lacuna/DB/Result/Ships.pm +++ b/lib/Lacuna/DB/Result/Ships.pm @@ -174,7 +174,13 @@ sub can_recall { sub type_formatted { my $self = shift; - my $type = $self->type; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + $type =~ s/_/ /g; $type =~ s/\b(\w)/\u$1/g; return $type; @@ -279,7 +285,9 @@ sub send { $self->payload($options{payload} || {}); $self->roundtrip($options{roundtrip} || 0); $self->direction($options{direction} || 'out'); - $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($options{target}))); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { $self->foreign_body_id($options{target}->id); $self->foreign_body($options{target}); @@ -339,11 +347,19 @@ sub land { sub calculate_travel_time { my ($self, $target) = @_; + my $distance = $self->body->calculate_distance_to_target($target); my $speed = $self->speed; if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { $speed = $self->fleet_speed; } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); $speed ||= 1; my $hours = $distance / $speed; my $seconds = 60 * 60 * $hours; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f6ce7b94..15568088 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -41,11 +41,55 @@ sub find_target { } } unless (defined $target) { - confess [ 1002, 'Could not find the target.', $target]; + confess [ 1002, 'Could not find the target.', $target]; } return $target; } +sub get_fleet_for { + my ($self, $session_id, $body_id, $target_params) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + + my $berth = Lacuna->db->resultset('Lacuna::DB::Result::Building')->search( { + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $body_id, + efficiency => 100, + } )->get_column('level')->max; + my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( + { + body_id => $body->id, + task => 'docked', + },{ + '+select' => [{count => 'id'}], + '+as' => [ qw(quantity) ], + group_by => [ qw(type speed stealth combat hold_size) ], + }, + ); + my $summary; + while (my $ship_group = $ships->next) { + my $travel_time = Lacuna::DB::Result::Ships->travel_time($body,$target,$ship_group->speed); + my $type_human = Lacuna::DB::Result::Ships->type_human($ship_group->type); + my $summation = { + type => $ship_group->type, + type_human => $type_human, + speed => int($ship_group->speed), + stealth => int($ship_group->stealth), + combat => int($ship_group->combat), + quantity => $ship_group->get_column('quantity'), + estimated_travel_time => $travel_time, + }; + push @$summary, $summation; + } + my %out = ( + status => $self->format_status($empire, $body), + ships => $summary, + ); + return \%out; +} + sub get_ships_for { my ($self, $session_id, $body_id, $target_params) = @_; my $empire = $self->get_empire_by_session($session_id); @@ -55,12 +99,12 @@ sub get_ships_for { my @incoming; my $incoming_rs = $ships->search({ - task => 'Travelling', - direction => 'out', - 'body.empire_id' => $empire->id, - }, - { join => 'body' } - ); + task => 'Travelling', + direction => 'out', + 'body.empire_id' => $empire->id, + },{ + join => 'body', + }); if ($target->isa('Lacuna::DB::Result::Map::Star')) { $incoming_rs = $incoming_rs->search({foreign_star_id => $target->id}); } @@ -171,6 +215,113 @@ sub send_ship { } } +sub find_arrival { + my ($self, $arrival_params) = @_; + + my $now = DateTime->now; + my $year = $now->year, + my $month = $now->month; + my $mon_end = DateTime->last_day_of_month(year => $year, month => $month); + my $day = $arrival_params->{day}; + my $hour = $arrival_params->{hour}; + my $minute = $arrival_params->{minute}; + my $second = $arrival_params->{second}; + + if (not defined $day or $day < 1 or $day > $mon_end->day) { + confess [1009, 'Invalid day.']; + } + if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { + confess [1002, 'Invalid hour.']; + } + if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { + confess [1002, 'Invalid minute.']; + } + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; + } + if ($day < $now->day) { + # Then it must be a day next month + $mon_end->add( days => $day); + $year = $mon_end->year; + $month = $mon_end->month; + } + my $arrival = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $minute, + second => $second, + ); + return $arrival; +} + +sub send_ship_types { + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + + my $empire = $self->get_empire_by_session($session_id); + my $body = $self->get_body($empire, $body_id); + my $target = $self->find_target($target_params); + my $arrival = $self->find_arrival($arrival_params); + + # calculate the total ships before the expense of any database operations. + my $total_ships = 0; + map {$total_ships += $_->{quantity}} @$type_params; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + if ($total_ships > $max_ships) { + confess [1009, 'Too many ships for a fleet.']; + } + + my $ship_ref; + my $do_captcha_check = 0; + foreach my $type_param (@$type_params) { + foreach my $arg (qw(speed stealth combat quantity)) { + confess [1002, "$arg cannot be negative."] if $type_param->{$arg} < 0; + confess [1002, "$arg must be an integer."] if $type_param->{$arg} != int($type_param->{$arg}); + } + my $type = $type_param->{type}; + my $speed = $type_param->{speed}; + my $stealth = $type_param->{stealth}; + my $combat = $type_param->{combat}; + my $quantity = $type_param->{quantity}; + confess [1009, "Cannot send more than one excavator"] if ($type eq 'excavator' and $quantity > 1); + + # TODO Must check for valid berth levels + # + my $ships_rs = Lacuna->db->resultset('Ships')->search({ + body_id => $body->id, + task => 'Docked', + type => $type, + speed => $speed, + stealth => $stealth, + combat => $combat, + }); + if ($ships_rs->count < $quantity) { + confess [1009, "Cannot find $quantity of $type ships."]; + } + my @ships = $ships_rs->search(undef,{rows => $quantity}); + my $ship = $ships[0]; + # We only need to check one of the ships + $ship->can_send_to_target($target); + if (not $do_captcha_check and $ship->hostile_action) { + $do_captcha_check = 1; + } + foreach my $ship (@ships) { + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; + } + } + if ($do_captcha_check) { + $empire->current_session->check_captcha; + } + # If we get here without exceptions, then all ships can be sent + foreach my $ship (values %$ship_ref) { + $ship->fleet_speed(1); + $ship->send(target => $target, arrival => $arrival); + } + +} + sub send_fleet { my ($self, $session_id, $ship_ids, $target_params, $set_speed) = @_; $set_speed //= 0; @@ -905,7 +1056,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t new file mode 100644 index 00000000..3e51eef0 --- /dev/null +++ b/t/440_fleets.t @@ -0,0 +1,32 @@ +use lib '../lib'; + +use strict; +use warnings; + +use Test::More tests => 10; +use Test::Deep; +use Data::Dumper; +use 5.010; +use DateTime; + +use TestHelper; +my $tester = TestHelper->new->use_existing_test_empire; +my $session_id = $tester->session->id; +my $empire = $tester->empire; +my $home = $empire->home_planet; +my $command = $home->command; + +my $result; + +my $space_port = Lacuna->db->resultset('Building')->search({ + class => 'Lacuna::DB::Result::Building::SpacePort', + body_id => $home->id, + },{ + rows => 1, +})->single; + +$result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); + +END { +# TestHelper->clear_all_test_empires; +} -- 2.51.2 From 83e66009592c426820284c292ca3c546d7697754 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 13:48:35 -0400 Subject: [PATCH 17/31] Minor changes --- lib/Lacuna/RPC/Building/SpacePort.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 15568088..dfe69c99 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -257,7 +257,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -319,7 +319,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - + return $self->get_fleet_for($session, $body_id, $target_params); } sub send_fleet { -- 2.51.2 From ac33cfaf5338049b7093892e0fc8f51a51ebc1bd Mon Sep 17 00:00:00 2001 From: ian docherty Date: Tue, 15 May 2012 05:09:30 -0400 Subject: [PATCH 18/31] Fix error checking for send_ship_types --- lib/Lacuna/RPC/Building/SpacePort.pm | 16 +++++++++------- t/440_fleets.t | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index dfe69c99..12564f1b 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -6,6 +6,8 @@ no warnings qw(uninitialized); extends 'Lacuna::RPC::Building'; use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); +use Data::Dumper; + use feature "switch"; sub app_url { @@ -228,7 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { - confess [1009, 'Invalid day.']; + confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -236,8 +238,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; + if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { + confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; } if ($day < $now->day) { # Then it must be a day next month @@ -257,7 +259,7 @@ sub find_arrival { } sub send_ship_types { - my ($self, $session_id, $body_id, $target_params, $type_params, $arrival) = @_; + my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -319,7 +321,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } - return $self->get_fleet_for($session, $body_id, $target_params); + return $self->get_fleet_for($session_id, $body_id, $target_params); } sub send_fleet { @@ -327,7 +329,7 @@ sub send_fleet { $set_speed //= 0; my $empire = $self->get_empire_by_session($session_id); my $target = $self->find_target($target_params); - my $max_ships = Lacuna->config->get('ships_per_fleet') || 20; + my $max_ships = Lacuna->config->get('ships_per_fleet') || 50; if (@$ship_ids > $max_ships) { confess [1009, 'Too many ships for a fleet.']; } @@ -1056,7 +1058,7 @@ around 'view' => sub { return $out; }; -__PACKAGE__->register_rpc_method_names(qw(get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); +__PACKAGE__->register_rpc_method_names(qw(send_ship_types get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); no Moose; diff --git a/t/440_fleets.t b/t/440_fleets.t index 3e51eef0..d4113cd9 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -27,6 +27,23 @@ my $space_port = Lacuna->db->resultset('Building')->search({ $result = $tester->post('spaceport','get_fleet_for', [$session_id, $home->id, {body_name => 'DeLambert-5-28'}]); +my ($sweepers) = grep {$_->{type} eq 'sweeper'} @{$result->{result}{ships}}; + +diag Dumper(\$sweepers); + +Lacuna->cache->set('captcha', $session_id, { guid => 1111, solution => 1111 }, 60 * 30 ); +$result = $tester->post('captcha','solve', [$session_id, 1111, 1111]); +is($result->{result}, 1, 'Solved captcha'); + + +$result = $tester->post('spaceport','send_ship_types', [ + $session_id, + $home->id, + {body_name => 'DeLambert-5-28'}, + [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], + {day => 10, hour => 1, minute => 1, second => 15}, +]); + END { # TestHelper->clear_all_test_empires; } -- 2.51.2 From f72ac1a1ec60c3228bae71345b44689d1c866116 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Thu, 17 May 2012 14:30:27 -0400 Subject: [PATCH 19/31] Send all ships in the fleet, not just one. --- lib/Lacuna/RPC/Building/SpacePort.pm | 3 +-- t/440_fleets.t | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 12564f1b..0175be4e 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -309,8 +309,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; + $ship_ref->{$ship->id} = $ship; } } if ($do_captcha_check) { diff --git a/t/440_fleets.t b/t/440_fleets.t index d4113cd9..787056fe 100644 --- a/t/440_fleets.t +++ b/t/440_fleets.t @@ -41,7 +41,7 @@ $result = $tester->post('spaceport','send_ship_types', [ $home->id, {body_name => 'DeLambert-5-28'}, [{type => 'sweeper', speed => $sweepers->{speed}, stealth => $sweepers->{stealth}, combat => $sweepers->{combat}, quantity => 10}], - {day => 10, hour => 1, minute => 1, second => 15}, + {day => 10, hour => 0, minute => 0, second => 0}, ]); END { -- 2.51.2 From 7a55329bf4b6a5ea7c1d39cb48270dabdd7b6220 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 20/31] Started adding new fleet action API calls --- lib/Lacuna/RPC/Building/SpacePort.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 0175be4e..e8419821 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { - confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; + confess [1009, 'Invalid day.']; } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -1059,7 +1059,6 @@ around 'view' => sub { __PACKAGE__->register_rpc_method_names(qw(send_ship_types get_fleet_for view_foreign_ships get_ships_for send_ship send_fleet recall_ship recall_all recall_spies scuttle_ship name_ship prepare_fetch_spies fetch_spies prepare_send_spies send_spies view_ships_orbiting view_ships_travelling view_all_ships view_battle_logs)); - no Moose; __PACKAGE__->meta->make_immutable; -- 2.51.2 From ce94968f4aead12798f06c41e794a8d6f915dd6b Mon Sep 17 00:00:00 2001 From: ian docherty Date: Tue, 15 May 2012 05:09:30 -0400 Subject: [PATCH 21/31] Fix error checking for send_ship_types --- lib/Lacuna/RPC/Building/SpacePort.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index e8419821..f2267570 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { - confess [1009, 'Invalid day.']; + confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; -- 2.51.2 From a75e97b95e619d1cb440088d060f4a178775f13d Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 22/31] Started adding new fleet action API calls --- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f2267570..76e3776f 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,11 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { +<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; +======= + confess [1009, 'Invalid day.']; +>>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -238,8 +242,13 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } +<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; +======= + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; +>>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -259,7 +268,11 @@ sub find_arrival { } sub send_ship_types { +<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; +======= + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; +>>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -309,7 +322,12 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { +<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; +======= + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; +>>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -320,7 +338,11 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } +<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); +======= + +>>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From 78a7ae24c24253e05cac811e1a5ab9474cf353c9 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 13:48:35 -0400 Subject: [PATCH 23/31] Minor changes --- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 76e3776f..f2267570 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,11 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { -<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; -======= - confess [1009, 'Invalid day.']; ->>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -242,13 +238,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } -<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; -======= - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; ->>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -268,11 +259,7 @@ sub find_arrival { } sub send_ship_types { -<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; -======= - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; ->>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -322,12 +309,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { -<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; -======= - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; ->>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -338,11 +320,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } -<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); -======= - ->>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From 315b965fed150156702f37ace95d8c35fa87a64b Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 04:50:41 -0400 Subject: [PATCH 24/31] Start to convert ships into fleets --- lib/Lacuna/DB/Result/Fleet.pm | 370 ++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 lib/Lacuna/DB/Result/Fleet.pm diff --git a/lib/Lacuna/DB/Result/Fleet.pm b/lib/Lacuna/DB/Result/Fleet.pm new file mode 100644 index 00000000..f6941df7 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet.pm @@ -0,0 +1,370 @@ +package Lacuna::DB::Result::Ships; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result'; +use Lacuna::Util qw(format_date randint); +use DateTime; +use feature "switch"; + +has 'hostile_action' => ( + is => 'rw', + isa => 'Bool', + lazy => 1, + builder => '_build_hostile_action', +); + +sub _build_hostile_action { 0 } + +__PACKAGE__->load_components('DynamicSubclass'); +__PACKAGE__->table('ships'); +__PACKAGE__->add_columns( + body_id => { data_type => 'int', is_nullable => 0 }, + shipyard_id => { data_type => 'int', is_nullable => 0 }, + date_started => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, + date_available => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, + type => { data_type => 'varchar', size => 30, is_nullable => 0 }, # probe, colony_ship, spy_pod, cargo_ship, space_station, smuggler_ship, mining_platform_ship, terraforming_platform_ship, gas_giant_settlement_ship + task => { data_type => 'varchar', size => 30, is_nullable => 0 }, # Docked, Building, Travelling, Mining, Defend, Orbiting + name => { data_type => 'varchar', size => 30, is_nullable => 0 }, + speed => { data_type => 'int', is_nullable => 0 }, + stealth => { data_type => 'int', is_nullable => 0 }, + combat => { data_type => 'int', is_nullable => 0 }, + hold_size => { data_type => 'int', is_nullable => 0 }, + payload => { data_type => 'mediumblob', is_nullable => 1, 'serializer_class' => 'JSON' }, + roundtrip => { data_type => 'bit', default_value => 0 }, + direction => { data_type => 'varchar', size => 3, is_nullable => 0 }, # in || out + foreign_body_id => { data_type => 'int', is_nullable => 1 }, + foreign_star_id => { data_type => 'int', is_nullable => 1 }, + fleet_speed => { data_type => 'int', is_nullable => 0 }, + berth_level => { data_type => 'int', is_nullable => 0 }, +); +__PACKAGE__->typecast_map(type => { + 'probe' => 'Lacuna::DB::Result::Ships::Probe', + 'stake' => 'Lacuna::DB::Result::Ships::Stake', + 'supply_pod' => 'Lacuna::DB::Result::Ships::SupplyPod', + 'supply_pod2' => 'Lacuna::DB::Result::Ships::SupplyPod2', + 'supply_pod3' => 'Lacuna::DB::Result::Ships::SupplyPod3', + 'supply_pod4' => 'Lacuna::DB::Result::Ships::SupplyPod4', + 'placebo' => 'Lacuna::DB::Result::Ships::Placebo', + 'placebo2' => 'Lacuna::DB::Result::Ships::Placebo2', + 'placebo3' => 'Lacuna::DB::Result::Ships::Placebo3', + 'placebo4' => 'Lacuna::DB::Result::Ships::Placebo4', + 'placebo5' => 'Lacuna::DB::Result::Ships::Placebo5', + 'placebo6' => 'Lacuna::DB::Result::Ships::Placebo6', + 'short_range_colony_ship' => 'Lacuna::DB::Result::Ships::ShortRangeColonyShip', + 'colony_ship' => 'Lacuna::DB::Result::Ships::ColonyShip', + 'spy_pod' => 'Lacuna::DB::Result::Ships::SpyPod', + 'cargo_ship' => 'Lacuna::DB::Result::Ships::CargoShip', + 'space_station' => 'Lacuna::DB::Result::Ships::SpaceStation', + 'smuggler_ship' => 'Lacuna::DB::Result::Ships::SmugglerShip', + 'mining_platform_ship' => 'Lacuna::DB::Result::Ships::MiningPlatformShip', + 'terraforming_platform_ship' => 'Lacuna::DB::Result::Ships::TerraformingPlatformShip', + 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Ships::GasGiantSettlementPlatformShip', + 'scanner' => 'Lacuna::DB::Result::Ships::Scanner', + 'surveyor' => 'Lacuna::DB::Result::Ships::Surveyor', + 'detonator' => 'Lacuna::DB::Result::Ships::Detonator', + 'excavator' => 'Lacuna::DB::Result::Ships::Excavator', + 'scow' => 'Lacuna::DB::Result::Ships::Scow', + 'scow_large' => 'Lacuna::DB::Result::Ships::ScowLarge', + 'scow_mega' => 'Lacuna::DB::Result::Ships::ScowMega', + 'scow_fast' => 'Lacuna::DB::Result::Ships::ScowFast', + 'freighter' => 'Lacuna::DB::Result::Ships::Freighter', + 'dory' => 'Lacuna::DB::Result::Ships::Dory', + 'barge' => 'Lacuna::DB::Result::Ships::Barge', + 'galleon' => 'Lacuna::DB::Result::Ships::Galleon', + 'hulk' => 'Lacuna::DB::Result::Ships::Hulk', + 'hulk_huge' => 'Lacuna::DB::Result::Ships::HulkHuge', + 'hulk_fast' => 'Lacuna::DB::Result::Ships::HulkFast', + 'snark' => 'Lacuna::DB::Result::Ships::Snark', + 'snark2' => 'Lacuna::DB::Result::Ships::Snark2', + 'snark3' => 'Lacuna::DB::Result::Ships::Snark3', + 'spy_shuttle' => 'Lacuna::DB::Result::Ships::SpyShuttle', + 'drone' => 'Lacuna::DB::Result::Ships::Drone', + 'fighter' => 'Lacuna::DB::Result::Ships::Fighter', + 'sweeper' => 'Lacuna::DB::Result::Ships::Sweeper', + 'bleeder' => 'Lacuna::DB::Result::Ships::Bleeder', + 'thud' => 'Lacuna::DB::Result::Ships::Thud', + 'observatory_seeker' => 'Lacuna::DB::Result::Ships::ObservatorySeeker', + 'spaceport_seeker' => 'Lacuna::DB::Result::Ships::SpacePortSeeker', + 'security_ministry_seeker' => 'Lacuna::DB::Result::Ships::SecurityMinistrySeeker', +}); + +with 'Lacuna::Role::Container'; + +__PACKAGE__->belongs_to('body', 'Lacuna::DB::Result::Map::Body', 'body_id'); +__PACKAGE__->belongs_to('foreign_star', 'Lacuna::DB::Result::Map::Star', 'foreign_star_id'); +__PACKAGE__->belongs_to('foreign_body', 'Lacuna::DB::Result::Map::Body', 'foreign_body_id'); + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::University', level => 1 } ]; +use constant base_food_cost => 1; +use constant base_water_cost => 1; +use constant base_energy_cost => 1; +use constant base_ore_cost => 1; +use constant base_time_cost => 1; +use constant base_waste_cost => 1; +use constant base_speed => 1; +use constant base_combat => 0; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant base_berth_level => 1; +use constant pilotable => 0; +use constant target_building => []; +use constant build_tags => []; +use constant splash_radius => 0; + +sub max_occupants { + my $self = shift; + return 0 unless $self->pilotable; + return int($self->hold_size / 350); +} + +sub arrive { + my $self = shift; + eval {$self->handle_arrival_procedures}; # throws exceptions to stop subsequent actions from happening + my $reason = $@; + if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { + # this is an expected exception, it means one of the roles took over + return; + } + elsif ($reason) { + # this is unexpected, so let's rethrow + confess $reason; + } + + # no exceptions, so we either need to go home or land + if ($self->direction eq 'out') { + $self->turn_around->update; + } + else { + $self->land->update; + } +} + +sub handle_arrival_procedures { + my $self = shift; + $self->note_arrival; +} + +sub note_arrival { + my $self = shift; + Lacuna->cache->increment($self->type.'_arrive_'.$self->foreign_body_id.$self->foreign_star_id, $self->body->empire_id,1, 60*60*24*30); +} + +sub is_available { + my ($self) = @_; + return ($self->task eq 'Docked'); +} + +sub can_send_to_target { + my $self = shift; + unless ($self->task eq 'Docked') { + confess [1010, 'That ship is busy.']; + } + return 1; +} + +sub can_recall { + my $self = shift; + unless ($self->task ~~ [qw(Defend Orbiting)]) { + confess [1010, 'That ship is busy.']; + } + return 1; +} + +sub type_formatted { + my $self = shift; + + return $self->type_human($self->type); +} + +sub type_human { + my ($self, $type) = @_; + + $type =~ s/_/ /g; + $type =~ s/\b(\w)/\u$1/g; + return $type; +} + +sub date_started_formatted { + my $self = shift; + return format_date($self->date_started); +} + +sub date_available_formatted { + my $self = shift; + return format_date($self->date_available); +} + +sub get_status { + my ($self, $target) = @_; + my %status = ( + id => $self->id, + name => $self->name, + type_human => $self->type_formatted, + type => $self->type, + task => $self->task, + speed => $self->speed, + fleet_speed => $self->fleet_speed, + stealth => $self->stealth, + combat => $self->combat, + hold_size => $self->hold_size, + berth_level => $self->berth_level, + date_started => $self->date_started_formatted, + date_available => $self->date_available_formatted, + max_occupants => $self->max_occupants, + payload => $self->format_description_of_payload, + can_scuttle => ($self->task eq 'Docked') ? 1 : 0, + can_recall => ($self->task ~~ [qw(Defend Orbiting)]) ? 1 : 0, + ); + if ($target) { + $status{estimated_travel_time} = $self->calculate_travel_time($target); + } + if ($self->task eq 'Travelling') { + my $body = $self->body; + my $target = ($self->foreign_body_id) ? $self->foreign_body : $self->foreign_star; + my $from = { + id => $body->id, + name => $body->name, + type => 'body', + }; + my $to = { + id => $target->id, + name => $target->name, + type => (ref $target eq 'Lacuna::DB::Result::Map::Star') ? 'star' : 'body', + }; + if ($self->direction ne 'out') { + my $temp = $from; + $from = $to; + $to = $temp; + } + $status{to} = $to; + $status{from} = $from; + $status{date_arrives} = $status{date_available}; + } + elsif ($self->task ~~ [qw(Defend Orbiting)]) { + my $body = $self->body; + my $from = { + id => $body->id, + name => $body->name, + type => 'body', + }; + my $orbiting = { + id => $self->foreign_body_id, + name => $self->foreign_body->name, + type => 'body', + x => $self->foreign_body->x, + y => $self->foreign_body->y, + }; + $status{from} = $from; + $status{orbiting} = $orbiting; + } + return \%status; +} + +sub seconds_remaining { + my $self = shift; + return time - $self->date_available->epoch; +} + +sub turn_around { + my $self = shift; + $self->direction( ($self->direction eq 'out') ? 'in' : 'out' ); +# $self->date_available(DateTime->now->add_duration( $self->date_available - $self->date_started )); + $self->fleet_speed(0); + my $target = ($self->foreign_body_id) ? $self->foreign_body : $self->foreign_star; + $self->date_available(DateTime->now->add(seconds=>$self->calculate_travel_time($target))); + $self->date_started(DateTime->now); + return $self; +} + +sub send { + my ($self, %options ) = @_; + $self->date_started(DateTime->now); + $self->task('Travelling'); + $self->payload($options{payload} || {}); + $self->roundtrip($options{roundtrip} || 0); + $self->direction($options{direction} || 'out'); + my $arrival = $options{arrival} || DateTime->now->add(seconds=>$self->calculate_travel_time($options{target})); + $self->date_available($arrival); + + if ($options{target}->isa('Lacuna::DB::Result::Map::Body')) { + $self->foreign_body_id($options{target}->id); + $self->foreign_body($options{target}); + $self->foreign_star_id(undef); + $self->foreign_star(undef); + } + elsif ($options{target}->isa('Lacuna::DB::Result::Map::Star')) { + $self->foreign_star_id($options{target}->id); + $self->foreign_star($options{target}); + $self->foreign_body_id(undef); + $self->foreign_body(undef); + } + else { + confess [1002, 'You cannot send a ship to a non-existant target.']; + } + $self->update; + return $self; +} + +sub finish_construction { + my ($self) = @_; + $self->body->empire->add_medal($self->type); + $self->task('Docked'); + $self->date_available(DateTime->now); + $self->update; +} + +sub orbit { + my ($self) = @_; + $self->task('Orbiting'); + $self->date_available(DateTime->now); + return $self; +} + +sub defend { + my ($self) = @_; + $self->task('Defend'); + $self->date_available(DateTime->now); + return $self; +} + +sub land { + my ($self) = @_; + $self->task('Docked'); + $self->fleet_speed(0); + $self->date_available(DateTime->now); + $self->payload({}); + return $self; +} + + + + +# DISTANCE + + + +sub calculate_travel_time { + my ($self, $target) = @_; + + my $distance = $self->body->calculate_distance_to_target($target); + my $speed = $self->speed; + if ( $self->fleet_speed > 0 && $self->fleet_speed < $self->speed ) { + $speed = $self->fleet_speed; + } + return $self->travel_time($self->body, $target, $speed); +} + +sub travel_time { + my ($class, $from, $target, $speed) = @_; + + my $distance = $from->calculate_distance_to_target($target); + $speed ||= 1; + my $hours = $distance / $speed; + my $seconds = 60 * 60 * $hours; + return sprintf('%.0f', $seconds); +} + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); -- 2.51.2 From d16851ed5b491633f4f520e5840921ff0bd942f3 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 05:24:48 -0400 Subject: [PATCH 25/31] Added Fleet SQL --- lib/Lacuna/DB/Result/Fleet.pm | 133 +++++++++++++++++----------------- var/upgrades/3.fleet.sql | 31 ++++++++ 2 files changed, 98 insertions(+), 66 deletions(-) create mode 100644 var/upgrades/3.fleet.sql diff --git a/lib/Lacuna/DB/Result/Fleet.pm b/lib/Lacuna/DB/Result/Fleet.pm index f6941df7..5557e8a4 100644 --- a/lib/Lacuna/DB/Result/Fleet.pm +++ b/lib/Lacuna/DB/Result/Fleet.pm @@ -1,4 +1,4 @@ -package Lacuna::DB::Result::Ships; +package Lacuna::DB::Result::Fleet; use Moose; use utf8; @@ -18,14 +18,15 @@ has 'hostile_action' => ( sub _build_hostile_action { 0 } __PACKAGE__->load_components('DynamicSubclass'); -__PACKAGE__->table('ships'); +__PACKAGE__->table('fleet'); __PACKAGE__->add_columns( body_id => { data_type => 'int', is_nullable => 0 }, + mark => { data_type => 'varchar', size => 10, is_nullable => 0 }, shipyard_id => { data_type => 'int', is_nullable => 0 }, date_started => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, date_available => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, - type => { data_type => 'varchar', size => 30, is_nullable => 0 }, # probe, colony_ship, spy_pod, cargo_ship, space_station, smuggler_ship, mining_platform_ship, terraforming_platform_ship, gas_giant_settlement_ship - task => { data_type => 'varchar', size => 30, is_nullable => 0 }, # Docked, Building, Travelling, Mining, Defend, Orbiting + type => { data_type => 'varchar', size => 30, is_nullable => 0 }, + task => { data_type => 'varchar', size => 30, is_nullable => 0 }, name => { data_type => 'varchar', size => 30, is_nullable => 0 }, speed => { data_type => 'int', is_nullable => 0 }, stealth => { data_type => 'int', is_nullable => 0 }, @@ -40,54 +41,54 @@ __PACKAGE__->add_columns( berth_level => { data_type => 'int', is_nullable => 0 }, ); __PACKAGE__->typecast_map(type => { - 'probe' => 'Lacuna::DB::Result::Ships::Probe', - 'stake' => 'Lacuna::DB::Result::Ships::Stake', - 'supply_pod' => 'Lacuna::DB::Result::Ships::SupplyPod', - 'supply_pod2' => 'Lacuna::DB::Result::Ships::SupplyPod2', - 'supply_pod3' => 'Lacuna::DB::Result::Ships::SupplyPod3', - 'supply_pod4' => 'Lacuna::DB::Result::Ships::SupplyPod4', - 'placebo' => 'Lacuna::DB::Result::Ships::Placebo', - 'placebo2' => 'Lacuna::DB::Result::Ships::Placebo2', - 'placebo3' => 'Lacuna::DB::Result::Ships::Placebo3', - 'placebo4' => 'Lacuna::DB::Result::Ships::Placebo4', - 'placebo5' => 'Lacuna::DB::Result::Ships::Placebo5', - 'placebo6' => 'Lacuna::DB::Result::Ships::Placebo6', - 'short_range_colony_ship' => 'Lacuna::DB::Result::Ships::ShortRangeColonyShip', - 'colony_ship' => 'Lacuna::DB::Result::Ships::ColonyShip', - 'spy_pod' => 'Lacuna::DB::Result::Ships::SpyPod', - 'cargo_ship' => 'Lacuna::DB::Result::Ships::CargoShip', - 'space_station' => 'Lacuna::DB::Result::Ships::SpaceStation', - 'smuggler_ship' => 'Lacuna::DB::Result::Ships::SmugglerShip', - 'mining_platform_ship' => 'Lacuna::DB::Result::Ships::MiningPlatformShip', - 'terraforming_platform_ship' => 'Lacuna::DB::Result::Ships::TerraformingPlatformShip', - 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Ships::GasGiantSettlementPlatformShip', - 'scanner' => 'Lacuna::DB::Result::Ships::Scanner', - 'surveyor' => 'Lacuna::DB::Result::Ships::Surveyor', - 'detonator' => 'Lacuna::DB::Result::Ships::Detonator', - 'excavator' => 'Lacuna::DB::Result::Ships::Excavator', - 'scow' => 'Lacuna::DB::Result::Ships::Scow', - 'scow_large' => 'Lacuna::DB::Result::Ships::ScowLarge', - 'scow_mega' => 'Lacuna::DB::Result::Ships::ScowMega', - 'scow_fast' => 'Lacuna::DB::Result::Ships::ScowFast', - 'freighter' => 'Lacuna::DB::Result::Ships::Freighter', - 'dory' => 'Lacuna::DB::Result::Ships::Dory', - 'barge' => 'Lacuna::DB::Result::Ships::Barge', - 'galleon' => 'Lacuna::DB::Result::Ships::Galleon', - 'hulk' => 'Lacuna::DB::Result::Ships::Hulk', - 'hulk_huge' => 'Lacuna::DB::Result::Ships::HulkHuge', - 'hulk_fast' => 'Lacuna::DB::Result::Ships::HulkFast', - 'snark' => 'Lacuna::DB::Result::Ships::Snark', - 'snark2' => 'Lacuna::DB::Result::Ships::Snark2', - 'snark3' => 'Lacuna::DB::Result::Ships::Snark3', - 'spy_shuttle' => 'Lacuna::DB::Result::Ships::SpyShuttle', - 'drone' => 'Lacuna::DB::Result::Ships::Drone', - 'fighter' => 'Lacuna::DB::Result::Ships::Fighter', - 'sweeper' => 'Lacuna::DB::Result::Ships::Sweeper', - 'bleeder' => 'Lacuna::DB::Result::Ships::Bleeder', - 'thud' => 'Lacuna::DB::Result::Ships::Thud', - 'observatory_seeker' => 'Lacuna::DB::Result::Ships::ObservatorySeeker', - 'spaceport_seeker' => 'Lacuna::DB::Result::Ships::SpacePortSeeker', - 'security_ministry_seeker' => 'Lacuna::DB::Result::Ships::SecurityMinistrySeeker', + 'probe' => 'Lacuna::DB::Result::Fleet::Probe', + 'stake' => 'Lacuna::DB::Result::Fleet::Stake', + 'supply_pod' => 'Lacuna::DB::Result::Fleet::SupplyPod', + 'supply_pod2' => 'Lacuna::DB::Result::Fleet::SupplyPod2', + 'supply_pod3' => 'Lacuna::DB::Result::Fleet::SupplyPod3', + 'supply_pod4' => 'Lacuna::DB::Result::Fleet::SupplyPod4', + 'placebo' => 'Lacuna::DB::Result::Fleet::Placebo', + 'placebo2' => 'Lacuna::DB::Result::Fleet::Placebo2', + 'placebo3' => 'Lacuna::DB::Result::Fleet::Placebo3', + 'placebo4' => 'Lacuna::DB::Result::Fleet::Placebo4', + 'placebo5' => 'Lacuna::DB::Result::Fleet::Placebo5', + 'placebo6' => 'Lacuna::DB::Result::Fleet::Placebo6', + 'short_range_colony_ship' => 'Lacuna::DB::Result::Fleet::ShortRangeColonyShip', + 'colony_ship' => 'Lacuna::DB::Result::Fleet::ColonyShip', + 'spy_pod' => 'Lacuna::DB::Result::Fleet::SpyPod', + 'cargo_ship' => 'Lacuna::DB::Result::Fleet::CargoShip', + 'space_station' => 'Lacuna::DB::Result::Fleet::SpaceStation', + 'smuggler_ship' => 'Lacuna::DB::Result::Fleet::SmugglerShip', + 'mining_platform_ship' => 'Lacuna::DB::Result::Fleet::MiningPlatformShip', + 'terraforming_platform_ship' => 'Lacuna::DB::Result::Fleet::TerraformingPlatformShip', + 'gas_giant_settlement_ship' => 'Lacuna::DB::Result::Fleet::GasGiantSettlementPlatformShip', + 'scanner' => 'Lacuna::DB::Result::Fleet::Scanner', + 'surveyor' => 'Lacuna::DB::Result::Fleet::Surveyor', + 'detonator' => 'Lacuna::DB::Result::Fleet::Detonator', + 'excavator' => 'Lacuna::DB::Result::Fleet::Excavator', + 'scow' => 'Lacuna::DB::Result::Fleet::Scow', + 'scow_large' => 'Lacuna::DB::Result::Fleet::ScowLarge', + 'scow_mega' => 'Lacuna::DB::Result::Fleet::ScowMega', + 'scow_fast' => 'Lacuna::DB::Result::Fleet::ScowFast', + 'freighter' => 'Lacuna::DB::Result::Fleet::Freighter', + 'dory' => 'Lacuna::DB::Result::Fleet::Dory', + 'barge' => 'Lacuna::DB::Result::Fleet::Barge', + 'galleon' => 'Lacuna::DB::Result::Fleet::Galleon', + 'hulk' => 'Lacuna::DB::Result::Fleet::Hulk', + 'hulk_huge' => 'Lacuna::DB::Result::Fleet::HulkHuge', + 'hulk_fast' => 'Lacuna::DB::Result::Fleet::HulkFast', + 'snark' => 'Lacuna::DB::Result::Fleet::Snark', + 'snark2' => 'Lacuna::DB::Result::Fleet::Snark2', + 'snark3' => 'Lacuna::DB::Result::Fleet::Snark3', + 'spy_shuttle' => 'Lacuna::DB::Result::Fleet::SpyShuttle', + 'drone' => 'Lacuna::DB::Result::Fleet::Drone', + 'fighter' => 'Lacuna::DB::Result::Fleet::Fighter', + 'sweeper' => 'Lacuna::DB::Result::Fleet::Sweeper', + 'bleeder' => 'Lacuna::DB::Result::Fleet::Bleeder', + 'thud' => 'Lacuna::DB::Result::Fleet::Thud', + 'observatory_seeker' => 'Lacuna::DB::Result::Fleet::ObservatorySeeker', + 'spaceport_seeker' => 'Lacuna::DB::Result::Fleet::SpacePortSeeker', + 'security_ministry_seeker' => 'Lacuna::DB::Result::Fleet::SecurityMinistrySeeker', }); with 'Lacuna::Role::Container'; @@ -122,7 +123,7 @@ sub max_occupants { sub arrive { my $self = shift; eval {$self->handle_arrival_procedures}; # throws exceptions to stop subsequent actions from happening - my $reason = $@; + my $reason = $@; if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { # this is an expected exception, it means one of the roles took over return; @@ -166,7 +167,7 @@ sub can_send_to_target { sub can_recall { my $self = shift; - unless ($self->task ~~ [qw(Defend Orbiting)]) { + unless ($self->task ~~ [qw(Defend Orbiting)]) { confess [1010, 'That ship is busy.']; } return 1; @@ -249,16 +250,16 @@ sub get_status { name => $body->name, type => 'body', }; - my $orbiting = { - id => $self->foreign_body_id, + my $orbiting = { + id => $self->foreign_body_id, name => $self->foreign_body->name, - type => 'body', - x => $self->foreign_body->x, - y => $self->foreign_body->y, + type => 'body', + x => $self->foreign_body->x, + y => $self->foreign_body->y, }; - $status{from} = $from; - $status{orbiting} = $orbiting; - } + $status{from} = $from; + $status{orbiting} = $orbiting; + } return \%status; } @@ -316,15 +317,15 @@ sub finish_construction { } sub orbit { - my ($self) = @_; - $self->task('Orbiting'); + my ($self) = @_; + $self->task('Orbiting'); $self->date_available(DateTime->now); return $self; } sub defend { - my ($self) = @_; - $self->task('Defend'); + my ($self) = @_; + $self->task('Defend'); $self->date_available(DateTime->now); return $self; } diff --git a/var/upgrades/3.fleet.sql b/var/upgrades/3.fleet.sql new file mode 100644 index 00000000..da71e190 --- /dev/null +++ b/var/upgrades/3.fleet.sql @@ -0,0 +1,31 @@ + +create table fleet ( + id int(11) not null auto_increment, + body_id int(11) not null, + shipyard_id int(11) not null, + date_started datetime not null, + date_available datetime not null, + mark varchar(10) not null, + type varchar(30) not null, + task varchar(30) not null, + name varchar(30) not null, + speed int(11) not null, + stealth int(11) not null, + combat int(11) not null, + hold_size int(11) not null, + payload mediumblob, + roundtrip tinyint(4) not null default 0, + direction varchar(3) not null, + foreign_body_id int(11), + foreign_star_id int(11), + berth_level tinyint(4) default 1, + primary key (id), + key f_mark (mark), + key f_idx_body_id (body_id), + key f_idx_foreign_body_id (foreign_body_id), + key f_idx_foreign_star_id (foreign_star_id), + constraint wc_f_body_id foreign key (body_id) references body (id), + constraint wc_f_foreign_body_id foreign key (foreign_body_id) references body (id), + constraint wc_f_foreign_star_id foreign key (foreign_star_id) references star (id) +); + -- 2.51.2 From bb34a44deecbb78173eeeeb3dfb38f4a09a80ab7 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 13 May 2012 05:19:39 -0400 Subject: [PATCH 26/31] Started adding new fleet action API calls --- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index f2267570..76e3776f 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,7 +230,11 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { +<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; +======= + confess [1009, 'Invalid day.']; +>>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -238,8 +242,13 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } +<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; +======= + if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { + confess [1002, 'Invalid second.']; +>>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -259,7 +268,11 @@ sub find_arrival { } sub send_ship_types { +<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; +======= + my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; +>>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -309,7 +322,12 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { +<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; +======= + my $hash = "${type}#${speed}#${stealth}#${combat}"; + $ship_ref->{$hash} = $ship; +>>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -320,7 +338,11 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } +<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); +======= + +>>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From 9304e7f1e1bec79b59462b6a3acc9a4926809195 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 06:25:13 -0400 Subject: [PATCH 27/31] Added Fleet files --- bin/convert_ships_to_fleets.pl | 81 +++++++++++++++++++ lib/Lacuna/DB/Result/Fleet/Barge.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Bleeder.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/CargoShip.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/ColonyShip.pm | 30 +++++++ lib/Lacuna/DB/Result/Fleet/Detonator.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Dory.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Drone.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Excavator.pm | 25 ++++++ lib/Lacuna/DB/Result/Fleet/Fighter.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Freighter.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Galleon.pm | 26 ++++++ .../Fleet/GasGiantSettlementPlatformShip.pm | 26 ++++++ lib/Lacuna/DB/Result/Fleet/Hulk.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/HulkFast.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/HulkHuge.pm | 28 +++++++ .../DB/Result/Fleet/MiningPlatformShip.pm | 27 +++++++ .../DB/Result/Fleet/ObservatorySeeker.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo2.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo3.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo4.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo5.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Placebo6.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Probe.pm | 24 ++++++ lib/Lacuna/DB/Result/Fleet/Scanner.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/Scow.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/ScowFast.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/ScowLarge.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/ScowMega.pm | 28 +++++++ .../DB/Result/Fleet/SecurityMinistrySeeker.pm | 29 +++++++ .../DB/Result/Fleet/ShortRangeColonyShip.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/Snark.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Snark2.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/Snark3.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SpaceStation.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/SpyPod.pm | 32 ++++++++ lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm | 31 +++++++ lib/Lacuna/DB/Result/Fleet/Stake.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod.pm | 28 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm | 29 +++++++ lib/Lacuna/DB/Result/Fleet/Surveyor.pm | 27 +++++++ lib/Lacuna/DB/Result/Fleet/Sweeper.pm | 27 +++++++ .../Result/Fleet/TerraformingPlatformShip.pm | 25 ++++++ lib/Lacuna/DB/Result/Fleet/Thud.pm | 29 +++++++ 49 files changed, 1436 insertions(+) create mode 100644 bin/convert_ships_to_fleets.pl create mode 100644 lib/Lacuna/DB/Result/Fleet/Barge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Bleeder.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/CargoShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ColonyShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Detonator.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Dory.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Drone.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Excavator.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Fighter.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Freighter.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Galleon.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Hulk.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/HulkFast.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/HulkHuge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo4.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo5.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Placebo6.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Probe.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Scanner.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Scow.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowFast.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowLarge.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ScowMega.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Snark3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpaceStation.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpyPod.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Stake.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Surveyor.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Sweeper.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm create mode 100644 lib/Lacuna/DB/Result/Fleet/Thud.pm diff --git a/bin/convert_ships_to_fleets.pl b/bin/convert_ships_to_fleets.pl new file mode 100644 index 00000000..9c3c3c9c --- /dev/null +++ b/bin/convert_ships_to_fleets.pl @@ -0,0 +1,81 @@ +use 5.010; +use strict; +use feature "switch"; +use lib '/data/Lacuna-Server/lib'; +use Lacuna::DB; +use Lacuna; +use Lacuna::Util qw(randint format_date); +use Getopt::Long; +$|=1; +our $quiet; +GetOptions( + 'quiet' => \$quiet, +); + +out('Started'); +my $start = time; + +out('Loading DB'); +our $db = Lacuna->db; + +out('Complete all ships being built'); +my $ships = $db->resultset('Lacuna::DB::Result::Ships')->search({ + task => 'Building', +}); +my $now = DateTime->now; +while (my $ship = $ships->next) { + $ship->update({ + task => 'Docked', + date_available => $now, + }); +} + +out('Zip all ships to their destination'); +my $ships = $db->resultset('Lacuna::DB::Result::Ships')->search({ + task => 'Travelling' +}); +while (my $ship = $ships->next) { + out('Zooming ship '.$ship->id); + $ship->update({ + date_available => $now, + }); +} + +out('Do a final tick of all planets'); +my $planets_rs = $db->resultset('Lacuna::DB::Result::Map::Body'); +my $planets = $planets_rs->search({ empire_id => {'!=' => 0} }); +while (my $planet = $planets->next) { + out('Ticking '.$planet->name); + eval{$planet->tick}; + my $reason = $@; + if (ref $reason eq 'ARRAY' && $reason->[0] eq -1) { + # this is an expected exception, it means one of the roles took over + } + elsif ( ref $reason eq 'ARRAY') { + out(sprintf("Ticking %s resulted in errno: %d, %s\n", $planet->name, $reason->[0], $reason->[1])); + } + elsif ( $reason ) { + out(sprintf("Ticking %s resulted in: %s\n", $planet->name, $reason)); + } +} + +$ships = $db->resultset('Lacuna::DB::Result::Ships')->search({},{ + group_by => [qw(body_id type task name speed stealth combat hold_size)], +}); + +my $finish = time; +out('Finished'); +out((($finish - $start)/60)." minutes have elapsed"); + + +############### +## SUBROUTINES +############### + +sub out { + my ($message) = @_; + unless ($quiet) { + say format_date(DateTime->now), " ", $message; + } +} + diff --git a/lib/Lacuna/DB/Result/Fleet/Barge.pm b/lib/Lacuna/DB/Result/Fleet/Barge.pm new file mode 100644 index 00000000..4149490e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Barge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Barge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 5 } ]; +use constant base_food_cost => 650; +use constant base_water_cost => 1900; +use constant base_energy_cost => 6100; +use constant base_ore_cost => 10300; +use constant base_time_cost => 5000; +use constant base_waste_cost => 900; +use constant base_speed => 1100; +use constant base_stealth => 2450; +use constant base_hold_size => 800; +use constant base_berth_level => 1; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Bleeder.pm b/lib/Lacuna/DB/Result/Fleet/Bleeder.pm new file mode 100644 index 00000000..af4cab2f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Bleeder.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Bleeder; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 12 } ]; +use constant base_food_cost => 8000; +use constant base_water_cost => 21000; +use constant base_energy_cost => 69010; +use constant base_ore_cost => 95020; +use constant base_time_cost => 60 * 60 * 13; +use constant base_waste_cost => 12200; +use constant base_speed => 600; +use constant base_stealth => 2850; +use constant base_combat => 1700; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployBleeder"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/CargoShip.pm b/lib/Lacuna/DB/Result/Fleet/CargoShip.pm new file mode 100644 index 00000000..36711848 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/CargoShip.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::CargoShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 10 } ]; +use constant base_food_cost => 1200; +use constant base_water_cost => 3600; +use constant base_energy_cost => 12000; +use constant base_ore_cost => 20400; +use constant base_time_cost => 7200; +use constant base_waste_cost => 1500; +use constant base_speed => 1050; +use constant base_stealth => 1500; +use constant base_hold_size => 1700; +use constant base_berth_level => 5; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm b/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm new file mode 100644 index 00000000..41505e9a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ColonyShip.pm @@ -0,0 +1,30 @@ +package Lacuna::DB::Result::Fleet::ColonyShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 5 } ]; +use constant base_food_cost => 45000; +use constant base_water_cost => 45000; +use constant base_energy_cost => 45000; +use constant base_ore_cost => 45000; +use constant base_time_cost => 60 * 60 * 24; +use constant base_waste_cost => 10000; +use constant base_combat => 1000; +use constant base_speed => 455; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::Colonize"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Detonator.pm b/lib/Lacuna/DB/Result/Fleet/Detonator.pm new file mode 100644 index 00000000..6e7cd68d --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Detonator.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Detonator; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 1 } ]; +use constant base_food_cost => 6000; +use constant base_water_cost => 15600; +use constant base_energy_cost => 113600; +use constant base_ore_cost => 97200; +use constant base_time_cost => 86400; +use constant base_waste_cost => 25200; +use constant base_combat => 1850; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::AsteroidStarUninhabited"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DestroyProbes"; +with "Lacuna::Role::Ship::Arrive::DestroyMinersExcavators"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Dory.pm b/lib/Lacuna/DB/Result/Fleet/Dory.pm new file mode 100644 index 00000000..c6419c74 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Dory.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Dory; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 1 } ]; +use constant base_food_cost => 350; +use constant base_water_cost => 700; +use constant base_energy_cost => 3250; +use constant base_ore_cost => 5500; +use constant base_time_cost => 3800; +use constant base_waste_cost => 400; +use constant base_speed => 1250; +use constant base_stealth => 4100; +use constant base_hold_size => 400; +use constant base_berth_level => 1; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Drone.pm b/lib/Lacuna/DB/Result/Fleet/Drone.pm new file mode 100644 index 00000000..28069c9a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Drone.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Drone; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Security', level => 1 } ]; +use constant base_food_cost => 250; +use constant base_water_cost => 650; +use constant base_energy_cost => 4050; +use constant base_ore_cost => 3550; +use constant base_time_cost => 3650; +use constant base_waste_cost => 1050; +use constant base_speed => 0; +use constant base_combat => 6000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::NotAllowed"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Excavator.pm b/lib/Lacuna/DB/Result/Fleet/Excavator.pm new file mode 100644 index 00000000..2abf774e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Excavator.pm @@ -0,0 +1,25 @@ +package Lacuna::DB::Result::Fleet::Excavator; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Archaeology', level => 11 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 5000; +use constant base_energy_cost => 20000; +use constant base_ore_cost => 80000; +use constant base_time_cost => 8 * 60 * 60; +use constant base_waste_cost => 10000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => ['Exploration']; + +with "Lacuna::Role::Ship::Send::AsteroidAndUninhabited"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployExcavator"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Fighter.pm b/lib/Lacuna/DB/Result/Fleet/Fighter.pm new file mode 100644 index 00000000..8f53cc36 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Fighter.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Fighter; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PilotTraining', level => 1 } ]; +use constant base_food_cost => 1000; +use constant base_water_cost => 2600; +use constant base_energy_cost => 16200; +use constant base_ore_cost => 14200; +use constant base_time_cost => 60 * 60 * 4; +use constant base_waste_cost => 4200; +use constant base_combat => 4000; +use constant base_speed => 2000; +use constant pilotable => 1; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Body"; +with "Lacuna::Role::Ship::Arrive::Defend"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Freighter.pm b/lib/Lacuna/DB/Result/Fleet/Freighter.pm new file mode 100644 index 00000000..20ecde1a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Freighter.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Freighter; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 20 } ]; +use constant base_food_cost => 3600; +use constant base_water_cost => 10800; +use constant base_energy_cost => 36000; +use constant base_ore_cost => 61000; +use constant base_time_cost => 15000; +use constant base_waste_cost => 4800; +use constant base_speed => 900; +use constant base_stealth => 0; +use constant base_hold_size => 4000; +use constant base_berth_level => 15; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Galleon.pm b/lib/Lacuna/DB/Result/Fleet/Galleon.pm new file mode 100644 index 00000000..436b69cb --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Galleon.pm @@ -0,0 +1,26 @@ +package Lacuna::DB::Result::Fleet::Galleon; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 15 } ]; +use constant base_food_cost => 2500; +use constant base_water_cost => 7500; +use constant base_energy_cost => 25000; +use constant base_ore_cost => 40200; +use constant base_time_cost => 11200; +use constant base_waste_cost => 3200; +use constant base_speed => 1250; +use constant base_stealth => 0; +use constant base_hold_size => 1750; +use constant base_berth_level => 10; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm new file mode 100644 index 00000000..42e21e55 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/GasGiantSettlementPlatformShip.pm @@ -0,0 +1,26 @@ +package Lacuna::DB::Result::Fleet::GasGiantSettlementPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::GasGiantLab', level => 1 } ]; +use constant base_food_cost => 36000; +use constant base_water_cost => 90000; +use constant base_energy_cost => 340000; +use constant base_ore_cost => 250000; +use constant base_time_cost => 48000; +use constant base_waste_cost => 53000; +use constant base_speed => 500; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::GasGiant"; +with "Lacuna::Role::Ship::Arrive::AddGasGiantPlatform"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Hulk.pm b/lib/Lacuna/DB/Result/Fleet/Hulk.pm new file mode 100644 index 00000000..017bdc88 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Hulk.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Hulk; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 25 }]; +use constant base_food_cost => 7300; +use constant base_water_cost => 23000; +use constant base_energy_cost => 75000; +use constant base_ore_cost => 124000; +use constant base_time_cost => 20000; +use constant base_waste_cost => 11000; +use constant base_speed => 600; +use constant base_stealth => 0; +use constant base_hold_size => 7900; +use constant base_berth_level => 20; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/HulkFast.pm b/lib/Lacuna/DB/Result/Fleet/HulkFast.pm new file mode 100644 index 00000000..d08a8dee --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/HulkFast.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::HulkFast; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 25 }, + { class=> 'Lacuna::DB::Result::Building::Propulsion', level => 30 } ]; +use constant base_food_cost => 15000; +use constant base_water_cost => 30000; +use constant base_energy_cost => 500000; +use constant base_ore_cost => 1000000; +use constant base_time_cost => 43200; +use constant base_waste_cost => 100000; +use constant base_speed => 750; +use constant base_stealth => 0; +use constant base_hold_size => 10000; +use constant base_berth_level => 25; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm b/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm new file mode 100644 index 00000000..c57e6bea --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/HulkHuge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::HulkHuge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Trade', level => 30 } ]; +use constant base_food_cost => 90000; +use constant base_water_cost => 150000; +use constant base_energy_cost => 15000000; +use constant base_ore_cost => 10000000; +use constant base_time_cost => 256000; +use constant base_waste_cost => 1000000; +use constant base_speed => 350; +use constant base_stealth => 0; +use constant base_hold_size => 170100; +use constant base_berth_level => 30; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; + + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm new file mode 100644 index 00000000..c02f702f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/MiningPlatformShip.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::MiningPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Ore::Ministry', level => 1 }]; +use constant base_food_cost => 4800; +use constant base_water_cost => 14400; +use constant base_energy_cost => 96000; +use constant base_ore_cost => 81600; +use constant base_time_cost => 28800; +use constant base_waste_cost => 12000; +use constant base_combat => 600; +use constant base_speed => 600; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Mining']; + +with "Lacuna::Role::Ship::Send::Asteroid"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeployMiningPlatform"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm b/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm new file mode 100644 index 00000000..f516a4d2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ObservatorySeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::ObservatorySeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 10 }]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 170000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 2500; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::Observatory']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo.pm b/lib/Lacuna/DB/Result/Fleet/Placebo.pm new file mode 100644 index 00000000..fd59e7bc --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::Placebo; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 5 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 4000; +use constant base_ore_cost => 4000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 400; +use constant base_speed => 500; +use constant base_combat => 0; +use constant base_stealth => 2500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo2.pm b/lib/Lacuna/DB/Result/Fleet/Placebo2.pm new file mode 100644 index 00000000..ef2a8ee3 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo2.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 10 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 5000; +use constant base_ore_cost => 5000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 500; +use constant base_speed => 1000; +use constant base_combat => 0; +use constant base_stealth => 4000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo II'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo3.pm b/lib/Lacuna/DB/Result/Fleet/Placebo3.pm new file mode 100644 index 00000000..ff95f603 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo3.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 15 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 6000; +use constant base_ore_cost => 6000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 600; +use constant base_speed => 1500; +use constant base_combat => 0; +use constant base_stealth => 5500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo III'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo4.pm b/lib/Lacuna/DB/Result/Fleet/Placebo4.pm new file mode 100644 index 00000000..32149049 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo4.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo4; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 20 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 7000; +use constant base_ore_cost => 7000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 700; +use constant base_speed => 2000; +use constant base_combat => 0; +use constant base_stealth => 7000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo IV'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo5.pm b/lib/Lacuna/DB/Result/Fleet/Placebo5.pm new file mode 100644 index 00000000..8e798b56 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo5.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo5; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 25 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 8000; +use constant base_ore_cost => 8000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 800; +use constant base_speed => 2500; +use constant base_combat => 0; +use constant base_stealth => 8500; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo V'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Placebo6.pm b/lib/Lacuna/DB/Result/Fleet/Placebo6.pm new file mode 100644 index 00000000..3d5e2fd6 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Placebo6.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Placebo6; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 30 }]; +use constant base_food_cost => 2000; +use constant base_water_cost => 2000; +use constant base_energy_cost => 9000; +use constant base_ore_cost => 9000; +use constant base_time_cost => 3600; +use constant base_waste_cost => 900; +use constant base_speed => 3000; +use constant base_combat => 0; +use constant base_stealth => 10000; +use constant base_hold_size => 0; +use constant build_tags => [qw(War)]; +use constant type_formatted => 'Placebo VI'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Probe.pm b/lib/Lacuna/DB/Result/Fleet/Probe.pm new file mode 100644 index 00000000..5dbffcd2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Probe.pm @@ -0,0 +1,24 @@ +package Lacuna::DB::Result::Fleet::Probe; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Observatory', level => 1 }]; +use constant base_food_cost => 100; +use constant base_water_cost => 300; +use constant base_energy_cost => 2000; +use constant base_ore_cost => 1700; +use constant base_time_cost => 3600; +use constant base_waste_cost => 500; +use constant base_speed => 5000; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Star"; +with "Lacuna::Role::Ship::Arrive::DeployProbe"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Scanner.pm b/lib/Lacuna/DB/Result/Fleet/Scanner.pm new file mode 100644 index 00000000..aa101d90 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Scanner.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Scanner; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Intelligence', level => 5 }]; +use constant base_food_cost => 150; +use constant base_water_cost => 250; +use constant base_energy_cost => 2500; +use constant base_ore_cost => 2900; +use constant base_time_cost => 3600; +use constant base_waste_cost => 520; +use constant base_speed => 3000; +use constant base_combat => 200; +use constant base_stealth => 1850; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::ScanSurface"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Scow.pm b/lib/Lacuna/DB/Result/Fleet/Scow.pm new file mode 100644 index 00000000..d1a6a1ca --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Scow.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Scow; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 10 } ]; +use constant base_food_cost => 2000; +use constant base_water_cost => 5200; +use constant base_energy_cost => 32400; +use constant base_ore_cost => 28400; +use constant base_time_cost => 14600; +use constant base_waste_cost => 8400; +use constant base_speed => 420; +use constant base_combat => 500; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowFast.pm b/lib/Lacuna/DB/Result/Fleet/ScowFast.pm new file mode 100644 index 00000000..8a2d8c78 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowFast.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::ScowFast; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [{ class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 25 }, + { class=> 'Lacuna::DB::Result::Building::Propulsion', level => 25 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 10000; +use constant base_energy_cost => 100000; +use constant base_ore_cost => 60000; +use constant base_time_cost => 21600; +use constant base_waste_cost => 25000; +use constant base_speed => 700; +use constant base_combat => 500; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant base_berth_level => 20; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm b/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm new file mode 100644 index 00000000..55bd8e5a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowLarge.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::ScowLarge; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 20 } ]; +use constant base_food_cost => 10000; +use constant base_water_cost => 32000; +use constant base_energy_cost => 170000; +use constant base_ore_cost => 120000; +use constant base_time_cost => 32000; +use constant base_waste_cost => 50000; +use constant base_speed => 325; +use constant base_combat => 600; +use constant base_stealth => 0; +use constant base_hold_size => 12000; +use constant base_berth_level => 15; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ScowMega.pm b/lib/Lacuna/DB/Result/Fleet/ScowMega.pm new file mode 100644 index 00000000..84443cd2 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ScowMega.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::ScowMega; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Waste::Sequestration', level => 30 } ]; +use constant base_food_cost => 60000; +use constant base_water_cost => 180000; +use constant base_energy_cost => 6000000; +use constant base_ore_cost => 1500000; +use constant base_time_cost => 98000; +use constant base_waste_cost => 25000000; +use constant base_speed => 100; +use constant base_combat => 0; +use constant base_stealth => 0; +use constant base_hold_size => 300000; +use constant base_berth_level => 25; +use constant build_tags => [qw(War WasteChain)]; + +with "Lacuna::Role::Ship::Send::PlanetAndStar"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DumpWaste"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm b/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm new file mode 100644 index 00000000..4b7d61fa --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SecurityMinistrySeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SecurityMinistrySeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 20 } ]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 180000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 3500; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::Security','Lacuna::DB::Result::Building::Module::PoliceStation']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm b/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm new file mode 100644 index 00000000..70a3545f --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/ShortRangeColonyShip.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::ShortRangeColonyShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 3 } ]; +use constant base_food_cost => 15000; +use constant base_water_cost => 15000; +use constant base_energy_cost => 15000; +use constant base_ore_cost => 15000; +use constant base_time_cost => 60 * 60 * 8; +use constant base_waste_cost => 7000; +use constant base_combat => 1000; +use constant base_speed => 700; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Range"; +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::Colonize"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm b/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm new file mode 100644 index 00000000..c1a85463 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SmugglerShip.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::SmugglerShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::CloakingLab', level => 1 } ]; +use constant base_food_cost => 1500; +use constant base_water_cost => 3900; +use constant base_energy_cost => 27000; +use constant base_ore_cost => 16800; +use constant base_time_cost => 28800; +use constant base_waste_cost => 1800; +use constant base_speed => 1700; +use constant base_stealth => 5000; +use constant base_hold_size => 520; +use constant base_berth_level => 10; +use constant pilotable => 1; +use constant build_tags => [qw(Trade Mining Intelligence SupplyChain)]; + +with "Lacuna::Role::Ship::Send::UsePush"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark.pm b/lib/Lacuna/DB/Result/Fleet/Snark.pm new file mode 100644 index 00000000..3fbf66ce --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Snark; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 5 } ]; +use constant base_food_cost => 18000; +use constant base_water_cost => 46800; +use constant base_energy_cost => 145000; +use constant base_ore_cost => 195030; +use constant base_time_cost => 60 * 60 * 16; +use constant base_waste_cost => 39600; +use constant base_speed => 1000; +use constant base_stealth => 2400; +use constant base_combat => 2000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark2.pm b/lib/Lacuna/DB/Result/Fleet/Snark2.pm new file mode 100644 index 00000000..cd24da8a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark2.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::Snark2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 18 } ]; +use constant base_food_cost => 37000; +use constant base_water_cost => 64600; +use constant base_energy_cost => 194000; +use constant base_ore_cost => 252230; +use constant base_time_cost => 58400; +use constant base_waste_cost => 59500; +use constant base_speed => 1000; +use constant base_stealth => 2600; +use constant base_combat => 4000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; +use constant type_formatted => 'Snark II'; +use constant splash_radius => 1; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Snark3.pm b/lib/Lacuna/DB/Result/Fleet/Snark3.pm new file mode 100644 index 00000000..62db2a19 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Snark3.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::Snark3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 25 } ]; +use constant base_food_cost => 47000; +use constant base_water_cost => 84600; +use constant base_energy_cost => 224000; +use constant base_ore_cost => 352230; +use constant base_time_cost => 58400; +use constant base_waste_cost => 69500; +use constant base_speed => 1000; +use constant base_stealth => 3000; +use constant base_combat => 5000; +use constant base_hold_size => 0; +use constant build_tags => ['War']; +use constant type_formatted => 'Snark III'; +use constant splash_radius => 2; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm b/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm new file mode 100644 index 00000000..0f53ee1b --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpacePortSeeker.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SpacePortSeeker; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 15 } ]; +use constant base_food_cost => 20000; +use constant base_water_cost => 50000; +use constant base_energy_cost => 160000; +use constant base_ore_cost => 200000; +use constant base_time_cost => 58500; +use constant base_waste_cost => 40000; +use constant base_speed => 1000; +use constant base_combat => 3000; +use constant base_stealth => 2700; +use constant target_building => ['Lacuna::DB::Result::Building::SpacePort']; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DamageBuilding"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm b/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm new file mode 100644 index 00000000..fc809839 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpaceStation.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::SpaceStation; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Embassy', level => 20 } ]; +use constant base_food_cost => 8000000; +use constant base_water_cost => 8000000; +use constant base_energy_cost => 8000000; +use constant base_ore_cost => 8000000; +use constant base_time_cost => 60 * 60 * 72; +use constant base_waste_cost => 1000000; +use constant base_speed => 10; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => [qw(War Intelligence)]; +use constant type_formatted => 'Space Station Hull'; + +with "Lacuna::Role::Ship::Send::Planet"; +with 'Lacuna::Role::Ship::Send::Uninhabited'; +with 'Lacuna::Role::Ship::Send::MemberOfAlliance'; +with "Lacuna::Role::Ship::Send::SpendNextColonyCost"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::ConvertToStation"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpyPod.pm b/lib/Lacuna/DB/Result/Fleet/SpyPod.pm new file mode 100644 index 00000000..474a2933 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpyPod.pm @@ -0,0 +1,32 @@ +package Lacuna::DB::Result::Fleet::SpyPod; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Espionage', level => 1 } ]; +use constant base_food_cost => 200; +use constant base_water_cost => 600; +use constant base_energy_cost => 4000; +use constant base_ore_cost => 3400; +use constant base_time_cost => 3600; +use constant base_waste_cost => 1000; +use constant base_speed => 2000; +use constant base_stealth => 7000; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Intelligence']; +use constant max_occupants => 1; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::LoadWithSpies"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::CargoExchange"; +with "Lacuna::Role::Ship::Arrive::Scuttle"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm b/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm new file mode 100644 index 00000000..59b8bfa1 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SpyShuttle.pm @@ -0,0 +1,31 @@ +package Lacuna::DB::Result::Fleet::SpyShuttle; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Espionage', level => 15 } ]; +use constant base_food_cost => 750; +use constant base_water_cost => 2300; +use constant base_energy_cost => 15000; +use constant base_ore_cost => 13000; +use constant base_time_cost => 7200; +use constant base_waste_cost => 5000; +use constant base_speed => 2000; +use constant base_stealth => 6200; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Intelligence']; +use constant max_occupants => 4; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::LoadWithSpies"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::Orbit"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Stake.pm b/lib/Lacuna/DB/Result/Fleet/Stake.pm new file mode 100644 index 00000000..90fa6759 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Stake.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Stake; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Observatory', level => 10 } ]; +use constant base_food_cost => 3000; +use constant base_water_cost => 4000; +use constant base_energy_cost => 10000; +use constant base_ore_cost => 10000; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 3500; +use constant base_speed => 3000; +use constant base_combat => 250; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 0; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Uninhabited"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::StakeAClaim"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm new file mode 100644 index 00000000..5ddd165e --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod.pm @@ -0,0 +1,28 @@ +package Lacuna::DB::Result::Fleet::SupplyPod; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 10 } ]; +use constant base_food_cost => 1800; +use constant base_water_cost => 1900; +use constant base_energy_cost => 4500; +use constant base_ore_cost => 4500; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 5000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 400; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 5; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm new file mode 100644 index 00000000..36ff6d8b --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod2.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod2; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 15 } ]; +use constant base_food_cost => 29000; +use constant base_water_cost => 30000; +use constant base_energy_cost => 74000; +use constant base_ore_cost => 74000; +use constant base_time_cost => 60 * 60 * 4; +use constant base_waste_cost => 30000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 900; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 10; +use constant type_formatted => 'Supply Pod II'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm new file mode 100644 index 00000000..c895ea91 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod3.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod3; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 20 } ]; +use constant base_food_cost => 480000; +use constant base_water_cost => 500000; +use constant base_energy_cost => 1200000; +use constant base_ore_cost => 1200000; +use constant base_time_cost => 60 * 60 * 6; +use constant base_waste_cost => 450000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 2000; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 15; +use constant type_formatted => 'Supply Pod III'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm b/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm new file mode 100644 index 00000000..5d0ef75a --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/SupplyPod4.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::SupplyPod4; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::PlanetaryCommand', level => 25 } ]; +use constant base_food_cost => 8000000; +use constant base_water_cost => 8500000; +use constant base_energy_cost => 20000000; +use constant base_ore_cost => 20000000; +use constant base_time_cost => 60 * 60 * 8; +use constant base_waste_cost => 2000000; +use constant base_speed => 1000; +use constant base_stealth => 0; +use constant base_hold_size => 3800; +use constant pilotable => 0; +use constant build_tags => [qw(Colonization)]; +use constant supply_pod_level => 20; +use constant type_formatted => 'Supply Pod IV'; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::LoadSupplyPod"; +with "Lacuna::Role::Ship::Arrive::DeploySupplyPod"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Surveyor.pm b/lib/Lacuna/DB/Result/Fleet/Surveyor.pm new file mode 100644 index 00000000..838f2b58 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Surveyor.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Surveyor; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::Intelligence', level => 10 } ]; +use constant base_food_cost => 1500; +use constant base_water_cost => 2500; +use constant base_energy_cost => 25000; +use constant base_ore_cost => 29000; +use constant base_time_cost => 60 * 60 * 6; +use constant base_waste_cost => 5200; +use constant base_speed => 3000; +use constant base_combat => 1000; +use constant base_stealth => 3000; +use constant base_hold_size => 0; +use constant build_tags => [qw(Exploration Intelligence)]; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::MaybeHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::SurveySurface"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Sweeper.pm b/lib/Lacuna/DB/Result/Fleet/Sweeper.pm new file mode 100644 index 00000000..97329ed1 --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Sweeper.pm @@ -0,0 +1,27 @@ +package Lacuna::DB::Result::Fleet::Sweeper; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 16 } ]; +use constant base_food_cost => 5000; +use constant base_water_cost => 12000; +use constant base_energy_cost => 70000; +use constant base_ore_cost => 75000; +use constant base_time_cost => 60 * 60 * 7; +use constant base_waste_cost => 20000; +use constant base_combat => 8100; +use constant base_speed => 2600; +use constant base_stealth => 2800; +use constant pilotable => 1; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Body"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm b/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm new file mode 100644 index 00000000..de1d8faa --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/TerraformingPlatformShip.pm @@ -0,0 +1,25 @@ +package Lacuna::DB::Result::Fleet::TerraformingPlatformShip; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::TerraformingLab', level => 1 } ]; +use constant base_food_cost => 96000; +use constant base_water_cost => 180000; +use constant base_energy_cost => 310000; +use constant base_ore_cost => 226000; +use constant base_time_cost => 45000; +use constant base_waste_cost => 45000; +use constant base_speed => 550; +use constant base_stealth => 0; +use constant base_hold_size => 0; +use constant pilotable => 1; +use constant build_tags => ['Colonization']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Arrive::AddTerraformingPlatform"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Fleet/Thud.pm b/lib/Lacuna/DB/Result/Fleet/Thud.pm new file mode 100644 index 00000000..5949b0dc --- /dev/null +++ b/lib/Lacuna/DB/Result/Fleet/Thud.pm @@ -0,0 +1,29 @@ +package Lacuna::DB::Result::Fleet::Thud; + +use Moose; +use utf8; +no warnings qw(uninitialized); +extends 'Lacuna::DB::Result::Fleet'; + +use constant prereq => [ { class=> 'Lacuna::DB::Result::Building::MunitionsLab', level => 3 } ]; +use constant base_food_cost => 7000; +use constant base_water_cost => 8000; +use constant base_energy_cost => 23000; +use constant base_ore_cost => 45000; +use constant base_time_cost => 60 * 60 * 2; +use constant base_waste_cost => 8400; +use constant base_speed => 700; +use constant base_stealth => 1600; +use constant base_combat => 2100; +use constant base_hold_size => 0; +use constant build_tags => ['War']; + +with "Lacuna::Role::Ship::Send::Planet"; +with "Lacuna::Role::Ship::Send::Inhabited"; +with "Lacuna::Role::Ship::Send::NotIsolationist"; +with "Lacuna::Role::Ship::Send::IsHostile"; +with "Lacuna::Role::Ship::Arrive::TriggerDefense"; +with "Lacuna::Role::Ship::Arrive::DeploySmolderingCrater"; + +no Moose; +__PACKAGE__->meta->make_immutable(inline_constructor => 0); -- 2.51.2 From f8f96cbfb73fafe043833a9d5de89250cf8168c3 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Sun, 3 Jun 2012 07:04:33 -0400 Subject: [PATCH 28/31] Withdraw all trades before converting ships to fleets --- bin/convert_ships_to_fleets.pl | 9 ++++++++- lib/Lacuna/RPC/Building/SpacePort.pm | 22 ---------------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/bin/convert_ships_to_fleets.pl b/bin/convert_ships_to_fleets.pl index 9c3c3c9c..f4723ef5 100644 --- a/bin/convert_ships_to_fleets.pl +++ b/bin/convert_ships_to_fleets.pl @@ -41,6 +41,12 @@ while (my $ship = $ships->next) { }); } +out('Withdraw all trades'); +my $trades = $db->resultset('Lacuna::DB::Result::Market')->search; +while (my $trade = $trades->next) { + $trade->withdraw($trade->body); +} + out('Do a final tick of all planets'); my $planets_rs = $db->resultset('Lacuna::DB::Result::Map::Body'); my $planets = $planets_rs->search({ empire_id => {'!=' => 0} }); @@ -59,8 +65,9 @@ while (my $planet = $planets->next) { } } +out('Group ships into fleets'); $ships = $db->resultset('Lacuna::DB::Result::Ships')->search({},{ - group_by => [qw(body_id type task name speed stealth combat hold_size)], + group_by => [qw(body_id type task name speed stealth combat hold_size berth_level foreign_body_id foreign_star_id)], }); my $finish = time; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 76e3776f..f2267570 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -230,11 +230,7 @@ sub find_arrival { my $second = $arrival_params->{second}; if (not defined $day or $day < 1 or $day > $mon_end->day) { -<<<<<<< HEAD confess [1009, "Invalid day. [$day][".Dumper($arrival_params)."]"]; -======= - confess [1009, 'Invalid day.']; ->>>>>>> Started adding new fleet action API calls } if (not defined $hour or $hour != int($hour) or $hour < 0 or $hour > 23) { confess [1002, 'Invalid hour.']; @@ -242,13 +238,8 @@ sub find_arrival { if (not defined $minute or $minute != int($minute) or $minute < 0 or $minute > 59) { confess [1002, 'Invalid minute.']; } -<<<<<<< HEAD if (not defined $second or $second != 0 and $second != 15 and $second != 30 and $second != 45) { confess [1002, 'Invalid second. Must be 0, 15, 30 or 45']; -======= - if (not defined $second or $second != int($second) or $second < 0 or $second > 59) { - confess [1002, 'Invalid second.']; ->>>>>>> Started adding new fleet action API calls } if ($day < $now->day) { # Then it must be a day next month @@ -268,11 +259,7 @@ sub find_arrival { } sub send_ship_types { -<<<<<<< HEAD my ($self, $session_id, $body_id, $target_params, $type_params, $arrival_params) = @_; -======= - my ($self, $session_id, $from_body_id, $target_params, $type_params, $arrival) = @_; ->>>>>>> Started adding new fleet action API calls my $empire = $self->get_empire_by_session($session_id); my $body = $self->get_body($empire, $body_id); @@ -322,12 +309,7 @@ sub send_ship_types { $do_captcha_check = 1; } foreach my $ship (@ships) { -<<<<<<< HEAD $ship_ref->{$ship->id} = $ship; -======= - my $hash = "${type}#${speed}#${stealth}#${combat}"; - $ship_ref->{$hash} = $ship; ->>>>>>> Started adding new fleet action API calls } } if ($do_captcha_check) { @@ -338,11 +320,7 @@ sub send_ship_types { $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } -<<<<<<< HEAD return $self->get_fleet_for($session_id, $body_id, $target_params); -======= - ->>>>>>> Started adding new fleet action API calls } sub send_fleet { -- 2.51.2 From 222e4ca63f84b8a4b6ffd7ac19d7e6300e66be09 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Tue, 5 Jun 2012 22:02:47 -0400 Subject: [PATCH 29/31] Remove memory leak on Space Station modules --- lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm b/lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm index 80050535..955d89e9 100644 --- a/lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm +++ b/lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm @@ -22,10 +22,6 @@ sub _build_parliament { my ($self) = @_; my ($parliament) = grep {$_->class =~ /Parliament$/} @{$self->building_cache}; - - if (defined $parliament) { - $parliament->body($self); - } return $parliament; } @@ -73,8 +69,6 @@ has command => ( sub _build_command { my ($self) = @_; my ($building) = grep {$_->class =~ /StationCommand$/} @{$self->building_cache}; - return undef unless defined $building; - $building->body($self); return $building; } -- 2.51.2 From f9495f523d3928c6858aa0784c2d53569dd3da90 Mon Sep 17 00:00:00 2001 From: ian docherty Date: Wed, 6 Jun 2012 07:59:58 -0400 Subject: [PATCH 30/31] Back-end support for fleet actions. --- lib/Lacuna.pm | 2 +- var/upgrades/{3.fleet.sql => 3.0854.sql} | 0 var/www/public/changes.txt | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) rename var/upgrades/{3.fleet.sql => 3.0854.sql} (100%) diff --git a/lib/Lacuna.pm b/lib/Lacuna.pm index f6d62717..93891ec1 100644 --- a/lib/Lacuna.pm +++ b/lib/Lacuna.pm @@ -7,7 +7,7 @@ use Config::JSON; useall __PACKAGE__; -our $VERSION = 3.0853; +our $VERSION = 3.0854; my $config = Config::JSON->new('/data/Lacuna-Server/etc/lacuna.conf'); my $db = Lacuna::DB->connect($config->get('db/dsn'),$config->get('db/username'),$config->get('db/password'), { mysql_enable_utf8 => 1}); diff --git a/var/upgrades/3.fleet.sql b/var/upgrades/3.0854.sql similarity index 100% rename from var/upgrades/3.fleet.sql rename to var/upgrades/3.0854.sql diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index ee86dadc..1d9f3ce6 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -1,3 +1,6 @@ +3.0854: + - Add: Backend support only for fleet actions. No changes to gameplay at this time. + 3.0853: - Mod: Excavator destruction will trigger a replacement excavator to be sent if available. - Add: Hooks for UI for excavator replacement added. (UI being updated soon.) -- 2.51.2 From e04c0ac186fd04990c1e10add34d4e28c768665d Mon Sep 17 00:00:00 2001 From: lemming552 Date: Wed, 6 Jun 2012 12:23:39 -0600 Subject: [PATCH 31/31] Check to make sure building over level 1 before stealing. --- lib/Lacuna/DB/Result/Spies.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index 81bc9337..833c0343 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -2142,6 +2142,7 @@ sub steal_building { rand() <=> rand() } grep { + ($_->level > 1) and ($_->class ne 'Lacuna::DB::Result::Building::Permanent::EssentiaVein') and ($_->class ne 'Lacuna::DB::Result::Building::Permanent::TheDillonForge') and ($_->class ne 'Lacuna::DB::Result::Building::DeployedBleeder') -- 2.51.2