Skip to content
Browse files

added basic space station infrastructure

  • Loading branch information...
1 parent 82e3720 commit 78a6ca767d8d14884993dcab9bc0d1a732496fd0 JT Smith committed
View
2 add_a_building.txt
@@ -7,7 +7,7 @@ add to bin/lacuna.psgi
add to Lacuna::DB::Result::Medals
add to var/www/public/resources.json
upload a medal image
-upload the building images in all 4 sizes
+upload the building images in all 5 sizes
create wiki entry
# if buildable
View
4 bin/lacuna.psgi
@@ -167,6 +167,10 @@ $urlmap->map(Lacuna::RPC::Building::SSLa->new->to_app_with_url);
$urlmap->map(Lacuna::RPC::Building::SSLb->new->to_app_with_url);
$urlmap->map(Lacuna::RPC::Building::SSLc->new->to_app_with_url);
$urlmap->map(Lacuna::RPC::Building::SSLd->new->to_app_with_url);
+$urlmap->map(Lacuna::RPC::Building::StationCommand->new->to_app_with_url);
+$urlmap->map(Lacuna::RPC::Building::Parliament->new->to_app_with_url);
+$urlmap->map(Lacuna::RPC::Building::Warehouse->new->to_app_with_url);
+$urlmap->map(Lacuna::RPC::Building::IBS->new->to_app_with_url);
# admin
View
6 docs/Body.pod
@@ -140,6 +140,8 @@ The id of the body you wish to retrieve the buildings on.
Provides a list of all the building types that are available to be built on a given space on a planet that are within a specific tag.
+B<NOTE:> Calling C<get_buildable> on a Space Station will result in an exception. Use L<Parliament> instead.
+
{
"max_items_in_build_queue" : 6,
"build_queue" : {
@@ -296,6 +298,8 @@ A tag that will limit the list of buildings to return. Required. Cannot be C<Now
Renames a body, provided the empire attached to the session owns the body. Returns a 1 on success.
+B<NOTE:> Calling C<rename> on a Space Station will result in an exception. Use L<Parliament> instead.
+
Throws 1000, 1002 and 1010.
=head3 session_id
@@ -316,6 +320,8 @@ The new name of the body.
Abandon's a colony, and destroys everything on the planet. Returns a status block.
+B<NOTE:> Calling C<abandon> on a Space Station will result in an exception. Use L<Parliament> instead.
+
=head3 session_id
A session id.
View
3 docs/Buildings.pod
@@ -269,8 +269,9 @@ A session id.
The unique id of the building.
+=head1 Space Station Modules
-
+Space stations have buildings too (called Modules), but they don't behave exactly the same as ground based buildings. See the L<Modules> documentation for more information.
=head1 Building Types
View
7 docs/IBS.pod
@@ -0,0 +1,7 @@
+=head1 Interstellar Broadcast System Methods
+
+Interstellar Broadcast System is accessible via the URL C</ibs>.
+
+The list of methods below represents changes and additions to the methods that all L<Modules> share.
+
+=cut
View
25 docs/Modules.pod
@@ -0,0 +1,25 @@
+=head1 Modules vs Buildings
+
+Modules are special types of L<Buildings> that can only be built on a space station.
+
+Modules produce no resources, and therefore may be built to consume resources beyond your production levels.
+
+Modules can only be built, repaired, upgraded, downgraded, and demolished via acts of L<Parliament>. Therefore modules don't inherit the C<build>, C<upgrade>, C<downgrade>, C<demolish>, and C<repair> methods from L<Buildings>.
+
+=head1 Module Types
+
+Below is a list of the different types of structures that can be built on space stations in Lacuna.
+
+=over
+
+=item L<IBS>
+
+=item L<Parliament>
+
+=item L<StationCommand>
+
+=item L<Warehouse>
+
+=back
+
+=cut
View
7 docs/Parliament.pod
@@ -0,0 +1,7 @@
+=head1 Parliament Methods
+
+Parliament is accessible via the URL C</parliament>.
+
+The list of methods below represents changes and additions to the methods that all L<Modules> share.
+
+=cut
View
83 docs/StationCommand.pod
@@ -0,0 +1,83 @@
+=head1 Station Command Methods
+
+Station Command Center is accessible via the URL C</stationcommand>.
+
+The list of methods below represents changes and additions to the methods that all L<Modules> share.
+
+=head2 view ( session_id, building_id )
+
+Command extends the view method to include a C<planet> section.
+
+ {
+ "building" : { ... },
+ "status" : { ... },
+ "next_colony_cost" : 750000, # the amount of happiness required to settle your next colony
+ "planet" : {
+ "id" : "id-goes-here",
+ "x" : -4,
+ "y" : 10,
+ "z" : 6,
+ "star_id" : "id-goes-here",
+ "orbit" : 3,
+ "type" : "habitable planet",
+ "name" : "Earth",
+ "image" : "p13",
+ "size" : 67,
+ "water" : 900,
+ "ore" : {
+ "gold" : 3399,
+ "bauxite" : 4000,
+ ...
+ },
+ "building_count" : 7,
+ "population" : 470000,
+ "happiness" : 3939,
+ "happiness_hour" : 25,
+ "food_stored" : 33329,
+ "food_capacity" : 40000,
+ "food_hour" : 229,
+ "energy_stored" : 39931,
+ "energy_capacity" : 43000,
+ "energy_hour" : 391,
+ "ore_hour" 284,
+ "ore_capacity" 35000,
+ "ore_stored" 1901,
+ "waste_hour" : 933,
+ "waste_stored" : 9933,
+ "waste_capacity" : 13000,
+ "water_stored" : 9929,
+ "water_hour" : 295,
+ "water_capacity" : 51050
+ }
+ }
+
+
+=head2 view_plans ( session_id, building_id )
+
+Returns a list of all the plans you've collected through various means.
+
+ {
+ "status" : { ... },
+ "plans" : [
+ {
+ "name" : "Malcud Fungus Farm",
+ "level" : 1,
+ "extra_build_level" : 5
+ },
+ ...
+ ]
+ }
+
+If the C<level> is 1, and there is an C<extra_build_level>, that means that the building will be built up to 1 plus the extra build level when complete. So in the example above, it would be a level 6 directly after being built.
+
+
+=head3 session_id
+
+A session id.
+
+=head3 building_id
+
+The unique id of the PCC.
+
+
+=cut
View
7 docs/Warehouse.pod
@@ -0,0 +1,7 @@
+=head1 Warehouse Methods
+
+Warehouse is accessible via the URL C</warehouse>.
+
+The list of methods below represents changes and additions to the methods that all L<Modules> share.
+
+=cut
View
11 lib/Lacuna/DB/Result/Building.pm
@@ -549,6 +549,9 @@ sub has_special_resources {
sub can_build {
my ($self, $body) = @_;
+ # check body type
+ $self->can_build_on;
+
# check goldilox zone
if ($body->orbit < $self->min_orbit || $body->orbit > $self->max_orbit) {
confess [1013, "This building may only be built between orbits ".$self->min_orbit." and ".$self->max_orbit.".", [$self->min_orbit, $self->max_orbit]];
@@ -577,6 +580,14 @@ sub can_build {
return 1;
}
+sub can_build_on {
+ my $self = shift;
+ if (!$self->isa('Lacuna::DB::Result::Map::Body::Planet') || $self->isa('Lacuna::DB::Result::Map::Body::Planet::Station')) {
+ confess [1009, 'Can only be built on habitable planets and gas giants.'];
+ }
+ return 1;
+}
+
# DEMOLISH
View
116 lib/Lacuna/DB/Result/Building/Module.pm
@@ -0,0 +1,116 @@
+package Lacuna::DB::Result::Building::Module;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::DB::Result::Building';
+
+around 'build_tags' => sub {
+ my ($orig, $class) = @_;
+ return ($orig->($class), qw(Infrastructure));
+};
+
+sub image_level {
+ my $self = shift;
+ return $self->image;
+}
+
+use constant energy_consumption => 200;
+use constant water_consumption => 100;
+use constant food_consumption => 100;
+use constant ore_consumption => 100;
+use constant energy_to_build => 500;
+use constant food_to_build => 100;
+use constant ore_to_build => 500;
+use constant water_to_build => 150;
+
+around spend_efficiency => sub {
+ my ($orig, $self, $amount) = @_;
+ if ($self->efficiency <= $amount) {
+ if ($self->level <= 1 && eval{$self->can_demolish}) {
+ $self->demolish;
+ }
+ elsif ($self->level > 1 && eval{$self->can_downgrade}) {
+ $self->downgrade;
+ }
+ else {
+ $orig->($self, $amount);
+ }
+ }
+ else {
+ $orig->($self, $amount);
+ }
+ return $self;
+};
+
+sub cost_to_upgrade {
+ return {
+ food => 0,
+ ore => 0,
+ water => 0,
+ energy => 0,
+ waste => 0,
+ time => 60,
+ };
+}
+
+around can_upgrade => sub {
+ my ($orig, $self, $cost, $from_parliament) = @_;
+ if ($from_parliament) {
+ $orig->($self, $cost);
+ }
+ else {
+ confess [1010, 'Space station modules can only be upgraded by an act of Parliament.'];
+ }
+};
+
+around can_downgrade => sub {
+ my ($orig, $self, $cost, $from_parliament) = @_;
+ if ($from_parliament) {
+ $orig->($self, $cost);
+ }
+ else {
+ confess [1010, 'Space station modules can only be downgraded by an act of Parliament.'];
+ }
+};
+
+around can_demolish => sub {
+ my ($orig, $self, $cost, $from_parliament) = @_;
+ if ($from_parliament) {
+ $orig->($self, $cost);
+ }
+ else {
+ confess [1010, 'Space station modules can only be demolished by an act of Parliament.'];
+ }
+};
+
+around can_build => sub {
+ my ($orig, $self, $cost, $from_parliament) = @_;
+ if ($from_parliament) {
+ $orig->($self, $cost);
+ }
+ else {
+ confess [1010, 'Space station modules can only be built by an act of Parliament.'];
+ }
+};
+
+around can_repair => sub {
+ my ($orig, $self, $cost, $from_parliament) = @_;
+ if ($from_parliament) {
+ $orig->($self, $cost);
+ }
+ else {
+ confess [1010, 'Space station modules can only be repaired by an act of Parliament.'];
+ }
+};
+
+sub can_build_on {
+ my $self = shift;
+ if ($self->isa('Lacuna::DB::Result::Map::Body::Planet::Station')) {
+ confess [1009, 'Can only be built on space stations.'];
+ }
+ return 1;
+}
+
+no Moose;
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
15 lib/Lacuna/DB/Result/Building/Module/IBS.pm
@@ -0,0 +1,15 @@
+package Lacuna::DB::Result::Building::Module::IBS;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::DB::Result::Building::Module';
+
+use constant controller_class => 'Lacuna::RPC::Building::IBS';
+use constant image => 'ibs';
+use constant name => 'Interstellar Broadcast System';
+use constant max_instances_per_planet => 1;
+
+
+no Moose;
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
16 lib/Lacuna/DB/Result/Building/Module/Parliament.pm
@@ -0,0 +1,16 @@
+package Lacuna::DB::Result::Building::Module::Parliament;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::DB::Result::Building::Module';
+
+use constant controller_class => 'Lacuna::RPC::Building::Parliament';
+use constant image => 'parliament';
+use constant name => 'Parliament';
+use constant max_instances_per_planet => 1;
+
+
+
+no Moose;
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
15 lib/Lacuna/DB/Result/Building/Module/StationCommand.pm
@@ -0,0 +1,15 @@
+package Lacuna::DB::Result::Building::Module::StationCommand;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::DB::Result::Building::Module';
+
+use constant controller_class => 'Lacuna::RPC::Building::StationCommand';
+use constant image => 'stationcommand';
+use constant name => 'Station Command Center';
+use constant max_instances_per_planet => 1;
+
+
+no Moose;
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
17 lib/Lacuna/DB/Result/Building/Module/Warehouse.pm
@@ -0,0 +1,17 @@
+package Lacuna::DB::Result::Building::Module::Warehouse;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::DB::Result::Building::Module';
+
+use constant controller_class => 'Lacuna::RPC::Building::Warehouse';
+use constant image => 'warehouse';
+use constant name => 'Warehouse';
+use constant water_storage => 2500;
+use constant energy_storage => 2500;
+use constant food_storage => 2500;
+use constant ore_storage => 2500;
+
+no Moose;
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
3 lib/Lacuna/DB/Result/Map/Body.pm
@@ -185,6 +185,9 @@ __PACKAGE__->belongs_to('star', 'Lacuna::DB::Result::Map::Star', 'star_id');
__PACKAGE__->belongs_to('empire', 'Lacuna::DB::Result::Empire', 'empire_id');
__PACKAGE__->has_many('buildings','Lacuna::DB::Result::Building','body_id');
+sub abandon {
+ my $self = shift;
+}
sub lock {
my $self = shift;
View
15 lib/Lacuna/DB/Result/Map/Body/Planet.pm
@@ -130,6 +130,14 @@ sub sanitize {
return $self;
}
+before abandon => sub {
+ my $self = shift;
+ if ($self->id eq $self->empire->home_planet_id) {
+ confess [1010, 'You cannot abandon your home colony.'];
+ }
+ $self->sanitize;
+};
+
around get_status => sub {
my ($orig, $self, $empire) = @_;
my $out = $orig->($self);
@@ -689,7 +697,7 @@ sub recalc_stats {
$stats{$type.'_production_hour'} = 0;
}
#calculate building production
- my ($gas_giant_platforms, $terraforming_platforms, $pantheon_of_hagness, $total_ore_production_hour, $ore_production_hour, $ore_consumption_hour) = 0;
+ my ($gas_giant_platforms, $terraforming_platforms, $station_command, $pantheon_of_hagness, $total_ore_production_hour, $ore_production_hour, $ore_consumption_hour) = 0;
while (my $building = $buildings->next) {
$stats{waste_capacity} += $building->waste_capacity;
$stats{water_capacity} += $building->water_capacity;
@@ -726,6 +734,9 @@ sub recalc_stats {
if ($building->isa('Lacuna::DB::Result::Building::Permanent::PantheonOfHagness')) {
$pantheon_of_hagness += $building->level;
}
+ if ($building->isa('Lacuna::DB::Result::Building::Module::StationCommand')) {
+ $station_command += $building->level;
+ }
}
# local ore production
@@ -761,7 +772,7 @@ sub recalc_stats {
}
# deal with plot usage
- my $max_plots = $self->size + $pantheon_of_hagness;
+ my $max_plots = $self->size + $pantheon_of_hagness + $station_command;
if ($self->isa('Lacuna::DB::Result::Map::Body::Planet::GasGiant')) {
$max_plots = $gas_giant_platforms < $max_plots ? $gas_giant_platforms : $max_plots;
}
View
28 lib/Lacuna/DB/Result/Map/Body/Planet/Station.pm
@@ -7,6 +7,14 @@ extends 'Lacuna::DB::Result::Map::Body::Planet';
use constant image => 'station';
+after abandon => sub {
+ my $self = shift;
+ $self->update({
+ size => randint(1,10),
+ class => 'Lacuna::DB::Result::Map::Body::Asteroid::A'.randint(1,20),
+ });
+};
+
has command => (
is => 'rw',
lazy => 1,
@@ -27,6 +35,26 @@ sub has_resources_to_operate_after_building_demolished {
return 1;
}
+sub spend_happiness {
+ my $self = shift;
+ return $self;
+}
+
+sub add_happiness {
+ my $self = shift;
+ return $self;
+}
+
+sub spend_waste {
+ my $self = shift;
+ return $self;
+}
+
+sub add_waste {
+ my $self = shift;
+ return $self;
+}
+
no Moose;
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
View
5 lib/Lacuna/DB/Result/Medals.pm
@@ -182,7 +182,10 @@ use constant MEDALS => {
building28 => 'Built Level 28 Building',
building29 => 'Built Level 29 Building',
building30 => 'Built Level 30 Building',
- SAW => 'Built Shield Against Weapons',
+ IBS => 'Built Interstellar Broadcast System',
+ StationCommand => 'Built Station Command Center',
+ Parliament => 'Built Parliament',
+ Warehouse => 'Built Warehouse',
DistributionCenter => 'Built Distribution Center',
AtmosphericEvaporator => 'Built Atmospheric Evaporator',
GreatBallOfJunk => 'Built Great Ball of Junk',
View
17 lib/Lacuna/RPC/Body.pm
@@ -7,6 +7,7 @@ extends 'Lacuna::RPC';
use Lacuna::Verify;
use Lacuna::Constants qw(BUILDABLE_CLASSES);
use DateTime;
+use Lacuna::Util qw(randint);
use List::MoreUtils qw(uniq);
sub get_status {
@@ -19,14 +20,11 @@ sub get_status {
sub abandon {
my ($self, $session_id, $body_id) = @_;
my $empire = $self->get_empire_by_session($session_id);
- if ($body_id eq $empire->home_planet_id) {
- confess [1010, 'You cannot abandon your home colony.'];
- }
my $body = $self->get_body($empire, $body_id);
- $body->sanitize;
- if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::SpaceStation')) {
- $body->delete;
+ if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::SpaceStation')) {
+ confess [1010, 'Space stations can only be abandoned through an act of Parliament.'];
}
+ $body->abandon;
return $self->format_status($empire);
}
@@ -42,6 +40,9 @@ sub rename {
my $empire = $self->get_empire_by_session($session_id);
my $body = $self->get_body($empire, $body_id);
+ if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::SpaceStation')) {
+ confess [1010, 'Space stations can only be renamed through an act of Parliament.'];
+ }
return 1 if $name eq $body->name;
@@ -94,8 +95,8 @@ sub get_buildable {
my $empire = $self->get_empire_by_session($session_id);
my $body = $self->get_body($empire, $body_id);
- if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::SpaceStation')) {
- confess [1010, 'This is not how you expand a space station.'];
+ if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::SpaceStation')) { # short circuiting for better performance
+ confess [1010, 'Space stations can only be expanded through an act of Parliament.'];
}
my $building_rs = Lacuna->db->resultset('Lacuna::DB::Result::Building');
View
21 lib/Lacuna/RPC/Building/IBS.pm
@@ -0,0 +1,21 @@
+package Lacuna::RPC::Building::IBS;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::RPC::Building';
+
+sub app_url {
+ return '/ibs';
+}
+
+sub model_class {
+ return 'Lacuna::DB::Result::Building::Module::IBS';
+}
+
+
+__PACKAGE__->register_rpc_method_names(qw());
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
View
21 lib/Lacuna/RPC/Building/Parliament.pm
@@ -0,0 +1,21 @@
+package Lacuna::RPC::Building::Parliament;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::RPC::Building';
+
+sub app_url {
+ return '/parliament';
+}
+
+sub model_class {
+ return 'Lacuna::DB::Result::Building::Module::Parliament';
+}
+
+
+__PACKAGE__->register_rpc_method_names(qw());
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
View
51 lib/Lacuna/RPC/Building/StationCommand.pm
@@ -0,0 +1,51 @@
+package Lacuna::RPC::Building::StationCommand;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::RPC::Building';
+
+sub app_url {
+ return '/stationcommand';
+}
+
+sub model_class {
+ return 'Lacuna::DB::Result::Building::Module::StationCommand';
+}
+
+around 'view' => sub {
+ my ($orig, $self, $session_id, $building_id) = @_;
+ my $empire = $self->get_empire_by_session($session_id);
+ my $building = $self->get_building($empire, $building_id, skip_offline => 1);
+ my $out = $orig->($self, $empire, $building);
+ $out->{planet} = $building->body->get_status($empire);
+ $out->{next_colony_cost} = $empire->next_colony_cost;
+ return $out;
+};
+
+sub view_plans {
+ my ($self, $session_id, $building_id) = @_;
+ my $empire = $self->get_empire_by_session($session_id);
+ my $building = $self->get_building($empire, $building_id);
+ my @out;
+ my $plans = $building->body->plans;
+ while (my $plan = $plans->next) {
+ push @out, {
+ name => $plan->class->name,
+ level => $plan->level,
+ extra_build_level => $plan->extra_build_level,
+ }
+ }
+ return {
+ status => $self->format_status($empire, $building->body),
+ plans => \@out,
+ }
+}
+
+__PACKAGE__->register_rpc_method_names(qw(view_plans));
+
+
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
View
21 lib/Lacuna/RPC/Building/Warehouse.pm
@@ -0,0 +1,21 @@
+package Lacuna::RPC::Building::Warehouse;
+
+use Moose;
+use utf8;
+no warnings qw(uninitialized);
+extends 'Lacuna::RPC::Building';
+
+sub app_url {
+ return '/warehouse';
+}
+
+sub model_class {
+ return 'Lacuna::DB::Result::Building::Module::Warehouse';
+}
+
+
+__PACKAGE__->register_rpc_method_names(qw());
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
View
2 var/www/public/changes.txt
@@ -1,5 +1,7 @@
2.4800
- Rule: Added Space Station Lab building, which will eventually allow building space station modules.
+ - Rule: Allow building space station hulls.
+ - Rule: Added Station Command Center, Parliament, Warehouse, and IBS modules for space stations.
- API: Sending ships that trigger defenses requires the new captchas.
- API: Sending spies requires the new captchas.
- API: Running spy missions require the new captchas.
View
6 var/www/public/resources.json
@@ -1,5 +1,11 @@
{
"buildings" : {
+ "/stationcommand" : { "description" : "The internal operations of a space station. Controls how big the station can be expanded.", "wiki" : "http://community.lacunaexpanse.com/wiki/station-command-center" },
+ "/parliament" : { "description" : "The central government for the star systems that are controlled by a space station. Laws for the jurisdiction are made here.", "wiki" : "http://community.lacunaexpanse.com/wiki/parliament" },
+ "/warehouse" : { "description" : "Resource storage for a space station.", "wiki" : "http://community.lacunaexpanse.com/wiki/warehouse" },
+ "/ibs" : { "description" : "A means of spreading the culture and influence of a space station's government.", "wiki" : "http://community.lacunaexpanse.com/wiki/interstellar-broadcast-system" },
+ "/stationcommand" : { "description" : "The internal operations of a space station. Controls how big the station can be expanded.", "wiki" : "http://community.lacunaexpanse.com/wiki/station-command-center" },
+ "/stationcommand" : { "description" : "The internal operations of a space station. Controls how big the station can be expanded.", "wiki" : "http://community.lacunaexpanse.com/wiki/station-command-center" },
"/ssla" : { "description" : "Allows the construction of Space Station Lab modules. Requires four plots, and this is the top left corner of the building.", "wiki" : "http://community.lacunaexpanse.com/wiki/space-station-lab" },
"/sslb" : { "description" : "Infrastructure required to support Space Station Lab (A).", "wiki" : "http://community.lacunaexpanse.com/wiki/space-station-lab" },
"/sslc" : { "description" : "Infrastructure required to support Space Station Lab (A).", "wiki" : "http://community.lacunaexpanse.com/wiki/space-station-lab" },

0 comments on commit 78a6ca7

Please sign in to comment.
Something went wrong with that request. Please try again.