diff --git a/bin/add_missions.pl b/bin/add_missions.pl new file mode 100644 index 00000000..6a418d75 --- /dev/null +++ b/bin/add_missions.pl @@ -0,0 +1,74 @@ +use 5.010; +use strict; +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('Finding Mission Files'); +my @mission_files = get_mission_files(); + +out('Loading DB'); +our $db = Lacuna->db; +our $missions = $db->resultset('Lacuna::DB::Result::Mission'); +our $news = $db->resultset('Lacuna::DB::Result::News'); + +out('Adding missions'); +my @zones = $db->resultset('Lacuna::DB::Result::Map::Body')->search( + { empire_id => { '>' => 0 }}, + { distinct => 1 })->get_column('zone')->all; +foreach my $zone (@zones) { + out($zone); + if ($missions->search({zone=>$zone})->count < 31) { + my $mission = $missions->new({ + zone => $zone, + mission_file_name => $mission_files[rand @mission_files], + })->insert; + $news->new({ + zone => $zone, + headline => $mission->params->get('network_19_headline'), + })->insert; + } +} + +my $finish = time; +out('Finished'); +out((($finish - $start)/60)." minutes have elapsed"); + + +############### +## SUBROUTINES +############### + + +sub get_missions_files { + opendir my $dir, '/data/Lacuna-Server/var/missions/'; + my @files = readdir $dir; + closedir $dir; + my @missions; + foreach my $file (@files) { + next unless $file =~ m/\.mission$/; + push @missions, $file; + } + return @missions; +} + + +sub out { + my $message = shift; + unless ($quiet) { + say format_date(DateTime->now), " ", $message; + } +} + + diff --git a/lib/Lacuna/DB/Result/Building/MissionCommand.pm b/lib/Lacuna/DB/Result/Building/MissionCommand.pm index 9547a184..c5e2fca6 100644 --- a/lib/Lacuna/DB/Result/Building/MissionCommand.pm +++ b/lib/Lacuna/DB/Result/Building/MissionCommand.pm @@ -42,29 +42,17 @@ use constant water_consumption => 10; use constant waste_production => 2; -sub get_missions { - my ($self, $session_id, $building_id) = @_; - my $empire = $self->get_empire_by_session($session_id); - my $building = $self->get_building($empire, $building_id); - my @missions; - my $missions = $building->missions; - while (my $mission = $missions->next) { - next if $mission->params->max_university_level < $empire->university_level; - push @missions, { - id => $mission->id, - name => $mission->name, - description => $mission->description, - objectives => $mission->format_objectives, - rewards => $mission->format_rewards, - }; - } - return { - status => $self->format_status($empire, $building->body), - missions => \@missions, - }; + +sub missions { + my ($self) = @_; + return Lacuna->db->resultset('Lacuna::DB::Result::Mission')->search({ + zone => $self->body->zone, + },{ + order_by => 'date_posted', + }); } -__PACKAGE__->register_rpc_method_names(qw(get_missions)); + no Moose; __PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Mission.pm b/lib/Lacuna/DB/Result/Mission.pm index e41e965d..74d9dd45 100644 --- a/lib/Lacuna/DB/Result/Mission.pm +++ b/lib/Lacuna/DB/Result/Mission.pm @@ -24,50 +24,107 @@ has params => ( }, ); +sub check_objectives { + my ($self, $body) = @_; + my $objectives = $self->params->get('mission_objective'); + + # essentia + if (exists $objectives->{essentia}) { + if ($body->empire->essentia < $objectives->{essentia}) { + confess [1011, 'You do not have the essentia needed to complete this mission.']; + } + } + + # resources + if (exists $objectives->{resources}) { + foreach my $resource (keys %{$objectives->{resources}}) { + if ($body->type_stored($resource) < $objectives->{resources}{$resource}) { + confess [1011, 'You do not have the '.$resource.' needed to complete this mission.']; + } + } + } + + # glyphs + if (exists $objectives->{glyphs}) { + foreach my $glyph (@{$objectives->{glyphs}}) { + unless ($body->glyphs->search({ type => $glyph })->count) { + confess [1011, 'You do not have the '.$glyph.' glyph needed to complete this mission.']; + } + } + } + + # ships + if (exists $objectives->{ships}) { + foreach my $ship (@{$objectives->{ships}}) { + unless ($body->ships->search({ type => $ship->{type}, speed => {'>=' => $ship->{speed}}, stealth => {'>=' => $ship->{stealth}}, hold_size => {'>=' => $ship->{hold_size}} })->count) { + my $ship = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->new({type=>$ship->{type}}); + confess [1011, 'You do not have the '.$ship->type_formatted.' needed to complete this mission.']; + } + } + } + + return 1; +} + sub format_objectives { my $self = shift; - my $objectives = $self->params->get('mission_objective'); - my @objectives; + return $self->format_items($self->params->get('mission_objective')); +} + +sub format_rewards { + my $self = shift; + return $self->format_items($self->params->get('mission_reward')); +} + +sub format_items { + my ($self, $items) = @_; + my @items; # essentia - push @objectives, sprintf('Provide %d essentia.', $objectives->{essentia}) if ($objectives->{essentia}); + push @items, sprintf('Essentia: %d essentia.', $items->{essentia}) if ($items->{essentia}); # resources my @resources; - foreach my $resource (keys %{ $objectives->{resources}}) { - push @resources, sprintf('%d %s', $objectives->{resources}{$resource}); + foreach my $resource (keys %{ $items->{resources}}) { + push @resources, sprintf('%d %s', $items->{resources}{$resource}); } - push @objectives, $self->format_list(@resources); + push @items, $self->format_list('Resources',@resources); + + # glyphs + push @items, $self->format_list('Glyphs',@{$items->{glyphs}}); # ships my @ships; my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships'); - foreach my $stats (@{ $objectives->{ships}}) { + foreach my $stats (@{ $items->{ships}}) { my $ship = $ships->new({type=>$stats->{type}}); push @ships, sprintf('%s (speed: %d, stealth: %d, hold size: %d)', $ship->name, $stats->{speed}, $stats->{stealth}, $stats->{hold_size}); } - push @objectives, $self->format_list(@ships); + push @items, $self->format_list('Ships',@ships); # plans my @plans; - foreach my $stats (@{ $objectives->{plans}}) { - push @plans, sprintf('%s (%s)', $stats); + foreach my $stats (@{ $items->{plans}}) { + my $level = $stats->{level}; + if ($stats->{extra_build_level}) { + $level = '+'.$stats->{extra_build_level}; + } + push @plans, sprintf('%s (%s)', $stats->{classname}->name, $level); } - push @objectives, $self->format_list(@plans); + push @items, $self->format_list('Plans',@plans); - - return \@objectives; + return \@items; } sub format_list { - my ($self, @list) = @_; + my ($self, $label, @list) = @_; my @out; if (scalar(@list) == 1) { - push @out, sprintf('Provide %s.', $list[0]); + push @out, sprintf($label.': %s.', $list[0]); } elsif (scalar(@list) > 1) { my $last = pop @list; - push @out, sprintf('Provide %s and %s', join(',', @list), $last); + push @out, sprintf($label.': %s and %s', join(',', @list), $last); } return @out; } diff --git a/lib/Lacuna/RPC/Building/MissionCommand.pm b/lib/Lacuna/RPC/Building/MissionCommand.pm index 2273bd9d..b8035c68 100644 --- a/lib/Lacuna/RPC/Building/MissionCommand.pm +++ b/lib/Lacuna/RPC/Building/MissionCommand.pm @@ -13,16 +13,46 @@ sub model_class { return 'Lacuna::DB::Result::Building::MissionCommand'; } -sub missions { - my ($self) = @_; - return Lacuna->db->resultset('Lacuna::DB::Result::Mission')->search({ - zone => $self->body->zone, - },{ - order_by => 'date_posted', - }); +sub get_missions { + my ($self, $session_id, $building_id) = @_; + my $empire = $self->get_empire_by_session($session_id); + my $building = $self->get_building($empire, $building_id); + my @missions; + my $missions = $building->missions; + while (my $mission = $missions->next) { + next if $mission->params->max_university_level < $empire->university_level; + push @missions, { + id => $mission->id, + name => $mission->name, + description => $mission->description, + objectives => $mission->format_objectives, + rewards => $mission->format_rewards, + max_university_level => $mission->max_university_level, + date_posted => $mission->date_posted_formatted, + }; + } + return { + status => $self->format_status($empire, $building->body), + missions => \@missions, + }; } +sub complete_mission { + my ($self, $session_id, $building_id, $mission_id) = @_; + my $empire = $self->get_empire_by_session($session_id); + my $building = $self->get_building($empire, $building_id); + confess [1002, 'Please specify a mission id.'] unless $mission_id; + my $mission = $building->missions->find($mission_id); + my $body = $building->body; + $mission->check_objectives($body); + $mission->spend_objectives($body); + $mission->add_rewards($body); + return { + status => $self->format_status($empire, $body), + } +} +__PACKAGE__->register_rpc_method_names(qw(get_missions complete_mission)); no Moose; __PACKAGE__->meta->make_immutable;