1 #**************************************************************************
2 # Copyright (C) 2006 by Michael Andreen <harvATruinDOTnu> *
4 # This program is free software; you can redistribute it and/or modify *
5 # it under the terms of the GNU General Public License as published by *
6 # the Free Software Foundation; either version 2 of the License, or *
7 # (at your option) any later version. *
9 # This program is distributed in the hope that it will be useful, *
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 # GNU General Public License for more details. *
14 # You should have received a copy of the GNU General Public License *
15 # along with this program; if not, write to the *
16 # Free Software Foundation, Inc., *
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 #**************************************************************************/
29 our @ISA = qw/Exporter/;
31 our @EXPORT = qw/checkGal shipEff shipStop parseValue prettyValue calcXp findCovOpper tick_time/;
37 if ($msg =~ /(\d+)\D+(\d+)/){
41 $ND::server->command("notice $ND::nick syntax: .g X:Y");
43 my $f = $ND::DBH->prepare(q{SELECT score,scorerank,size,sizerank,value,valuerank,planets
44 FROM galaxies WHERE x = ? AND y = ? AND tick = (SELECT max(tick) from galaxies)
47 while (my @row = $f->fetchrow()){
48 @row = map (valuecolor(1),@row);
49 $ND::server->command("notice $ND::nick $x:$y Score=$row[0] ($row[1]), Size=$row[2] ($row[3]), Value=$row[4] ($row[5]), Planets=$row[6]");
54 my ($msg,$command) = @_;
55 my ($amount,$ship,$value,$target);
57 $eff = 0 if $command =~ /stop/;
58 if(defined $msg && $msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)(?: (\w+))?/){
60 $target = ($3 || '%');
62 if ($command =~ /^v.+$/){
63 $value = parseValue($am);
64 $value *= -1.5 if $value < 0;
67 $amount = parseValue($am);
70 $ND::server->command("notice $ND::nick syntax: $command amount ship [race|class] | Amount can use SI prefixes like k and M. Race or class is an optional argument, using the short form (i.e. cath or Fi)");
75 my $s= $ND::DBH->selectrow_hashref(q{
76 SELECT name,t1,t2,t3,"type",damage
77 ,metal+crystal+eonium AS cost
78 ,init,"class",guns,race,eres,armor
79 FROM ship_stats WHERE name ILIKE ?
83 $amount = int(($value*100/$s->{cost}));
84 $feud = '(FEUD: '.prettyValue(int($amount/0.86)).') ';
86 $value = prettyValue(($amount*$s->{cost}/100));
87 my $name = shipColor($s->{name},$s->{type});
88 my $text = prettyValue($amount)." $name ($s->{init}:$value) :";
89 for my $tn ('t1','t2','t3'){
90 next if ($eff && not defined $s->{$tn});
91 $text .= " $ND::B${ND::C}03" . ($eff ? $s->{$tn} : $tn) . "$ND::O: ";
93 SELECT name,"class","type",armor
94 ,metal+crystal+eonium AS cost
95 ,init,t1,t2,t3,eres,race
100 $st = $ND::DBH->prepare($st . q{
102 AND ("class" ILIKE $2 OR race ILIKE $2)
104 $st->execute($s->{$tn},$target);
106 $st = $ND::DBH->prepare($st . qq{
108 AND ("class" ILIKE \$2 OR race ILIKE \$2)
110 $st->execute($s->{class},$target);
112 while (my $t = $st->fetchrow_hashref()){
113 my $number = calcEff($s,$t,$amount,$eff);
115 $number *= 0.60 if $tn eq 't2';
116 $number *= 0.30 if $tn eq 't3';
118 $number /= 0.60 if $tn eq 't2';
119 $number /= 0.30 if $tn eq 't3';
121 $number = int($number);
122 $value = prettyValue($number*$t->{cost}/100);
123 my $name = shipColor($t->{name},$t->{type});
124 $text .= " $ND::B$number$ND::O $name ($t->{init}:$value),";
128 $ND::server->command("notice $ND::nick $text");
133 my ($s,$t,$amount,$eff) = @_;
137 $number = $s->{type} eq 'Emp' ?
138 ($amount*$s->{guns}*(100-$t->{eres})/100)
139 : ($amount*$s->{damage}/$t->{armor});
141 $number = $t->{type} eq 'Emp' ?
142 ($amount*100/(100 - $s->{eres})/$t->{guns})
143 : ($amount*$s->{armor}/$t->{damage});
146 for my $tn ('t1','t2','t3'){
147 my ($s1,$t1) = $eff ? ($s,$t) : ($t,$s);
148 next unless (defined $t1->{$tn});
149 next unless ($t1->{$tn} eq $s1->{class});
151 if($t1->{init} <= $s1->{init}){
152 $t->{init} = "${ND::C}04$t->{init}$ND::O";
154 $t->{init} = "${ND::C}12$t->{init}$ND::O";
161 my ($string,$type) = @_;
163 $c = 12 if $type eq 'Emp';
164 $c = 13 if $type eq 'Steal';
165 return "$ND::C$c$string$ND::O";
171 my ($x,$y,$z,$roids,$cap);
172 if(defined $msg && $msg =~ /^(\d+)\D+(\d+)\D+(\d+)(?:[^\.\d]+(\d+))?(?:[^\.\d]+(\d*\.\d+))?$/){
179 $ND::server->command("notice $ND::nick syntax: .xp X:Y:Z [roids] [cap] | if roids < 10 then it's taken as the wave, cap is a floating point number, defaults to 0.25");
183 my ($avalue,$ascore) = $ND::DBH->selectrow_array(q{
184 SELECT value,score FROM current_planet_stats WHERE
185 id = (SELECT planet FROM users WHERE hostmask ILIKE ?);
186 }, undef, $ND::address);
187 my ($tvalue,$tscore,$tsize) = $ND::DBH->selectrow_array(q{
188 SELECT value,score,size FROM current_planet_stats WHERE
189 x = ? AND y = ? and z = ?;
191 $cap = 0.25 unless $cap;
193 $roids = int($tsize*$cap);
194 }elsif ($roids < 10){
195 $tsize = ceil($tsize*.75**($roids-1));
196 $roids = int($cap*$tsize);
199 unless (defined $avalue && defined $ascore){
200 $ND::server->command("notice $ND::nick You don't have a planet specified");
203 unless (defined $tvalue && defined $tscore){
204 $ND::server->command("notice $ND::nick Doesn't seem to be a planet at $x:$y:$z");
207 my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
208 my $score = 60 * $xp;
209 my $value = $roids*200;
210 my $totscore = prettyValue($score + $value);
211 $ND::server->command("notice $ND::nick You will gain $ND::B$xp$ND::B XP, $ND::B$score$ND::B score, if you steal $roids roids ($ND::B$value$ND::B value), from $ND::B$x:$y:$z$ND::B, who will have $ND::B$tsize$ND::B roids left, total score gain will be: $ND::B$totscore$ND::B in total,");
215 my ($stolen, $command) = @_;
217 my $tick = $ND::tick;
220 if (defined $stolen && $stolen =~ /(\d+) (\d+) (\d+)/){
224 }elsif (defined $stolen && $stolen =~ /(\d+) (\d+)/){
228 $ND::server->command("notice $ND::nick syntax: .$command [tick] agents stolen | tick can be omitted if you're doing this the same tick you got cov opped, if you have different amount of your resources stolen, specify the highest amount. Only works if less than 10% of your resources and < 10,000*agents were stolen");
232 my ($value,$score) = $ND::DBH->selectrow_array(q{
233 SELECT value,score FROM planet_stats WHERE
234 id = (SELECT planet FROM users WHERE hostmask ILIKE ?) AND tick = ?;
235 }, undef, $ND::address,$tick);
237 $ND::server->command("notice $ND::nick No value found for tick $tick, can't find your cov opper.");
240 my $attackers = $ND::DBH->prepare(q{
241 SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE
242 ps.tick = $1 AND (2000.0*$2*$3/ps.value)::int = $4 ;
244 $attackers->execute($tick,$agents,$value,$stolen);
245 if ($attackers->rows == 0){
246 $ND::server->command("notice $ND::nick No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
250 while (my $attacker = $attackers->fetchrow_hashref){
251 $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
253 $ND::server->command("notice $ND::nick The planet that cov opped you is one of: $coords");
257 my ($msg,$command) = @_;
258 my $tick = $ND::tick;
259 my $timezone = 'GMT';
260 if ($msg =~ /^(\d+)(?: (\S+))?/){
261 $tick = $1 if defined $1;
262 $timezone = $2 if defined $2;
263 }elsif ($msg =~ /^(\S+)/){
266 $ND::server->command("notice $ND::nick syntax: .time [tick] [timezone] | Gives the time at the specied tick. Assumes GMT if no timezone is given and current tick if no tick is given.");
269 my $query = $ND::DBH->prepare(q{SELECT date_trunc('seconds',now() + (($1 - tick()) || ' hr')::interval) AT TIME ZONE $2});
270 $query->execute($tick,$timezone);
271 my $time = $query->fetchrow_array;
272 $ND::server->command("notice $ND::nick Time at tick $ND::B$tick$ND::O, timezone $ND::B$timezone$ND::O: $ND::B$time$ND::O");