From 5a9bc1edd542acc858f3202305b1962865dbaebe Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 23 Nov 2014 16:52:02 -0700 Subject: [PATCH 01/16] Comment out auto alliance room creation for now. --- lib/Lacuna/RPC/Chat.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/RPC/Chat.pm b/lib/Lacuna/RPC/Chat.pm index b241d889..87927a96 100644 --- a/lib/Lacuna/RPC/Chat.pm +++ b/lib/Lacuna/RPC/Chat.pm @@ -32,7 +32,8 @@ sub init_chat { ); my $chat_name = $empire->name; - if ($empire->alliance_id) { +if (0) { +# if ($empire->alliance_id) { $chat_name .= " (".$empire->alliance->name.")"; my $room = eval { $firebase->get('room-metadata/'.$empire->alliance_id) }; if ($@) { @@ -84,7 +85,8 @@ sub init_chat { isStaff => $empire->is_admin ? \1 : \0, isModerator => $empire->chat_admin ? \1 : \0, }; - if ($empire->alliance_id) { + if (0) { +# if ($empire->alliance_id) { $ret->{private_room} = { id => $empire->alliance_id, name => $empire->alliance->name, -- 2.51.2 From 3af0ccd493b07f9dd82cc1ad324a5aefb984ea3d Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 23 Nov 2014 17:12:42 -0700 Subject: [PATCH 02/16] Alliance name though gets added --- lib/Lacuna/RPC/Chat.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Lacuna/RPC/Chat.pm b/lib/Lacuna/RPC/Chat.pm index 87927a96..f6e27fdd 100644 --- a/lib/Lacuna/RPC/Chat.pm +++ b/lib/Lacuna/RPC/Chat.pm @@ -32,7 +32,10 @@ sub init_chat { ); my $chat_name = $empire->name; -if (0) { + if ($empire->alliance_id) { + $chat_name .= " (".$empire->alliance->name.")"; + } + if (0) { # if ($empire->alliance_id) { $chat_name .= " (".$empire->alliance->name.")"; my $room = eval { $firebase->get('room-metadata/'.$empire->alliance_id) }; -- 2.51.2 From adb9a904d908dde9981032cb3d74008f3084c846 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 23 Nov 2014 20:07:06 -0700 Subject: [PATCH 03/16] Dropped alliance chat and munged empire/alliance names. --- lib/Lacuna/RPC/Chat.pm | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/Lacuna/RPC/Chat.pm b/lib/Lacuna/RPC/Chat.pm index f6e27fdd..c2cd1c67 100644 --- a/lib/Lacuna/RPC/Chat.pm +++ b/lib/Lacuna/RPC/Chat.pm @@ -31,13 +31,17 @@ sub init_chat { authobj => $chat_auth, ); my $chat_name = $empire->name; - + my $aname; + $chat_name =~ s/[^0-9a-zA-Z_ ]/_/g; + $chat_name =~ s/__*/_/g; if ($empire->alliance_id) { - $chat_name .= " (".$empire->alliance->name.")"; + $aname = $empire->alliance->name; + $aname =~ s/[^0-9a-zA-Z_ ]/_/g; + $aname =~ s/__*/_/g; + $chat_name .= " (".$aname.")"; } if (0) { # if ($empire->alliance_id) { - $chat_name .= " (".$empire->alliance->name.")"; my $room = eval { $firebase->get('room-metadata/'.$empire->alliance_id) }; if ($@) { warn bleep; @@ -56,7 +60,8 @@ sub init_chat { eval { $firebase->put('room-metadata/'.$empire->alliance_id, { id => $empire->alliance_id, - name => $empire->alliance->name, +# name => $empire->alliance->name, + name => $aname, type => 'private', createdByUserId => $empire->id, '.priority' => {'.sv' => 'timestamp'}, @@ -68,12 +73,12 @@ sub init_chat { } } } - if ($empire->is_admin) { - $chat_name .= " "; - } - elsif ($empire->chat_admin) { - $chat_name .= " "; - } +# if ($empire->is_admin) { +# $chat_name .= " "; +# } +# elsif ($empire->chat_admin) { +# $chat_name .= " "; +# } my $gravatar_id = gravatar_id($empire->email); my $gravatar_url = gravatar_url( email => $empire->email, @@ -92,7 +97,7 @@ sub init_chat { # if ($empire->alliance_id) { $ret->{private_room} = { id => $empire->alliance_id, - name => $empire->alliance->name, + name => $aname, }; } return $ret; -- 2.51.2 From e124decde30b8b07060ada2e0b22a5f45414b464 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Wed, 26 Nov 2014 13:28:21 -0700 Subject: [PATCH 04/16] Added nz entry date --- lib/Lacuna.pm | 2 +- var/upgrades/3.0907.sql | 1 + var/www/public/changes.txt | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 var/upgrades/3.0907.sql diff --git a/lib/Lacuna.pm b/lib/Lacuna.pm index 9f42fd48..6670fb81 100644 --- a/lib/Lacuna.pm +++ b/lib/Lacuna.pm @@ -7,7 +7,7 @@ use Config::JSON; useall __PACKAGE__; -our $VERSION = 3.0906; +our $VERSION = 3.0907; my $config = Config::JSON->new('/data/Lacuna-Server/etc/lacuna.conf'); my $db = Lacuna::DB->connect($config->get('db/dsn'),$config->get('db/username'),$config->get('db/password'), { mysql_enable_utf8 => 1}); diff --git a/var/upgrades/3.0907.sql b/var/upgrades/3.0907.sql new file mode 100644 index 00000000..b0ab59b6 --- /dev/null +++ b/var/upgrades/3.0907.sql @@ -0,0 +1 @@ +alter table body add column `neutral_entry datetime NOT NULL default '2014-11-10 12:00:00'; diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index dd8c7016..0bfa8978 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -1,3 +1,6 @@ +3.0907: + - Add: Timer added to colony object preventing passage into Neutral Zone. + 3.0906: - Fix: Some fixes to the send_ship_types API call. - Fix: Don't list platform plans for splitting in Dillon Forge. -- 2.51.2 From f7d9c1223ac820ecfccd18cf8a21a3d611a7bb77 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Wed, 26 Nov 2014 20:02:55 -0700 Subject: [PATCH 05/16] Limit on when a planet can port into Neutral Area. --- lib/Lacuna/DB/Result/Map/Body.pm | 18 +++++++++++ lib/Lacuna/DB/Result/Map/Body/Planet.pm | 1 + lib/Lacuna/DB/Result/Spies.pm | 4 ++- lib/Lacuna/RPC/Building/BlackHoleGenerator.pm | 32 +++++++++++++++---- lib/Lacuna/RPC/Building/SpacePort.pm | 3 ++ var/upgrades/3.0907.sql | 3 +- 6 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/Lacuna/DB/Result/Map/Body.pm b/lib/Lacuna/DB/Result/Map/Body.pm index 70b94a14..0add5e09 100644 --- a/lib/Lacuna/DB/Result/Map/Body.pm +++ b/lib/Lacuna/DB/Result/Map/Body.pm @@ -129,6 +129,7 @@ __PACKAGE__->add_columns( unhappy_date => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, unhappy => { data_type => 'tinyint', default_value => 0 }, propaganda_boost => { data_type => 'int', default_value => 0 }, + neutral_entry => { data_type => 'datetime', is_nullable => 0, set_on_create => 1 }, ); after 'sqlt_deploy_hook' => sub { @@ -402,5 +403,22 @@ sub is_bhg_neutralized { return 0; } +sub add_to_neutral_entry { + my ($self, $seconds) = @_; + + my $dtf = Lacuna->db->storage->datetime_parser; + my $now = DateTime->now; + if ($self->neutral_entry < $now) { + $self->neutral_entry($now->add(seconds => $seconds)); + } + else { + $self->neutral_entry->clone->add(seconds => $seconds); + my $day_30 = $now->add(days => 30); + $self->neutral_entry($day_30) if ($self->neutral_entry > $day_30); + } + $self->update; + return 1; +} + no Moose; __PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Map/Body/Planet.pm b/lib/Lacuna/DB/Result/Map/Body/Planet.pm index 95db5888..609d044c 100644 --- a/lib/Lacuna/DB/Result/Map/Body/Planet.pm +++ b/lib/Lacuna/DB/Result/Map/Body/Planet.pm @@ -538,6 +538,7 @@ around get_status => sub { $out->{propaganda_boost} = $self->propaganda_boost; $out->{propaganda_boost} = 50 if ($out->{propaganda_boost} > 50); } + $out->{neutral_entry} = format_date($self->neutral_entry); } elsif ($empire->alliance_id && $self->empire->alliance_id == $empire->alliance_id) { $out->{empire}{alignment} = $self->empire->is_isolationist ? 'ally-isolationist' : 'ally'; diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index c5a301f7..81d63abb 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -742,6 +742,8 @@ sub run_mission { $hfa = $defender->home_field_advantage; } my $breakthru = ($power - $toughness - $hfa) + $self->luck; + + $self->on_body->add_to_neutral_entry($power); $breakthru = ( randint(0,99) < 5) ? $breakthru * -1 : $breakthru; # handle outcomes and xp @@ -856,7 +858,7 @@ sub run_security_sweep { } my $breakthru = ($power - $toughness + $self->home_field_advantage) + $self->luck; $breakthru = ( randint(0,99) < 5) ? $breakthru * -1 : $breakthru; - + # handle outcomes and xp my $out; if ($breakthru < 0) { diff --git a/lib/Lacuna/RPC/Building/BlackHoleGenerator.pm b/lib/Lacuna/RPC/Building/BlackHoleGenerator.pm index e8a8a2c4..b25ff366 100644 --- a/lib/Lacuna/RPC/Building/BlackHoleGenerator.pm +++ b/lib/Lacuna/RPC/Building/BlackHoleGenerator.pm @@ -421,24 +421,42 @@ sub check_neutral_violation { else { $target_in = $target->in_neutral_area; } - return 0 unless $target_in; + my $body_in = $body->in_neutral_area; + if (($body_in and $target_in) or (!($body_in) and !($target_in))) { +# Swap in happening fully inside or fully outside Neutral Area + return 0; + } + my $test_body; + if ($target_in) { + $test_body = $body; + } + else { + $test_body = $target; + } + + my $dtf = Lacuna->db->storage->datetime_parser; + my $now = DateTime->now; if ($task->{name} eq "Jump Zone" or $task->{name} eq "Swap Places") { - if ( $body->has_outgoing_ships(100) ) { + if ( $test_body->neutral_entry > $now ) { $throw = 1009; - $reason = sprintf("Colony %s has travelling ships, disallowing a jump to the Neutral Area.", $body->name); + $reason = sprintf("Colony %s can not enter the neutral area until %s.", $test_body->name, $dtf->format_datetime($test_body->neutral_entry)); return $throw, $reason; } } elsif ($task->{name} eq "Move System") { - my $bodies = Lacuna->db->resultset('Map::Body')->search({star_id => [ $body->star_id ]}); + my $bodies = Lacuna->db->resultset('Map::Body')->search({star_id => [ $test_body->star_id ]}); + my $fail = 0; while (my $obody = $bodies->next) { next unless (defined($obody->empire)); - if ( $obody->has_outgoing_ships(100) ) { + if ( $obody->neutral_entry > $now ) { $throw = 1009; - $reason = sprintf("Colony %s has travelling ships, disallowing a jump to the Neutral Area.", $obody->name); - return $throw, $reason; + $reason = sprintf("Colony %s can not enter the neutral area until %s.", $obody->name, $dtf->format_datetime($obody->neutral_entry)); + $fail = 1; } } + if ($fail) { + return $throw, $reason; + } } return 0; } diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 2e46c4db..d69a89e4 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -220,6 +220,7 @@ sub send_ship { if ($ship->hostile_action) { $empire->current_session->check_captcha; } + $body->add_to_neutral_entry($ship->combat); $ship->send(target => $target); return { ship => $ship->get_status, @@ -331,6 +332,7 @@ sub send_ship_types { } # If we get here without exceptions, then all ships can be sent foreach my $ship (values %$ship_ref) { + $body->add_to_neutral_entry($ship->combat); $ship->fleet_speed(1); $ship->send(target => $target, arrival => $arrival); } @@ -384,6 +386,7 @@ sub send_fleet { $empire->current_session->check_captcha; $captcha_check = 0; } + $body->add_to_neutral_entry($ship->combat); $ship->fleet_speed($speed); $ship->send(target => $target); push @ret, { diff --git a/var/upgrades/3.0907.sql b/var/upgrades/3.0907.sql index b0ab59b6..978a5cc8 100644 --- a/var/upgrades/3.0907.sql +++ b/var/upgrades/3.0907.sql @@ -1 +1,2 @@ -alter table body add column `neutral_entry datetime NOT NULL default '2014-11-10 12:00:00'; +alter table body add column `neutral_entry` datetime NOT NULL default '2014-11-10 12:00:00'; + -- 2.51.2 From 8fd96f599a4a1c4594c228c8d75069303b9a551d Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Fri, 28 Nov 2014 14:17:33 -0700 Subject: [PATCH 06/16] Subtract time from neutral exile if attacked. --- lib/Lacuna/DB/Result/Map/Body.pm | 16 ++++++++++++++-- lib/Lacuna/DB/Result/Spies.pm | 3 ++- lib/Lacuna/Role/Ship/Arrive/TriggerDefense.pm | 3 +++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Lacuna/DB/Result/Map/Body.pm b/lib/Lacuna/DB/Result/Map/Body.pm index 0add5e09..baa2d5df 100644 --- a/lib/Lacuna/DB/Result/Map/Body.pm +++ b/lib/Lacuna/DB/Result/Map/Body.pm @@ -406,13 +406,12 @@ sub is_bhg_neutralized { sub add_to_neutral_entry { my ($self, $seconds) = @_; - my $dtf = Lacuna->db->storage->datetime_parser; my $now = DateTime->now; if ($self->neutral_entry < $now) { $self->neutral_entry($now->add(seconds => $seconds)); } else { - $self->neutral_entry->clone->add(seconds => $seconds); + $self->neutral_entry($self->neutral_entry->add(seconds => $seconds)); my $day_30 = $now->add(days => 30); $self->neutral_entry($day_30) if ($self->neutral_entry > $day_30); } @@ -420,5 +419,18 @@ sub add_to_neutral_entry { return 1; } +sub subtract_from_neutral_entry { + my ($self, $seconds) = @_; + + my $now = DateTime->now; + my $time_ends = $self->neutral_entry->clone->subtract(seconds => $seconds); + $self->neutral_entry($time_ends); + if ($self->neutral_entry < $now) { + $self->neutral_entry($now); + } + $self->update; + return 1; +} + no Moose; __PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index 81d63abb..f694790d 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -743,7 +743,8 @@ sub run_mission { } my $breakthru = ($power - $toughness - $hfa) + $self->luck; - $self->on_body->add_to_neutral_entry($power); + $self->from_body->add_to_neutral_entry($mission->{recovery}); + $self->on_body->subtract_from_neutral_entry(int($mission->{recovery}/2)); $breakthru = ( randint(0,99) < 5) ? $breakthru * -1 : $breakthru; # handle outcomes and xp diff --git a/lib/Lacuna/Role/Ship/Arrive/TriggerDefense.pm b/lib/Lacuna/Role/Ship/Arrive/TriggerDefense.pm index 6707b951..99b96573 100644 --- a/lib/Lacuna/Role/Ship/Arrive/TriggerDefense.pm +++ b/lib/Lacuna/Role/Ship/Arrive/TriggerDefense.pm @@ -31,6 +31,9 @@ after handle_arrival_procedures => sub { # set last attack status $body_attacked->set_last_attacked_by($ship_body->id); + # subtract from time being able to jump to neutral area + $body_attacked->subtract_from_neutral_entry(int($self->combat/5)); + # get SAWs $self->system_saw_combat; -- 2.51.2 From 088e15f0ff7ae9ed6211a2ec777cddc23f3923a7 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Fri, 28 Nov 2014 18:33:05 -0700 Subject: [PATCH 07/16] Saben don't beat up starter zones and util for seeding fissures, and inflating asteroids. --- bin/saben/send_attack.pl | 5 +- bin/util/inflate_asteroids.pl | 105 +++++++++++++++++++++++++++ bin/util/seed_fissures.pl | 129 ++++++++++++++++++++++++++++++++++ lib/Lacuna/AI/Saben.pm | 2 +- 4 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 bin/util/inflate_asteroids.pl create mode 100644 bin/util/seed_fissures.pl diff --git a/bin/saben/send_attack.pl b/bin/saben/send_attack.pl index 814c2b1f..d39ccd7c 100644 --- a/bin/saben/send_attack.pl +++ b/bin/saben/send_attack.pl @@ -48,13 +48,14 @@ while (my $attacking_colony = $colonies->next) { out('Attacked recently from '.$attacking_colony->name); next; } - $ai->destroy_world($attacking_colony); - out('Finding target body to attack...'); if ($attacking_colony->in_neutral_area or $attacking_colony->in_starter_zone) { out($attacking_colony->name." in Neutral Area or a Starting Zone, skipping."); next; } + $ai->destroy_world($attacking_colony); + out('Finding target body to attack...'); + my $targets = $db->resultset('Lacuna::DB::Result::Map::Body')->search({ empire_id => { '>' => 1 }, is_isolationist => 0, diff --git a/bin/util/inflate_asteroids.pl b/bin/util/inflate_asteroids.pl new file mode 100644 index 00000000..ac6453fc --- /dev/null +++ b/bin/util/inflate_asteroids.pl @@ -0,0 +1,105 @@ +# Reinflate asteroids into planets +use 5.010; +use strict; +use lib '/data/Lacuna-Server/lib'; +use Lacuna::DB; +use Lacuna; +use Lacuna::Util qw(randint format_date); +use Getopt::Long; +$|=1; +our $quiet; +our $target_zone; +our $target_body_id; +our $number = 10_000; + +GetOptions( + 'zone=s' => \$target_zone, + 'body_id=i' => \$target_body_id, + 'number=i' => \$number, + 'quiet' => \$quiet, +); + +die "$0 --zone ZONE --body_id BODYID --number NUMBER\n" unless $target_zone or $target_body_id; + +out('Started'); +my $start = time; + +out('Loading DB'); +our $db = Lacuna->db; + +my $search = { + class => { like => 'Lacuna::DB::Result::Map::Body::Asteroid::%' }, +}; + +if ($target_zone ne '') { + $search->{zone} = $target_zone; +} +if ($target_body_id ne '') { + $search->{id} = $target_body_id; + $number = 1; +} + +out('Reviewing asteroids'); +my $rocks_rs = $db->resultset('Lacuna::DB::Result::Map::Body'); +my @rocks = $rocks_rs->search( + $search, + )->get_column('id')->all; +out('Found '.scalar @rocks.' asteroids.'); + +my $changed = 0; my $unchanged = 0; +foreach my $id (sort { 5 > randint(10) } @rocks) { + my $rock = $rocks_rs->find($id); + next unless ($rock->get_type eq 'asteroid'); + + my $orbit = $rock->orbit; + + my $new_t = randint(1,Lacuna::DB::Result::Map::Body->planet_types); + my $class = 'Lacuna::DB::Result::Map::Body::Planet::P'.$new_t; + my $size = 30; + my $old_class = $rock->class; + $old_class =~ s/.*:://; + my $pcount = Lacuna->db->resultset('Lacuna::DB::Result::MiningPlatforms') + ->search({asteroid_id => $id })->count; + out( sprintf("%30s %6d %3s -> P%3s o:%s (%4d,%4d) Z:%5s %d", + $rock->name, $rock->id, + $old_class, $new_t, + $rock->orbit, + $rock->x, $rock->y, + $rock->zone, + $pcount, + )); + if ($pcount) { + $unchanged++; + } + else { + $rock->size(45); + $rock->class($class); + if ($rock->orbit != 8) { + $rock->usable_as_starter(randint(8000,9000) + 450 - abs($rock->y) - abs($rock->x)); + $rock->usable_as_starter_enabled(1); + } + $rock->update; + $changed++; + } + if ($changed >= $number) { + out("All done."); + last; + } +} + +my $finish = time; +out('Finished'); +out((($finish - $start)/60)." minutes have elapsed"); +out(sprintf("%6d Asteroids checked, %6d changed to planets, %6d unchanged", scalar @rocks, $changed, $unchanged)); + + +############### +## SUBROUTINES +############### + +sub out { + my $message = shift; + unless ($quiet) { + say format_date(DateTime->now), " ", $message; + } +} diff --git a/bin/util/seed_fissures.pl b/bin/util/seed_fissures.pl new file mode 100644 index 00000000..2360ad34 --- /dev/null +++ b/bin/util/seed_fissures.pl @@ -0,0 +1,129 @@ +use 5.010; +use strict; +use lib '/data/Lacuna-Server/lib'; +use Data::Dumper; +use Lacuna::DB; +use Lacuna; +use Lacuna::Util qw(randint format_date random_element); +use Getopt::Long; +$|=1; +our $quiet; +our $number = 1; +our $target_zone; +our $target_body_id; + +GetOptions( + 'quiet' => \$quiet, + 'number=i' => \$number, + 'zone=s' => \$target_zone, + 'body_id=i' => \$target_body_id, +); + +out("Putting ".$number." fissures in ".$target_zone." on ".$target_body_id."."); + +my $search = { + class => { like => 'Lacuna::DB::Result::Map::Body::Planet::P%' }, +}; + +if ($target_zone ne '') { + $search->{zone} = $target_zone; +} +if ($target_body_id ne '') { + $search->{id} = $target_body_id; + $number = 1; +} +else { + $search->{empire_id} = undef; + usable_as_starter_enabled => 0, +} + +out('Started'); +my $start = time; + +out('Loading DB'); +our $db = Lacuna->db; + +my $placed = 0; +while ($placed < $number) { + my $target = Lacuna->db->resultset('Lacuna::DB::Result::Map::Body')->search( + $search, + {rows => 1, order_by => 'rand()' } + )->single; + unless (defined $target) { + print "No body found\n"; + $placed++; + next; + } + my $btype = $target->get_type; + + my ($throw, $reason) = check_bhg_neutralized($target); + if ($throw > 0) { + out($reason); + } + elsif ($btype eq 'habitable planet') { + my ($x, $y) = eval { $target->find_free_space}; + unless ($@) { + my $building = Lacuna->db->resultset('Lacuna::DB::Result::Building')->new({ + x => $x, + y => $y, + level => randint(1, 30), + body_id => $target->id, + body => $target, + class => 'Lacuna::DB::Result::Building::Permanent::Fissure', + }); + $target->build_building($building, undef, 1); + out(sprintf('Level %s Fissure formed on %s:%s in zone %s.', $building->level, $target->id, $target->name, $target->zone )); + $placed++; + } + else { + out(sprintf('No fissure placed on %s.', $target->name)); + } + } + else { + out(sprintf('No fissure placed on %s.', $target->name)); + } +} + +exit; + +sub check_bhg_neutralized { + my ($check) = @_; + my $tstar; my $tname; + if (ref $check eq 'HASH') { + $tstar = $check->{star}; + $tname = $check->{name}; + } + else { + if ($check->isa('Lacuna::DB::Result::Map::Star')) { + $tstar = $check; + $tname = $check->name; + } + else { + $tstar = $check->star; + $tname = $check->name; + } + } + my $sname = $tstar->name; + my $throw; my $reason; + if ($tstar->station_id) { + if ($tstar->station->laws->search({type => 'BHGNeutralized'})->count) { + my $ss_name = $tstar->station->name; + $throw = 1009; + $reason = sprintf("The star, %s is under BHG Neutralization from %s", $sname, $ss_name), + return $throw, $reason; + } + } + return 0, ""; +} + +############### +## SUBROUTINES +############### + +sub out { + my $message = shift; + unless ($quiet) { + say format_date(DateTime->now), " ", $message; + } +} + diff --git a/lib/Lacuna/AI/Saben.pm b/lib/Lacuna/AI/Saben.pm index bc69f00b..0499b6d9 100644 --- a/lib/Lacuna/AI/Saben.pm +++ b/lib/Lacuna/AI/Saben.pm @@ -147,7 +147,7 @@ sub run_hourly_colony_updates { sub destroy_world { my ($self, $colony) = @_; if ($colony->is_bhg_neutralized) { - say "BHG is neutralized by a space station."; + say sprintf("BHG of %s is neutralized by a space station.",$colony->name); return; } my $enemies = Lacuna->db->resultset('Lacuna::DB::Result::Spies') -- 2.51.2 From ac6130f257eb9bde346927fdfe4998d549189563 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sat, 29 Nov 2014 15:49:04 -0700 Subject: [PATCH 08/16] Added colonies/stations to empire status. planets kept as union of both. --- bin/util/inflate_asteroids.pl | 2 +- docs/Empire.pod | 10 +++++++++- lib/Lacuna/DB/Result/Empire.pm | 10 ++++++++++ var/www/public/changes.txt | 1 + 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/bin/util/inflate_asteroids.pl b/bin/util/inflate_asteroids.pl index ac6453fc..70007382 100644 --- a/bin/util/inflate_asteroids.pl +++ b/bin/util/inflate_asteroids.pl @@ -47,7 +47,7 @@ my @rocks = $rocks_rs->search( out('Found '.scalar @rocks.' asteroids.'); my $changed = 0; my $unchanged = 0; -foreach my $id (sort { 5 > randint(10) } @rocks) { +foreach my $id (sort { 5 > rand(10) } @rocks) { my $rock = $rocks_rs->find($id); next unless ($rock->get_type eq 'asteroid'); diff --git a/docs/Empire.pod b/docs/Empire.pod index ae2ed388..1361bd80 100644 --- a/docs/Empire.pod +++ b/docs/Empire.pod @@ -214,6 +214,10 @@ B You should probably B call this method directly, as it is a wast "server" : { ... }, "empire" : { "id" : "xxxx", + "colonies" : { + "id-goes-here" : "Earth", + "id-goes-here" : "Mars" + }, "rpc_count" : 321, # the number of calls made to the server "is_isolationist" : 1, # hasn't sent out probes or colony ships "name" : "The Syndicate", @@ -224,11 +228,15 @@ B You should probably B call this method directly, as it is a wast "essentia" : 0, "planets" : { "id-goes-here" : "Earth", - "id-goes-here" : "Mars + "id-goes-here" : "Mars", + "id-goes-here" : "Death Star" }, "tech_level" : 20, # Highests level university has gotten to. "self_destruct_active" : 0, "self_destruct_date" : "", + "stations" : { + "id-goes-here" : "Death Star" + }, "primary_embassy_id" : 234567 } } diff --git a/lib/Lacuna/DB/Result/Empire.pm b/lib/Lacuna/DB/Result/Empire.pm index 2ceb3421..ad58a82e 100644 --- a/lib/Lacuna/DB/Result/Empire.pm +++ b/lib/Lacuna/DB/Result/Empire.pm @@ -451,8 +451,16 @@ sub get_status { $planet_rs = Lacuna->db->resultset('Map::Body')->search({-or => { empire_id => $self->id, alliance_id => $self->alliance_id }}); } my %planets; + my %stations; + my %colonies; while (my $planet = $planet_rs->next) { $planets{$planet->id} = $planet->name; + if ($planet->get_type eq 'space station') { + $stations{$planet->id} = $planet->name; + } + else { + $colonies{$planet->id} = $planet->name; + } } my $embassy = $self->highest_embassy; my $embassy_id = defined $embassy ? $embassy->id : undef; @@ -469,6 +477,8 @@ sub get_status { home_planet_id => $self->home_planet_id, tech_level => $self->university_level, planets => \%planets, + stations => \%stations, + colonies => \%colonies, self_destruct_active=> $self->self_destruct_active, self_destruct_date => $self->self_destruct_date_formatted, primary_embassy_id => $embassy_id, diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index 0bfa8978..a2b231a1 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -1,5 +1,6 @@ 3.0907: - Add: Timer added to colony object preventing passage into Neutral Zone. + - Add: colonies and stations added to empire stat. planets kept to maintain backwards compatibility 3.0906: - Fix: Some fixes to the send_ship_types API call. -- 2.51.2 From 30b6cda6ceac3e115c6e0798d05270d6a819317c Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sat, 29 Nov 2014 16:48:29 -0700 Subject: [PATCH 09/16] Make Police Station add Gauntlet action. --- .../Result/Building/Module/PoliceStation.pm | 26 +++++++++++++++++++ lib/Lacuna/DB/Result/Spies.pm | 13 ++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/DB/Result/Building/Module/PoliceStation.pm b/lib/Lacuna/DB/Result/Building/Module/PoliceStation.pm index b3485b6f..d6a41f85 100644 --- a/lib/Lacuna/DB/Result/Building/Module/PoliceStation.pm +++ b/lib/Lacuna/DB/Result/Building/Module/PoliceStation.pm @@ -70,6 +70,32 @@ sub orbiting_ships { ); } +before 'repair' => sub { + my $self = shift; + my $db = Lacuna->db; + my $now = DateTime->now; + my $dtf = $db->storage->datetime_parser; + my $i_spies = $db->resultset('Spies') + ->search( { on_body_id => $self->body->id, + empire_id => { '!=' => $self->body->empire_id }, + available_on => { '<' => $dtf->format_datetime($now) }, + task => 'Travelling', + }); + while (my $spy = $i_spies->next) { + my $starting_task = $spy->task; + $spy->is_available; + if ($spy->task eq 'Idle' && $starting_task ne 'Idle') { + if (!$spy->empire->skip_spy_recovery) { + $spy->empire->send_predefined_message( + tags => ['Intelligence'], + filename => 'ready_for_assignment.txt', + params => [$spy->name, $spy->from_body->id, $spy->from_body->name], + ); + } + } + } +}; + no Moose; __PACKAGE__->meta->make_immutable(inline_constructor => 0); diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index f694790d..390226e5 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -486,9 +486,18 @@ sub is_available { $self->on_body->update; if (!$self->empire->alliance_id || $self->empire->alliance_id != $self->on_body->empire->alliance_id ) { my $seconds = 3600; - my $gauntlet = $self->on_body->get_building_of_class('Lacuna::DB::Result::Building::Permanent::GratchsGauntlet'); + my $onbody = $self->on_body; + my $building = 'Permanent::GratchsGauntlet'; + my $uni_level = $body->empire->university_level; + if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::Station')) { + $building = 'Module::PoliceStation'; + $uni_level = 30; #This way, uni level doesn't matter with SS + } + my $gauntlet = $body->get_building_of_class('Lacuna::DB::Result::Building::'.$building); if (defined $gauntlet) { - $seconds += int(3600 * (($gauntlet->level * 3 * $gauntlet->efficiency)/100 + 1)); + my $level = $gauntlet->level; + $level = $uni_level if ($level > $uni_level); + $seconds += int(3600 * (($level * 3 * $gauntlet->efficiency)/100 + 1)); } my $infiltration_time = $self->available_on->clone->add(seconds => $seconds); -- 2.51.2 From b0b285576d4b3fe6809a6494db2b8e71a28773af Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sat, 29 Nov 2014 16:56:53 -0700 Subject: [PATCH 10/16] fixing typos --- lib/Lacuna/DB/Result/Spies.pm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index 390226e5..1f5a82ac 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -486,14 +486,13 @@ sub is_available { $self->on_body->update; if (!$self->empire->alliance_id || $self->empire->alliance_id != $self->on_body->empire->alliance_id ) { my $seconds = 3600; - my $onbody = $self->on_body; my $building = 'Permanent::GratchsGauntlet'; - my $uni_level = $body->empire->university_level; - if ($body->isa('Lacuna::DB::Result::Map::Body::Planet::Station')) { + my $uni_level = $self->on_body->empire->university_level; + if ($self->on_body->isa('Lacuna::DB::Result::Map::Body::Planet::Station')) { $building = 'Module::PoliceStation'; $uni_level = 30; #This way, uni level doesn't matter with SS } - my $gauntlet = $body->get_building_of_class('Lacuna::DB::Result::Building::'.$building); + my $gauntlet = $self->on_body->get_building_of_class('Lacuna::DB::Result::Building::'.$building); if (defined $gauntlet) { my $level = $gauntlet->level; $level = $uni_level if ($level > $uni_level); -- 2.51.2 From 4c33f1bbe87c3a209e1120f6f2b4de8bafd1ddc3 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 30 Nov 2014 15:23:04 -0700 Subject: [PATCH 11/16] Finish Bugout, Sabotage Defenses, and fetching issues. --- lib/Lacuna/DB/Result/Ships/SpyPod.pm | 1 + lib/Lacuna/DB/Result/Ships/SpyShuttle.pm | 1 + lib/Lacuna/DB/Result/Spies.pm | 203 ++++++++++++++++++- lib/Lacuna/Role/Ship/Arrive/Orbit.pm | 1 + lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm | 1 + var/messages/on_way_home.txt | 7 + var/messages/unauthorized_launch.txt | 8 + var/messages/unauthorized_launch_tracked.txt | 9 + var/www/public/changes.txt | 3 + 9 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 var/messages/on_way_home.txt create mode 100644 var/messages/unauthorized_launch.txt create mode 100644 var/messages/unauthorized_launch_tracked.txt diff --git a/lib/Lacuna/DB/Result/Ships/SpyPod.pm b/lib/Lacuna/DB/Result/Ships/SpyPod.pm index b0a1c1f1..b192db80 100644 --- a/lib/Lacuna/DB/Result/Ships/SpyPod.pm +++ b/lib/Lacuna/DB/Result/Ships/SpyPod.pm @@ -26,6 +26,7 @@ with "Lacuna::Role::Ship::Send::NotIsolationist"; with "Lacuna::Role::Ship::Send::LoadWithSpies"; with "Lacuna::Role::Ship::Send::IsHostile"; with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; with "Lacuna::Role::Ship::Arrive::CargoExchange"; with "Lacuna::Role::Ship::Arrive::Scuttle"; diff --git a/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm b/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm index a32487dd..76336f0e 100644 --- a/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm +++ b/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm @@ -27,6 +27,7 @@ with "Lacuna::Role::Ship::Send::LoadWithSpies"; with "Lacuna::Role::Ship::Send::IsHostile"; with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; with "Lacuna::Role::Ship::Arrive::Orbit"; +with "Lacuna::Role::Ship::Arrive::PickUpSpies"; with "Lacuna::Role::Ship::Arrive::CargoExchange"; no Moose; diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index 1f5a82ac..5c9d0028 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -171,6 +171,11 @@ sub offensive_assignments { recovery => $self->recovery_time(60 * 60 * 8), skill => 'mayhem', }, + { + task =>'Sabotage Defenses', + recovery => $self->recovery_time(60 * 60 * 10), + skill => 'mayhem', + }, { task =>'Sabotage BHG', recovery => 0, @@ -262,13 +267,23 @@ sub defensive_assignments { sub neutral_assignments { my $self = shift; - return ( + my @assignments = ( { task => 'Idle', recovery => 0, skill => 'none', }, ); + if ($self->on_body->id ne $self->from_body_id) { + push @assignments, ( + { + task =>'Bugout', + recovery => 0, + skill => '*', + }, + ); + } + return @assignments; } sub get_possible_assignments { @@ -531,6 +546,7 @@ use constant assignments => ( 'Rescue Comrades', 'Sabotage Resources', 'Appropriate Resources', + 'Sabotage Defenses', 'Sabotage Infrastructure', 'Sabotage BHG', 'Assassinate Operatives', @@ -539,6 +555,7 @@ use constant assignments => ( 'Incite Rebellion', 'Appropriate Technology', 'Incite Insurrection', + 'Bugout', 'Intel Training', 'Mayhem Training', 'Politics Training', @@ -620,6 +637,9 @@ sub assign { elsif ($assignment eq 'Security Sweep') { return $self->run_security_sweep($mission); } + elsif ($assignment eq 'Bugout') { + return $self->bugout($mission); + } else { return $self->run_mission($mission); } @@ -684,6 +704,7 @@ my %outcomes = ( 'Appropriate Technology' => 'appropriate_tech', 'Sabotage Probes' => 'sabotage_probes', 'Rescue Comrades' => 'rescue_comrades', + 'Sabotage Defenses' => 'sabotage_defenses', 'Sabotage Resources' => 'sabotage_resources', 'Appropriate Resources' => 'appropriate_resources', 'Assassinate Operatives' => 'assassinate_operatives', @@ -943,6 +964,88 @@ sub run_security_sweep { return $out; } +sub bugout { + my ($self, $mission) = @_; + + if (!$self->empire->alliance_id || $self->empire->alliance_id != $self->on_body->empire->alliance_id ) { + my $power = $self->offense + $self->intel_xp; + my $toughness = 0; + my $defender = $self->get_defender; + my $hfa = 0; + if (defined $defender) { + $toughness = $defender->defense + $defender->intel_xp; + $hfa = $defender->home_field_advantage; + } + my $breakthru = ($power - $toughness - $hfa) + $self->luck; + + $breakthru = ( randint(0,99) < 5) ? $breakthru * -1 : $breakthru; + if ($breakthru < -2000) { + $self->on_body->add_news(50, + 'An enemy agent narrowly got away from the security forces of %s.', + $self->on_body->name); + $self->on_body->empire->send_predefined_message( + tags => ['Spies','Alert'], + filename => 'unauthorized_launch_tracked.txt', + params => [$self->on_body->id, $self->on_body->name, + $self->from_body->x, $self->from_body->y, $self->from_body->name], + ); +#Narrow escape home + } + elsif ($breakthru > 500) { +#Clean escape + $self->on_body->add_news(10, + 'An unauthorized ship launching happened on %s.', + $self->on_body->name); + } + else { + $self->on_body->add_news(50, + 'An unauthorized ship launching happened on %s.', + $self->on_body->name); + $self->on_body->empire->send_predefined_message( + tags => ['Spies','Alert'], + filename => 'unauthorized_launch.txt', + params => [$self->on_body->id, $self->on_body->name], + ); + } + $self->empire->send_predefined_message( + tags => ['Intelligence'], + filename => 'on_way_home.txt', + params => [ + $self->on_body->empire->id, + $self->on_body->empire->name, + $self->on_body->x, + $self->on_body->y, + $self->on_body->name, + $self->name, + $self->from_body->id, + $self->from_body->name], + ); + } + my $spy_pod = Lacuna->db->resultset('Ships')->new({ + body_id => $self->from_body_id, + type => 'spy_pod', + name => "Bugout", + })->insert; + $spy_pod->date_available(DateTime->now); + $spy_pod->speed(1000+ ($self->level*100)); + $spy_pod->send( + target => $self->on_body, + direction => 'in', + payload => { spies => [ $self->id ] } + ); + $self->available_on($spy_pod->date_available); + $self->on_body_id($self->from_body_id); + $self->task('Travelling'); + $self->started_assignment(DateTime->now); + $self->update; + my $out = { result => 'Success', +# message_id => $message_id, + reason => random_element(['Mom would have been proud.', + 'Done.', + 'That is why you pay me the big bucks.']) }; + return $out; +} + sub get_defender { my ($self, $mission) = @_; @@ -1546,6 +1649,26 @@ sub abduct_operatives_loss { } } +sub sabotage_defenses { + my $self = shift; + given (randint(1,4)) { + when (1) { return $self->knock_defender_unconscious(@_) } + when (2) { return $self->shut_down_defenses(@_) } + when (3) { return $self->shut_down_defenses(@_) } + when (4) { return $self->destroy_defense_ship(@_) } +# when (5) { return $self->destroy_incoming_supply(@_) } + } +} + +sub sabotage_defenses_loss { + my $self = shift; + given (randint(1,3)) { + when (1) { return $self->capture_saboteur(@_) } + when (2) { return $self->thwart_saboteur(@_) } + when (3) { return $self->knock_attacker_unconscious(@_) } + } +} + sub sabotage_resources { my $self = shift; given (randint(1,9)) { @@ -2269,6 +2392,44 @@ sub destroy_infrastructure { )->id; } +sub destroy_defense_ship { + my ($self, $defender) = @_; + my $ship = $self->on_body->ships->search( + {task => 'Docked', + type => {'in' => ['sweeper', + 'fighter', + 'drone', + ]}, + }, + {rows => 1, order_by => 'rand()' } + )->single; + + return $self->ship_not_found->id unless (defined $ship); + $self->things_destroyed( $self->things_destroyed + 1 ); + $self->on_body->empire->send_predefined_message( + tags => ['Spies','Alert'], + filename => 'ship_blew_up_at_port.txt', + params => [$ship->type_formatted, $self->on_body->id, $self->on_body->name], + ); + my $message = $self->empire->send_predefined_message( + tags => ['Intelligence'], + filename => 'sabotage_report.txt', + params => [$ship->type_formatted, + $self->on_body->x, + $self->on_body->y, + $self->on_body->name, + $self->name, + $self->from_body->id, + $self->from_body->name], + ); + $self->on_body->add_news(90, + 'Today officials on %s are investigating the explosion of a %s at the Space Port.', + $self->on_body->name, + $ship->type_formatted); + $ship->delete; + return $message->id; +} + sub destroy_ship { my ($self, $defender) = @_; my $ship = $self->on_body->ships->search( @@ -2788,6 +2949,46 @@ sub thwart_thief { return $defender->thwart_a_spy($self)->id; } +sub shut_down_defenses { + my ($self, $defender) = @_; + + my ($building) = sort { + rand() <=> rand() + } + grep { + ($_->efficiency > 0) and ( + $_->class eq 'Lacuna::DB::Result::Building::SAW' or + $_->class eq 'Lacuna::DB::Result::Building::Shipyard' or + $_->class eq 'Lacuna::DB::Result::Building::Intelligence' or + $_->class eq 'Lacuna::DB::Result::Building::Security' or + $_->class eq 'Lacuna::DB::Result::Building::Module::PoliceStation' or + $_->class eq 'Lacuna::DB::Result::Building::Permanent::GratchsGauntlet' or + $_->class eq 'Lacuna::DB::Result::Building::Permanent::CitadelOfKnope' ) + } + @{$self->on_body->building_cache}; + + return $self->building_not_found->id unless defined $building; + $self->on_body->empire->send_predefined_message( + tags => ['Spies','Alert'], + filename => 'building_loss_of_power.txt', + params => [$building->name, $self->on_body->id, $self->on_body->name], + ); + $building->spend_efficiency(2 * $self->level)->update; + $self->on_body->add_news(25, + 'Employees at the %s on %s were left in the dark today during a power outage.', + $building->name, + $self->on_body->name); + return $self->empire->send_predefined_message( + tags => ['Intelligence'], + filename => 'we_disabled_a_building.txt', + params => [$building->name, + $self->on_body->x, + $self->on_body->y, + $self->on_body->name, + $self->format_from], + )->id; +} + sub shut_down_building { my ($self, $defender) = @_; diff --git a/lib/Lacuna/Role/Ship/Arrive/Orbit.pm b/lib/Lacuna/Role/Ship/Arrive/Orbit.pm index f44e6cd9..bff33ede 100644 --- a/lib/Lacuna/Role/Ship/Arrive/Orbit.pm +++ b/lib/Lacuna/Role/Ship/Arrive/Orbit.pm @@ -12,6 +12,7 @@ after handle_arrival_procedures => sub { # only orbit on arrival to the foreign body return if $self->direction eq 'in'; + return if ( $self->payload->{fetch_spies} ); # Don't orbit if we're fetching $self->orbit->update; confess [-1]; diff --git a/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm b/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm index 1e91e2e7..f2859fef 100644 --- a/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm +++ b/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm @@ -8,6 +8,7 @@ after send => sub { return if ( $self->direction eq 'in' && $self->type ne 'spy_shuttle' ); # load outbound ships and inbound spy shuttles return if ( $self->payload->{mercenary} ); # Mercenary already loaded return if ( $self->payload->{spies} ); # Spies already loaded + return if ( $self->payload->{fetch_spies} ); # Don't send spies if we are fetching my $arrives = DateTime->now->add(seconds=>$self->calculate_travel_time($self->foreign_body)); my @spies; my $to_body = $self->direction eq 'out' ? $self->foreign_body : $self->body; diff --git a/var/messages/on_way_home.txt b/var/messages/on_way_home.txt new file mode 100644 index 00000000..af63d8f9 --- /dev/null +++ b/var/messages/on_way_home.txt @@ -0,0 +1,7 @@ +On Way Home +~~~ +I managed to give {Empire %s %s}'s goons the slip and am heading away from {Starmap %s %s %s}. I'll be home soon. + +Regards, + +%s of {Planet %s %s} diff --git a/var/messages/unauthorized_launch.txt b/var/messages/unauthorized_launch.txt new file mode 100644 index 00000000..0ee9c69c --- /dev/null +++ b/var/messages/unauthorized_launch.txt @@ -0,0 +1,8 @@ +Unauthorized Launch +~~~ +A launch was seen leaving the atmosphere just now from {Planet %s %s}. + +Regards, + +Your Humble Assistant + diff --git a/var/messages/unauthorized_launch_tracked.txt b/var/messages/unauthorized_launch_tracked.txt new file mode 100644 index 00000000..6e4ca9a3 --- /dev/null +++ b/var/messages/unauthorized_launch_tracked.txt @@ -0,0 +1,9 @@ +Launch Tracked +~~~ +A launch was seen leaving the atmosphere just now from {Planet %s %s}. +We managed to track it long enough to see that it is headed for {Starmap %s %s %s}. + +Regards, + +Your Humble Assistant + diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index a2b231a1..c0df7045 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -1,6 +1,9 @@ 3.0907: - Add: Timer added to colony object preventing passage into Neutral Zone. - Add: colonies and stations added to empire stat. planets kept to maintain backwards compatibility + - Fix: Fetching Spies no longer will send more spies. + - Add: Sabotage Defenses task added for spies. + - Add: Bugout task for spies added to get spies home. 3.0906: - Fix: Some fixes to the send_ship_types API call. -- 2.51.2 From 1eae1b35eb919ee4e1d2b4080bbc17c1179475bf Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 30 Nov 2014 16:52:14 -0700 Subject: [PATCH 12/16] Finished up Bugout and fetch bugs. --- docs/Body.pod | 1 + docs/Intelligence.pod | 10 +++++++++- lib/Lacuna/DB/Result/Ships/SpyPod.pm | 1 - lib/Lacuna/DB/Result/Ships/SpyShuttle.pm | 2 +- lib/Lacuna/DB/Result/Spies.pm | 2 +- lib/Lacuna/RPC/Building/SpacePort.pm | 2 +- lib/Lacuna/Role/Ship/Arrive/Orbit.pm | 10 +++++----- lib/Lacuna/Role/Ship/Arrive/PickUpSpies.pm | 1 + 8 files changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/Body.pod b/docs/Body.pod index fb9a752b..3253f3fd 100644 --- a/docs/Body.pod +++ b/docs/Body.pod @@ -50,6 +50,7 @@ B You should probably B call this method directly, as it is a wast "happiness" : 3939, "happiness_hour" : 25, "unhappy_date" : "01 13 2014 16:11:21 +0600", # Only given if happiness is below zero + "neutral_entry" : "01 13 2014 16:11:21 +0600", # Earliest time body can enter neutral area "propaganda_boost" : 20, "food_stored" : 33329, "food_capacity" : 40000, diff --git a/docs/Intelligence.pod b/docs/Intelligence.pod index 8462bcd0..472ae8ac 100644 --- a/docs/Intelligence.pod +++ b/docs/Intelligence.pod @@ -309,6 +309,10 @@ A string containing the new assignment name. These are the possible assignments: Don't do anything. +=item Bugout + +Only visible on non-home planets. Immediately has agent go to their home base via spypod. + =item Counter Espionage. Passively defend against all attackers. @@ -335,7 +339,7 @@ Train in Theft skill =item Political Propaganda -Give happiness generation a boost. Especially effective on unhappy colonies, but hastens an agent toward retirement. +Give happiness generation a boost. Especially effective on unhappy colonies, but hastens an agent toward retirement. Only usuable on owned planets. =item Gather Resource Intelligence @@ -377,6 +381,10 @@ Kill spies. Destroy buildings. +=item Sabotage Defenses + +Destroy buildings that are used in defense. + =item Sabotage BHG Prevent enemy planet from using Black Hole Generator. diff --git a/lib/Lacuna/DB/Result/Ships/SpyPod.pm b/lib/Lacuna/DB/Result/Ships/SpyPod.pm index b192db80..b0a1c1f1 100644 --- a/lib/Lacuna/DB/Result/Ships/SpyPod.pm +++ b/lib/Lacuna/DB/Result/Ships/SpyPod.pm @@ -26,7 +26,6 @@ with "Lacuna::Role::Ship::Send::NotIsolationist"; with "Lacuna::Role::Ship::Send::LoadWithSpies"; with "Lacuna::Role::Ship::Send::IsHostile"; with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; -with "Lacuna::Role::Ship::Arrive::PickUpSpies"; with "Lacuna::Role::Ship::Arrive::CargoExchange"; with "Lacuna::Role::Ship::Arrive::Scuttle"; diff --git a/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm b/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm index 76336f0e..9bf8c5df 100644 --- a/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm +++ b/lib/Lacuna/DB/Result/Ships/SpyShuttle.pm @@ -26,8 +26,8 @@ with "Lacuna::Role::Ship::Send::NotIsolationist"; with "Lacuna::Role::Ship::Send::LoadWithSpies"; with "Lacuna::Role::Ship::Send::IsHostile"; with "Lacuna::Role::Ship::Arrive::CaptureWithSpies"; -with "Lacuna::Role::Ship::Arrive::Orbit"; with "Lacuna::Role::Ship::Arrive::PickUpSpies"; +with "Lacuna::Role::Ship::Arrive::Orbit"; with "Lacuna::Role::Ship::Arrive::CargoExchange"; no Moose; diff --git a/lib/Lacuna/DB/Result/Spies.pm b/lib/Lacuna/DB/Result/Spies.pm index 5c9d0028..cadf3049 100644 --- a/lib/Lacuna/DB/Result/Spies.pm +++ b/lib/Lacuna/DB/Result/Spies.pm @@ -279,7 +279,7 @@ sub neutral_assignments { { task =>'Bugout', recovery => 0, - skill => '*', + skill => 'intel', }, ); } diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index d69a89e4..bee81300 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -639,7 +639,7 @@ sub prepare_fetch_spies { } my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( - {type => { in => [qw(spy_pod cargo_ship smuggler_ship dory spy_shuttle barge)]}, + {type => { in => [qw(cargo_ship smuggler_ship dory spy_shuttle barge)]}, task=>'Docked', body_id => $to_body_id, berth_level => {'<=' => $max_berth } }, {order_by => 'name', rows=>100} diff --git a/lib/Lacuna/Role/Ship/Arrive/Orbit.pm b/lib/Lacuna/Role/Ship/Arrive/Orbit.pm index bff33ede..a0551661 100644 --- a/lib/Lacuna/Role/Ship/Arrive/Orbit.pm +++ b/lib/Lacuna/Role/Ship/Arrive/Orbit.pm @@ -9,13 +9,13 @@ after handle_arrival_procedures => sub { # cannot orbit stars return unless $self->foreign_body_id; - # only orbit on arrival to the foreign body - return if $self->direction eq 'in'; + # only orbit on arrival to the foreign body + return if $self->direction eq 'in'; - return if ( $self->payload->{fetch_spies} ); # Don't orbit if we're fetching - $self->orbit->update; + return if ( $self->payload->{fetch_spies} ); # Don't orbit if we're fetching + $self->orbit->update; - confess [-1]; + confess [-1]; }; 1; diff --git a/lib/Lacuna/Role/Ship/Arrive/PickUpSpies.pm b/lib/Lacuna/Role/Ship/Arrive/PickUpSpies.pm index cd010c09..eba532ba 100644 --- a/lib/Lacuna/Role/Ship/Arrive/PickUpSpies.pm +++ b/lib/Lacuna/Role/Ship/Arrive/PickUpSpies.pm @@ -62,6 +62,7 @@ after handle_arrival_procedures => sub { # object_type => ref($self), # object_id => $self->id, #})->insert; + confess [-1]; }; 1; -- 2.51.2 From 5ca2bf2338a9e18a0a5aa988bd0828fe9f073217 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 30 Nov 2014 19:08:02 -0700 Subject: [PATCH 13/16] Replace cheap plastic parts on Space Station with steel --- lib/Lacuna/DB/Result/Building/Module.pm | 10 +++++++++- var/www/public/changes.txt | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/Lacuna/DB/Result/Building/Module.pm b/lib/Lacuna/DB/Result/Building/Module.pm index 9fe9317b..60ed6030 100644 --- a/lib/Lacuna/DB/Result/Building/Module.pm +++ b/lib/Lacuna/DB/Result/Building/Module.pm @@ -31,12 +31,20 @@ sub sortable_name { around spend_efficiency => sub { my ($orig, $self, $amount) = @_; + $amount = int($amount/5) + 1; if ($self->efficiency <= $amount) { if ($self->level <= 1 && eval{$self->can_demolish}) { $self->demolish; } elsif ($self->level > 1 && eval{$self->can_downgrade}) { - $self->downgrade; + if (!Lacuna->cache->get('downgrade',$self->id)) { + $self->downgrade; + Lacuna->cache->set('downgrade',$self->id, 1, 15 * 60); + } + else { + $amount = $self->efficiency - 1; + $orig->($self, $amount); + } } else { $orig->($self, $amount); diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index c0df7045..33522bce 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -4,6 +4,7 @@ - Fix: Fetching Spies no longer will send more spies. - Add: Sabotage Defenses task added for spies. - Add: Bugout task for spies added to get spies home. + - Mod: Replace cheap plastic parts on Space Station with steel. 3.0906: - Fix: Some fixes to the send_ship_types API call. -- 2.51.2 From 4a4d44cac379abd22eee46a3742af1c102127e35 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 30 Nov 2014 19:14:51 -0700 Subject: [PATCH 14/16] Reduced Jackpot Security Ministry --- lib/Lacuna/AI/Jackpot.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Lacuna/AI/Jackpot.pm b/lib/Lacuna/AI/Jackpot.pm index 0523771c..d028cae0 100644 --- a/lib/Lacuna/AI/Jackpot.pm +++ b/lib/Lacuna/AI/Jackpot.pm @@ -46,7 +46,7 @@ sub colony_structures { return ( ['Lacuna::DB::Result::Building::Waste::Sequestration', 20], ['Lacuna::DB::Result::Building::Intelligence', 15], - ['Lacuna::DB::Result::Building::Security', 15], + ['Lacuna::DB::Result::Building::Security', 5], ['Lacuna::DB::Result::Building::Shipyard', 15], ['Lacuna::DB::Result::Building::Shipyard', 15], ['Lacuna::DB::Result::Building::Shipyard', 15], -- 2.51.2 From 6ecef84436063442c288b076268270a2f304798e Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Sun, 30 Nov 2014 20:01:07 -0700 Subject: [PATCH 15/16] Repair capitol --- lib/Lacuna/AI/Cult.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/AI/Cult.pm b/lib/Lacuna/AI/Cult.pm index c81ab5e0..825254d9 100644 --- a/lib/Lacuna/AI/Cult.pm +++ b/lib/Lacuna/AI/Cult.pm @@ -104,8 +104,10 @@ sub run_hourly_colony_updates { my ($self, $colony) = @_; $self->demolish_bleeders($colony); $self->set_defenders($colony); -# $self->pod_check($colony, 10); -# $self->repair_buildings($colony); + if ($colony->id == $colony->empire->home_planet_id) { + $self->pod_check($colony, 25); + $self->repair_buildings($colony); + } # $self->train_spies($colony); # $self->build_ships($colony); # $self->run_missions($colony); -- 2.51.2 From 4bcc25556491294586093a40f808be92b37ec642 Mon Sep 17 00:00:00 2001 From: Mark Lemming Date: Mon, 1 Dec 2014 14:31:35 -0700 Subject: [PATCH 16/16] Tweaked AI behaviours. --- lib/Lacuna/AI.pm | 24 ++++++++++++++++-------- lib/Lacuna/AI/DeLambert.pm | 2 +- lib/Lacuna/AI/Diablotin.pm | 2 +- lib/Lacuna/AI/Jackpot.pm | 2 +- lib/Lacuna/AI/Saben.pm | 2 +- lib/Lacuna/AI/Trelvestian.pm | 2 +- var/www/public/changes.txt | 1 + 7 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/Lacuna/AI.pm b/lib/Lacuna/AI.pm index bfaea618..4dfacf10 100644 --- a/lib/Lacuna/AI.pm +++ b/lib/Lacuna/AI.pm @@ -217,9 +217,11 @@ sub run_missions { while (my $spy = $infiltrated_spies->next) { next if $spy->task eq "Sabotage BHG"; if ($spy->is_available) { - if ($spy->on_body->in_neutral_area) { + if ($spy->on_body->id != $spy->from_body->id and $spy->on_body->in_neutral_area ) { # Check if spy is in neutral zone, if it is, send someone to fetch? - say " Spy ID: ".$spy->id." stuck in neutral zone..."; + say " Spy ID: ".$spy->id." escaping from neutral zone..."; + my $result = eval{$spy->assign("Bugout")}; + say " ".$result->{result}; } else { say " Spy ID: ".$spy->id." running mission..."; @@ -331,7 +333,7 @@ sub pod_check { } sub train_spies { - my ($self, $colony, $subsidise) = @_; + my ($self, $colony, $chance, $subsidise ) = @_; say 'TRAIN SPIES'; my $intelligence = $colony->get_building_of_class('Lacuna::DB::Result::Building::Intelligence'); @@ -339,13 +341,17 @@ sub train_spies { return unless defined $intelligence; my $costs = $intelligence->training_costs; - if ($subsidise) { - my $spies = Lacuna->db->resultset('Lacuna::DB::Result::Spies')->search({ + my $spies = Lacuna->db->resultset('Lacuna::DB::Result::Spies')->search({ from_body_id => $colony->id, })->count; - my $max_spies = $intelligence->level; + my $max_spies = $intelligence->level * 3; + my $room_for = $max_spies - $spies; + my $train_count = 0; + if ($subsidise) { my $deception = $colony->empire->deception_affinity * 50; - while ($spies < $max_spies * 3) { + while ($train_count < $room_for) { + $train_count++; + next if (rand(100) < $chance); # bypass everything and just create the spy my $spy = Lacuna->db->resultset('Lacuna::DB::Result::Spies')->new({ from_body_id => $colony->id, @@ -371,7 +377,9 @@ sub train_spies { else { my $can_train = 1; - while ($can_train) { + while ($can_train and $train_count < $room_for) { + $train_count++; + next if (rand(100) < $chance); my $can = eval{$intelligence->can_train_spy($costs)}; my $reason = $@; if ($can) { diff --git a/lib/Lacuna/AI/DeLambert.pm b/lib/Lacuna/AI/DeLambert.pm index 39923093..f48f443c 100644 --- a/lib/Lacuna/AI/DeLambert.pm +++ b/lib/Lacuna/AI/DeLambert.pm @@ -109,7 +109,7 @@ sub run_hourly_colony_updates { $self->set_defenders($colony); $self->pod_check($colony, 20); $self->repair_buildings($colony); - $self->train_spies($colony, 1); + $self->train_spies($colony, 100, 1); $self->build_ships_max($colony); $self->run_missions($colony); $self->buy_trade($colony); diff --git a/lib/Lacuna/AI/Diablotin.pm b/lib/Lacuna/AI/Diablotin.pm index 43d01bd5..f63e296d 100644 --- a/lib/Lacuna/AI/Diablotin.pm +++ b/lib/Lacuna/AI/Diablotin.pm @@ -152,7 +152,7 @@ sub run_hourly_colony_updates { $self->set_defenders($colony); $self->pod_check($colony, 15); $self->repair_buildings($colony); - $self->train_spies($colony); + $self->train_spies($colony, 50); $self->build_ships($colony); $self->run_missions($colony); } diff --git a/lib/Lacuna/AI/Jackpot.pm b/lib/Lacuna/AI/Jackpot.pm index d028cae0..dfa22856 100644 --- a/lib/Lacuna/AI/Jackpot.pm +++ b/lib/Lacuna/AI/Jackpot.pm @@ -113,7 +113,7 @@ sub run_hourly_colony_updates { $self->pod_check($colony, 10); $self->reset_stuff($colony); $self->repair_buildings($colony); - $self->train_spies($colony); + $self->train_spies($colony, 100); $self->build_ships($colony); $self->run_missions($colony); } diff --git a/lib/Lacuna/AI/Saben.pm b/lib/Lacuna/AI/Saben.pm index 0499b6d9..d1da5d52 100644 --- a/lib/Lacuna/AI/Saben.pm +++ b/lib/Lacuna/AI/Saben.pm @@ -139,7 +139,7 @@ sub run_hourly_colony_updates { $self->set_defenders($colony); $self->pod_check($colony, 25); $self->repair_buildings($colony); - $self->train_spies($colony,1); + $self->train_spies($colony,50, 1); $self->build_ships($colony); $self->run_missions($colony); } diff --git a/lib/Lacuna/AI/Trelvestian.pm b/lib/Lacuna/AI/Trelvestian.pm index e490feef..4e91976f 100644 --- a/lib/Lacuna/AI/Trelvestian.pm +++ b/lib/Lacuna/AI/Trelvestian.pm @@ -147,7 +147,7 @@ sub run_hourly_colony_updates { $self->set_defenders($colony); $self->pod_check($colony, 25); $self->repair_buildings($colony); - $self->train_spies($colony, 1); + $self->train_spies($colony, 100, 1); $self->build_ships($colony); $self->run_missions($colony); } diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index 33522bce..81cb9ac9 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -5,6 +5,7 @@ - Add: Sabotage Defenses task added for spies. - Add: Bugout task for spies added to get spies home. - Mod: Replace cheap plastic parts on Space Station with steel. + - Mod: Slight tweaking of AI behaviours. 3.0906: - Fix: Some fixes to the send_ship_types API call. -- 2.51.2