Games-Lacuna-Client

 view release on metacpan or  search on metacpan

examples/build_scheduled.pl  view on Meta::CPAN

    ) if $dist;
  };
  usage() unless $config_file and -e $config_file
}
usage() if not defined $schedule_file or not -e $schedule_file;

my $client = Games::Lacuna::Client->new(
  cfg_file => $config_file,
  #debug => 1,
);

$SIG{INT} = sub {
  undef $client; # for session persistence
  warn "Interrupted!\n";
  exit(1);
};


my $to_be_built = YAML::Any::LoadFile($schedule_file);
foreach my $name (keys %$to_be_built) {
  my $build_order = $to_be_built->{$name};
  $build_order->{dependent_on} ||= [];
  prepare_building($build_order);
}

my @work_order = build_topo_sort(%$to_be_built);
print "Working in the following order:\n";
print Dumper(\@work_order);
print "\n";
my $empire = $client->empire;
my $estatus = $empire->get_status->{empire};
my %planets_by_name = map { ($estatus->{planets}->{$_} => $client->body(id => $_)) }
                      keys %{$estatus->{planets}};


my %failed_jobs;
while (1) {
  output("Checking status");

  my %tainted_planets;
  my %checked_planets;
  die if not @work_order;
  my $current_work = $work_order[0];
  output("Current work slice: " . join (", ", @$current_work));

  foreach (my $ibuild = 0; $ibuild < @$current_work; ++$ibuild) {
    my $name = $current_work->[$ibuild];
    my $build_order = $to_be_built->{$name};
    output("Attempting '$name'");

    # check for bad dependencies
    if (grep {$failed_jobs{$_}} @{$build_order->{dependent_on}}) {
      output("Depends on failed job. Removing.");
      $failed_jobs{$name} = 1;
      splice(@$current_work, $ibuild, 1);
      $ibuild--;
      next;
    }
    # check for known (currently) bad planets
    if ($tainted_planets{ $build_order->{planet} }) {
      output("Planet busy, skipping.");
      next;
    }

    my $planet_name = $build_order->{planet};
    my $planet = $planets_by_name{$planet_name};

    if (not $checked_planets{$planet_name}) {
      # This needs better API (understanding)
      #my $buildable = $planet->get_buildable(0, 0, 'Storage');
      #if ($buildable->{build_queue}{max} <= $buildable->{build_queue}{current}) {
      #  output("Planet build queue is full. Marking as tainted. Skipping.");
      #  $tainted_planets{$planet_name} = 1;
      #  next;
      #}
      my $buildings_struct = $planet->get_buildings();
      $checked_planets{$planet_name} = $buildings_struct;
    }

    if (not defined $build_order->{building}) {
      prepare_building($client, $build_order, $checked_planets{$planet_name});
      if (not defined $build_order->{building}) {
        output("Can't infer building type or position, skipping this order");
        $failed_jobs{$name} = 1;
        splice(@$current_work, $ibuild, 1);
        $ibuild--;
        next;
      }
    }
    if (not defined $build_order->{building}->building_id) {
      $build_order->{building}->{building_id}
        = find_building_id($checked_planets{$planet_name}, $build_order->{x}, $build_order->{y});
    }

    my $err;
    my $action;
    if ($build_order->{ship_type}) {
      output("Building new ship");
      $action = 'ship';
      eval { $build_order->{building}->build_ship($build_order->{ship_type}) };
      $err = $@;
    }
    elsif ($build_order->{upgrade}) {
      output("Performing upgrade of building.");
      $action = 'upgrade';
      eval { $build_order->{building}->upgrade() };
      $err = $@;
    }
    else { # fresh build
      output("Constructing new building");
      $action = 'build';
      eval { $build_order->{building}->build($planet->body_id, $build_order->{x}, $build_order->{y}) };
      $err = $@;
    } # end fresh build

    if ($err) {
      output(ucfirst($action) . " failed.");
      $err =~ /^RPC Error \((\d+)\)/ or die $err;
      my $code = $1;
      if ($code == 1009) {
        if ($err =~ /build queue/) {



( run in 0.738 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )