package Lacuna::RPC::Role::Building; use Moose::Role; use Lacuna::Constants qw(ORE_TYPES); # Return a 'buildings' hash suitable for output to the RPC # # Pass { include_resources => 1 } to attach a 'resources' hash (production, # storage and per-food/per-ore breakdowns) to each building - see get_buildings_resources. # sub out_buildings { my ($self, $body, $options) = @_; $options //= {}; my $out; my @buildings = @{$body->building_cache}; foreach my $building (@buildings) { $out->{$building->id} = { url => $building->controller_class->app_url, image => $building->image_level, name => $building->name, x => $building->x, y => $building->y, level => $building->level, efficiency => $building->efficiency, }; if ($building->is_upgrading) { $out->{$building->id}{pending_build} = $building->upgrade_status; } if ($building->is_working) { $out->{$building->id}{work} = { seconds_remaining => $building->work_seconds_remaining, start => $building->work_started_formatted, end => $building->work_ends_formatted, }; } if ($building->efficiency < 100) { $out->{$building->id}{repair_costs} = $building->get_repair_costs; } if ($options->{include_resources}) { $out->{$building->id}{resources} = $self->building_resources($building); } } return $out; } # Return the hourly production/consumption, storage capacity and per-type # production breakdown for a single building. # sub building_resources { my ($self, $building) = @_; my $body = $building->body; my %resources = ( food_hour => 0 + $building->food_hour, food_capacity => 0 + $building->food_capacity, water_hour => 0 + $building->water_hour, water_capacity => 0 + $building->water_capacity, waste_hour => 0 + $building->waste_hour, waste_capacity => 0 + $building->waste_capacity, energy_hour => 0 + $building->energy_hour, energy_capacity => 0 + $building->energy_capacity, happiness_hour => 0 + $building->happiness_hour, ); # Per-food-type production, for the food items this building actually makes. my %food; foreach my $type (@{$building->produces_food_items}) { my $method = $type . '_production_hour'; $food{$type} = 0 + $building->$method; } $resources{food} = \%food if %food; # The Mining Ministry's ore output comes from its deployed mining platforms # and the ships servicing them, not from this building's own constants. # Reproducing that here would mean several extra queries (platforms, their # asteroids and ore balances, mining ships) plus the full shipping-capacity # calculation, so we deliberately omit all ore figures for the Ministry. unless ($building->isa('Lacuna::DB::Result::Building::Ore::Ministry')) { $resources{ore_hour} = 0 + $building->ore_hour; $resources{ore_capacity} = 0 + $building->ore_capacity; # Per-ore-type production, splitting the building's generic ore output by # the body's ore concentration - mirrors Planet::recalc_stats' "local # ore production". my $ore_production_hour = $building->ore_production_hour; my $total_concentration = $body->total_ore_concentration; if ($ore_production_hour && $total_concentration) { my %ore; foreach my $type (ORE_TYPES) { $ore{$type} = 0 + sprintf('%.0f', $body->$type * $ore_production_hour / $total_concentration); } $resources{ore} = \%ore; } } return \%resources; } 1;