Games-Lacuna-Client

 view release on metacpan or  search on metacpan

examples/wr.pl  view on Meta::CPAN


my @wrs;
foreach my $planet (values %planets_by_name) {
  my %buildings = %{ $planet->get_buildings->{buildings} };

  my @waste_ids = grep {$buildings{$_}{name} eq 'Waste Recycling Center'}
                  keys %buildings;
  push @wrs, map  { $client->building(type => 'WasteRecycling', id => $_) } @waste_ids;
}

my @wr_handlers;
my @wr_timers;
foreach my $iwr (0..$#wrs) {
  my $wr = $wrs[$iwr];
  push @wr_handlers, sub {
    my $wait_sec = update_wr($wr, $iwr);
    return if not $wait_sec;
    $wr_timers[$iwr] = AnyEvent->timer(
      after => $wait_sec,
      cb    => sub {
        output("Waited for $wait_sec on WR $iwr");
        $wr_handlers[$iwr]->()
      },
    );
  };
}

foreach my $wrh (@wr_handlers) {
  $wrh->();
}

output("Done setting up initial jobs. Waiting for events.");
$program_exit->recv;
undef $client; # for session persistence
exit(0);

sub output {
  my $str = join ' ', @_;
  $str .= "\n" if $str !~ /\n$/;
  print "[" . localtime() . "] " . $str;
}

sub usage {
  die <<"END_USAGE";
Usage: $0 myempire.yml
       --interval MINUTES  (defaults to 20)

Need to generate an API key at https://us1.lacunaexpanse.com/apikey
and create a configuration YAML file that should look like this

  ---
  api_key: the_public_key
  empire_name: Name of empire
  empire_password: password of empire
  server_uri: https://us1.lacunaexpanse.com/

END_USAGE

}

sub update_wr {
  my $wr = shift;
  my $iwr = shift;

  output("checking WR stats for WR $iwr");
  my $wr_stat = $wr->view;

  my $busy_seconds = $wr_stat->{building}{work}{seconds_remaining};
  if ($busy_seconds) {
    output("Still busy for $busy_seconds, waiting");
    return $busy_seconds+3;
  }

  output("Checking resource stats");
  my $pstatus = $wr_stat->{status}{body} or die "Could not get planet status via \$struct->{status}{body}: " . Dumper($wr_stat);
  my $waste = $pstatus->{waste_stored};

  if (not $waste or $waste < 100) {
    output("(virtually) no waste has accumulated, waiting");
    return 5*MINUTE;
  }

  my $sec_per_waste = $wr_stat->{recycle}{seconds_per_resource};
  die "seconds_per_resource not found" if not $sec_per_waste;

  my $rec_waste = min($waste, $TimePerIteration / $sec_per_waste, $wr_stat->{recycle}{max_recycle});

  # yeah, I know this is a bit verbose.
  my $ore_c    = $pstatus->{ore_capacity};
  my $water_c  = $pstatus->{water_capacity};
  my $energy_c = $pstatus->{energy_capacity};

  my $ore_s    = $pstatus->{ore_stored};
  my $water_s  = $pstatus->{water_stored};
  my $energy_s = $pstatus->{energy_stored};

  my $produce_ore    = $ore_c > $ore_s+1;
  my $produce_water  = $water_c > $water_s+1;
  my $produce_energy = $energy_c > $energy_s+1;
  my $total_s        = $ore_s + $water_s + $energy_s;

  my ($ore, $water, $energy);
  if (not $produce_ore and not $produce_energy and not $produce_water) {
    output("All storage full! Producing equal amounts of resources to keep waste low.");
    ($ore, $water, $energy) = map {$total_s/3} 1..3;
  }
  else {
    if ($water_perc or $energy_perc or $ore_perc) {
      $ore    = $rec_waste * $ore_perc;
      $water  = $rec_waste * $water_perc;
      $energy = $rec_waste * $energy_perc;
    } else {
      $ore    = $rec_waste * 0.5*($water_s+$energy_s)/$total_s;
      $water  = $rec_waste * 0.5*($energy_s+$ore_s)/$total_s;
      $energy = $rec_waste * 0.5*($water_s+$ore_s)/$total_s;
    }
    if (not $produce_ore) {
      output("Ore storage full! Producing no ore.");
      $water  += $ore/2;
      $energy += $ore/2;
      $ore = 0;



( run in 0.990 second using v1.01-cache-2.11-cpan-39bf76dae61 )