From 3c789fb652faabd78b0de604fd4c9cc775f703c7 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Tue, 24 Dec 2013 00:45:44 -0700 Subject: [PATCH] Ability to commit numerous plans to the forge. --- docs/TheDillonForge.pod | 8 ++- .../Building/Permanent/TheDillonForge.pm | 54 +++++++++++++++---- lib/Lacuna/RPC/Building/TheDillonForge.pm | 19 +++++-- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/docs/TheDillonForge.pod b/docs/TheDillonForge.pod index f02ea48df..1d30cb2dc 100644 --- a/docs/TheDillonForge.pod +++ b/docs/TheDillonForge.pod @@ -62,7 +62,7 @@ specified class to build a level x+0 plan. The B is how long it will take to build a plan per level. -=head2 split_plan ( session_id, building_id, plan_class, level, extra_build_level ) +=head2 split_plan ( session_id, building_id, plan_class, level, extra_build_level, quantity ) Split a plan into it's constituant glyphs. The glyph types that can be returned depend upon the recipe to build that type of plan. The maximum number of glyphs @@ -97,9 +97,13 @@ The level of the plan to be split. The extra build levels (if any) for that plan. +=head3 quantity + +Number of plans to feed into the forge. Time does not go up linearly, but the more plans fed in, the more efficient. + =head2 subsidize ( session_id, building_id ) -Will spend 2 essentia to complete the current task immediately. Returns B +Will spend essentia to complete the current task immediately. Cost is 2e unless splitting multiple plans. Returns B Throws 1011. diff --git a/lib/Lacuna/DB/Result/Building/Permanent/TheDillonForge.pm b/lib/Lacuna/DB/Result/Building/Permanent/TheDillonForge.pm index 51dbf5aba..5f6073894 100644 --- a/lib/Lacuna/DB/Result/Building/Permanent/TheDillonForge.pm +++ b/lib/Lacuna/DB/Result/Building/Permanent/TheDillonForge.pm @@ -11,7 +11,7 @@ use Lacuna::Util qw(randint); use constant controller_class => 'Lacuna::RPC::Building::TheDillonForge'; -use constant subsidy_cost => 2; +#use constant subsidy_cost => 2; around can_build => sub { my ($orig, $self, $body) = @_; @@ -49,9 +49,24 @@ use constant name => 'The Dillon Forge'; use constant time_to_build => 0; use constant max_instances_per_planet => 1; +sub subsidy_cost { + my ($self) = @_; + + my $sub = 2; + if ($self->is_working) { + my $work = $self->work; + if ($work->{task} eq "split_plan" and $work->{quantity} > 1) { + my $pow_two = int(log($work->{quantity})/log(2)+0.5); + $sub = 2 + $sub * $pow_two; + } + } + return $sub; +} + sub split_plan { - my ($self, $plan_class, $level, $extra_build_level) = @_; + my ($self, $plan_class, $level, $extra_build_level, $quantity) = @_; + $quantity = $quantity || 1; my $halls = $self->equivalent_halls($level, $extra_build_level); my $class = 'Lacuna::DB::Result::Building::'.$plan_class; my $body = $self->body; @@ -64,6 +79,9 @@ sub split_plan { if (not $plan) { confess [1002, 'You cannot split a plan you do not have.']; } + if ($plan->quantity < $quantity) { + confess [1002, 'You only have '.$plan->quantity.' of the '.$quantity.' you wish to split.']; + } my $glyphs = Lacuna::DB::Result::Plan->get_glyph_recipe($class); if (not $glyphs) { confess [1002, 'You can only split plans that have a glyph recipe.']; @@ -71,10 +89,12 @@ sub split_plan { if ($class =~ m/Platform$/) { confess [1002, 'You cannot split a Platform plan.']; } - $body->delete_one_plan($plan); + $body->delete_many_plans($plan, $quantity); + my $num_glyphs = scalar @$glyphs; - my $build_secs = int($halls * 30 * 3600 / $self->level); - $self->start_work({task => 'split_plan', class => $class, level => $level, extra_build_level => $extra_build_level}, $build_secs)->update; + my $base = ($num_glyphs * $halls * 30 * 3600) / ($self->level * 4); + my $build_secs = int($base + ($base * log($quantity))/log(2) + 0.5); + $self->start_work({task => 'split_plan', class => $class, level => $level, extra_build_level => $extra_build_level, quantity => $quantity}, $build_secs)->update; } sub make_plan { @@ -148,15 +168,29 @@ before finish_work => sub { $plan_class .= " $hall_type"; } my $glyphs = Lacuna::DB::Result::Plan->get_glyph_recipe($plan_class); - my @many_glyphs = shuffle map { @$glyphs } (1..$halls); my $glyphs_built; my $total_glyphs = 0; - for my $glyph (@many_glyphs) { - if ($success_percent > rand(100)) { - $glyphs_built->{$glyph} = $glyphs_built->{$glyph} ? $glyphs_built->{$glyph}+1 : 1; - $total_glyphs++; + for my $glyph (@$glyphs) { + my $potential = $halls * $work->{quantity}; + my $slice = 0; + my $reward = 0; + if ($potential > 100) { + $slice = $potential - 100; + $potential = 100; + } + for (1..$potential) { + if ($success_percent > rand(100)) { + $glyphs_built->{$glyph} = $glyphs_built->{$glyph} ? $glyphs_built->{$glyph}+1 : 1; + $total_glyphs++; + } + } + if ($slice > 0) { + my $avg_num = int($slice * $success_percent/100 + 0.5); + $glyphs_built->{$glyph} += $avg_num; + $total_glyphs += $avg_num; } } + for my $glyph (keys %{$glyphs_built}) { $self->body->add_glyph($glyph, $glyphs_built->{$glyph}); } diff --git a/lib/Lacuna/RPC/Building/TheDillonForge.pm b/lib/Lacuna/RPC/Building/TheDillonForge.pm index 61b890d1f..834a95735 100644 --- a/lib/Lacuna/RPC/Building/TheDillonForge.pm +++ b/lib/Lacuna/RPC/Building/TheDillonForge.pm @@ -25,7 +25,12 @@ around 'view' => sub { my $plan_class = $work->{class}; my $desc; if ($work->{task} eq 'split_plan') { - $desc = sprintf("Splitting %s %s+%s", $plan_class->name, $work->{level},$work->{extra_build_level}), + if ($work->{quantity} > 1) { + $desc = sprintf("Splitting %d %s %s+%s", $work->{quantity}, $plan_class->name, $work->{level},$work->{extra_build_level}), + } + else { + $desc = sprintf("Splitting %s %s+%s", $plan_class->name, $work->{level},$work->{extra_build_level}), + } } elsif ($work->{task} eq 'make_plan') { $desc = sprintf("Making %s %s", $plan_class->name, $work->{level}), @@ -68,19 +73,22 @@ sub _forge_tasks { PLAN: for my $plan (@{$body->plan_cache}) { # Can only split plans with recipes - next PLAN if not Lacuna::DB::Result::Plan->get_glyph_recipe($plan->class); + my $glyphs = Lacuna::DB::Result::Plan->get_glyph_recipe($plan->class); + next PLAN if not $glyphs; my ($class) = $plan->class =~ m/Lacuna::DB::Result::Building::(.*)$/; my $halls = $self->equivalent_halls($plan); + my $num_glyphs = scalar @$glyphs; + push @split_plans, { name => $plan->class->name, class => $class, level => $plan->level, extra_build_level => $plan->extra_build_level, fail_chance => 100 - ($building->level * 3), - reset_seconds => $halls * 30 * 3600 / $building->level, + reset_seconds => int(($num_glyphs * $halls * 30 * 3600) / ($building->level * 4)), }; } @@ -109,11 +117,12 @@ PLAN: } sub split_plan { - my ($self, $session_id, $building_id, $plan_class, $level, $extra_build_level) = @_; + my ($self, $session_id, $building_id, $plan_class, $level, $extra_build_level, $quantity) = @_; my $empire = $self->get_empire_by_session($session_id); my $building = $self->get_building($empire, $building_id); + $quantity = $quantity || 1; - $building->split_plan($plan_class, $level, $extra_build_level); + $building->split_plan($plan_class, $level, $extra_build_level, $quantity); return $self->view($empire, $building); }