File Coverage

blib/lib/Games/Lacuna/Task/Action/UpgradeBuilding.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Games::Lacuna::Task::Action::UpgradeBuilding;
2              
3 1     1   2072 use 5.010;
  1         5  
  1         133  
4             our $VERSION = $Games::Lacuna::Task::VERSION;
5              
6 1     1   488 use Moose;
  0            
  0            
7             extends qw(Games::Lacuna::Task::Action);
8             with 'Games::Lacuna::Task::Role::Building',
9             'Games::Lacuna::Task::Role::PlanetRun',
10             'Games::Lacuna::Task::Role::CommonAttributes' => { attributes => ['start_building_at'] };
11              
12             use List::Util qw(max min);
13             use Games::Lacuna::Task::Utils qw(parse_date);
14              
15             has 'upgrade_buildings' => (
16             isa => 'HashRef[ArrayRef[Str]]',
17             is => 'rw',
18             default => sub {
19             {
20             'WasteSequestration' => ['waste','storage'],
21            
22             'OreStorage' => ['ore','storage'],
23             'WaterStorage' => ['water','storage','max20'],
24             'FoodReserve' => ['food','storage','max20'],
25             'EnergyReserve' => ['energy','storage','max20'],
26            
27             'Stockpile' => ['global','storage'],
28             'PlanetaryCommand' => ['global','storage'],
29             'DistributionCenter' => ['global','storage','max18'],
30            
31             'AtmosphericEvaporator' => ['water','production'],
32             'WaterProduction' => ['water','production'],
33             'WaterPurification' => ['water','production'],
34             'WaterReclamation' => ['water','waste','production'],
35            
36             'Mine' => ['ore','production'],
37             'MiningMinistry' => ['ore','production'],
38             'OreRefinery' => ['ore','production'],
39             'WasteDigester' => ['ore','waste','production'],
40            
41             'Hydrocarbon' => ['energy','production'],
42             'Geo' => ['energy','production'],
43             'Fission' => ['energy','production'],
44             'Fusion' => ['energy','production'],
45             'Singularity' => ['energy','production'],
46             'WasteEnergy' => ['energy','waste','production'],
47            
48             'Algae' => ['food','production'],
49             'Apple' => ['food','production'],
50             'Bean' => ['food','production'],
51             'Beeldeban' => ['food','production'],
52             'Corn' => ['food','production'],
53             'Dairy' => ['food','production'],
54             'Beeldeban' => ['food','production'],
55             'Lapis' => ['food','production'],
56             'Malcud' => ['food','production'],
57             'Potato' => ['food','production'],
58             'Wheat' => ['food','production'],
59            
60             'WasteTreatment' => ['global','waste','production'],
61             'WasteExchanger' => ['global','waste','production'],
62            
63             'Shipyard' => ['extra','maxother'],
64             'SpacePort' => ['extra','maxother'],
65             'SAW' => ['extra','maxother'],
66            
67             'Sand' => ['extra'],
68             'Grove' => ['extra'],
69             'Lagoon' => ['extra'],
70             (map {
71             'lcot'.$_ => ['global','extra'],
72             } qw(a..i)),
73             }
74             },
75             documentation => 'Building uprade preferences',
76             );
77              
78             sub description {
79             return q[Upgrade buildings if the build queue is empty];
80             }
81              
82             sub process_planet {
83             my ($self,$planet_stats) = @_;
84            
85             my @buildings = $self->buildings_body($planet_stats->{id});
86             my $timestamp = time();
87             my $build_queue_size = $self->build_queue_size($planet_stats->{id});
88            
89             # Check if build queue is filled
90             return
91             if ($build_queue_size > $self->start_building_at);
92            
93             my @upgradeable_buildings;
94            
95             # Check if waste production > 0
96             if ($planet_stats->{'waste_hour'} > 0) {
97             push(@upgradeable_buildings,$self->find_upgrade_buildings($planet_stats,'waste','production'));
98             }
99            
100             # Check if storage is overflowing
101             if (scalar @upgradeable_buildings == 0) {
102             foreach my $element (qw(waste ore water food energy)) {
103             my $available_storage = $planet_stats->{$element.'_capacity'};
104             my $free_storage = $available_storage-$planet_stats->{$element.'_stored'};
105             if (($free_storage / $available_storage) < 0.01) {
106             push(@upgradeable_buildings,$self->find_upgrade_buildings($planet_stats,$element,'storage'));
107             }
108             }
109             }
110            
111             # Check production buildings
112             if (scalar @upgradeable_buildings == 0) {
113             my @production =
114             sort { $planet_stats->{$a.'_hour'} cmp $planet_stats->{$b.'_hour'} } @Games::Lacuna::Task::Constants::RESOURCES;
115             my $min_production = min map { $planet_stats->{$_.'_hour'} } @production;
116             foreach my $element (@Games::Lacuna::Task::Constants::RESOURCES) {
117             my $limit_production = $planet_stats->{$element.'_hour'} * 0.8;
118             next
119             if $limit_production > $min_production;
120             push(@upgradeable_buildings,$self->find_upgrade_buildings($planet_stats,$element,'production'));
121             last
122             if scalar(@upgradeable_buildings) > 0;
123             }
124             }
125            
126             # Find any other upgradeable building
127             for my $tag (qw(storage waste global extra)) {
128             last
129             if (scalar @upgradeable_buildings > 0);
130             @upgradeable_buildings = $self->find_upgrade_buildings($planet_stats,$tag);
131             }
132            
133             if (scalar @upgradeable_buildings) {
134             @upgradeable_buildings = sort { $a->{level} <=> $b->{level} }
135             @upgradeable_buildings;
136            
137             foreach my $building_data (@upgradeable_buildings) {
138            
139             my $upgrade = $self->upgrade_building($planet_stats,$building_data);
140            
141             $build_queue_size ++
142             if $upgrade;
143             return
144             if ($build_queue_size > $self->start_building_at);
145             }
146             }
147            
148             warn \@upgradeable_buildings;
149            
150             return;
151             }
152              
153             sub find_upgrade_buildings {
154             my ($self,$planet_stats,@tags) = @_;
155            
156             my @upgrade_buildings;
157             my @buildings = $self->buildings_body($planet_stats->{id});
158            
159             my $max_ressouce_level = $self->max_resource_building_level($planet_stats->{id});
160             my $max_building_level = $self->university_level() + 1;
161             my $max_building_type_level = {};
162             my $timestamp = time();
163            
164             BUILDING:
165             foreach my $building_data (sort { $b->{level} <=> $a->{level} } @buildings) {
166             my $building_class = Games::Lacuna::Client::Buildings::type_from_url($building_data->{url});
167             my $building_level = $building_data->{level};
168            
169             $max_building_type_level->{$building_class} ||= $building_level;
170            
171             next BUILDING
172             unless exists $self->upgrade_buildings->{$building_class};
173            
174             foreach my $tag (@tags) {
175             next BUILDING
176             unless $tag ~~ $self->upgrade_buildings->{$building_class};
177             }
178            
179             foreach my $tag (@{$self->upgrade_buildings->{$building_class}}) {
180             next BUILDING
181             if $tag =~ m/max(?<level>\d+)$/ && $building_level >= $+{level};
182             }
183            
184             next BUILDING
185             if $building_level >= $max_building_level;
186            
187             next BUILDING
188             if 'production' ~~ $self->upgrade_buildings->{$building_class}
189             && $building_level >= $max_ressouce_level;
190            
191             next BUILDING
192             if 'maxother' ~~ $self->upgrade_buildings->{$building_class}
193             && $building_level >= $max_building_type_level->{$building_class};
194            
195             if (defined $building_data->{pending_build}) {
196             my $date_end = parse_date($building_data->{pending_build}{end});
197             next BUILDING
198             if $timestamp < $date_end;
199             }
200            
201             next BUILDING
202             unless $self->check_upgrade_building($planet_stats,$building_data);
203            
204             push(@upgrade_buildings,$building_data);
205             }
206            
207             return @upgrade_buildings;
208             }
209              
210             __PACKAGE__->meta->make_immutable;
211             no Moose;
212             1;