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/checkPlanet checkGal shipEff shipStop parseValue prettyValue calcXp findCovOpper/;
37 if ($msg =~ /(\d+)\D+(\d+)\D+(\d+)/){
41 }elsif (officer() && defined $msg){
44 $ND::server->command("notice $ND::nick usage .p X:Y:Z".(officer() ? ' or .p nick' : ''));
47 my $f = $ND::DBH->prepare(q{SELECT coords(x,y,z),ruler,planet,race,score,size,value,scorerank,sizerank,
48 valuerank, xp, xprank, alliance, relationship, nick, planet_status, hit_us, channel
49 FROM current_planet_stats WHERE (x = $1 AND y = $2 and z = $3) OR nick ILIKE $4 LIMIT 1
51 $f->execute($x,$y,$z,$nick);
52 if (my $planet = $f->fetchrow_hashref()){
53 for (keys %{$planet}){
54 $planet->{$_} = valuecolor(1,$planet->{$_});
57 if (officer() || dc()){
58 $ally = "Alliance=$planet->{alliance} ($planet->{relationship}), Nick=$planet->{nick} ($planet->{planet_status}), Channel: $planet->{channel}, Hostile Count: $planet->{hit_us},";
60 $ND::server->command("notice $ND::nick $planet->{coords} $planet->{ruler} OF $planet->{planet},$ally Race=$planet->{race}, Score=$planet->{score} ($planet->{scorerank}), Size=$planet->{size} ($planet->{sizerank}), Value=$planet->{value} ($planet->{valuerank}), XP=$planet->{xp} ($planet->{xprank})");
62 $ND::server->command("notice $ND::nick Couldn't find planet: $msg");
69 if ($msg =~ /(\d+)\D+(\d+)/){
73 $ND::server->command("notice $ND::nick syntax: .g X:Y");
75 my $f = $ND::DBH->prepare("SELECT score,size,value FROM galaxies WHERE x = ? AND y = ? and tick = (SELECT max(tick) from galaxies)");
77 while (my @row = $f->fetchrow()){
78 @row = map (valuecolor(1),@row);
79 $ND::server->command("notice $ND::nick $x:$y Score=$row[0], Size=$row[1], Value=$row[2]");
84 my ($msg,$command) = @_;
85 my ($amount,$ship,$value,$target);
86 if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)(?: (\w+))?/){
87 if ($command eq 'veff'){
88 $value = parseValue($1);
89 $value *= -1.5 if $value < 0;
92 $amount = parseValue($1);
95 $target = ($3 || '%');
97 $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)");
102 my $s= $ND::DBH->selectrow_hashref(q{
103 SELECT name,t1,t2,t3,"type",damage,metal+crystal+eonium AS cost,init,"class",guns,race
104 FROM ship_stats WHERE name ILIKE ?
108 $type = "stun" if $s->{type} eq 'Emp';
109 $type = "steal" if ($s->{type} eq 'Steal') or ($s->{type} eq 'Pod');
112 $amount = int(($value*100/$s->{cost}));
113 $feud = '(FEUD: '.prettyValue(int($amount/0.85)).') ';
115 $value = prettyValue(($amount*$s->{cost}/100));
116 my $text = prettyValue($amount)." $feud $s->{name} ($s->{init}:$value) will $type:";
117 for my $tn ('t1','t2','t3'){
118 if (defined $s->{$tn}){
119 $text .= " $ND::B${ND::C}03" . $s->{$tn} . "$ND::C$ND::B: ";
123 my $st = $ND::DBH->prepare(q{
124 SELECT name,"class","type",armor,metal+crystal+eonium AS cost,init,t1,t2,t3,eres,race
125 FROM ship_stats WHERE "class" = $1 AND ("class" ILIKE $2 OR race ILIKE $2)
127 $st->execute($s->{$tn},$target);
128 while (my $t = $st->fetchrow_hashref()){
129 my $dead = $s->{type} eq 'Emp' ? int($amount*$s->{guns}*(100-$t->{eres})/100)
130 : int($amount*$s->{damage}/$t->{armor});
131 $value = prettyValue($dead*$t->{cost}/100);
132 for my $tn2 ('t1','t2','t3'){
133 next unless (defined $t->{$tn2});
134 next unless ($t->{$tn2} eq $s->{class});
136 if($t->{init} <= $s->{init}){
137 $t->{init} = "${ND::C}04$t->{init}$ND::C";
138 }elsif($t->{init} > $s->{init}){
139 $t->{init} = "${ND::C}12$t->{init}$ND::C";
142 $t->{name} = "${ND::C}04$t->{name}$ND::C" if $t->{type} eq 'Norm' || $t->{type} eq 'Cloak';
143 $t->{name} = "${ND::C}12$t->{name}$ND::C" if $t->{type} eq 'Emp';
144 $t->{name} = "${ND::C}13$t->{name}$ND::C" if $t->{type} eq 'Steal';
145 $text .= " $ND::B$dead$ND::B $t->{name} ($t->{init}:$value),";
149 $ND::server->command("notice $ND::nick $text");
155 my ($msg,$command) = @_;
156 my ($amount,$ship,$value);
157 if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)/){
158 if ($command eq 'vstop'){
159 $value = parseValue($1);
160 $value *= -1.5 if $value < 0;
163 $amount = parseValue($1);
167 $ND::server->command("notice $ND::nick syntax: .$command amount ship");
172 my @ship = $ND::DBH->selectrow_array(q{
173 SELECT name,target,"type",armor,metal+crystal+eonium,init,"class",eres,race
174 FROM ship_stats WHERE name ILIKE ?
177 $ship[0] = "${ND::C}04$ship[0]$ND::C" if $ship[2] eq 'Norm';
178 $ship[0] = "${ND::C}12$ship[0]$ND::C" if $ship[2] eq 'Emp';
179 $ship[0] = "${ND::C}13$ship[0]$ND::C" if $ship[2] eq 'Steal';
182 $amount = int(($value*100/$ship[4]));
183 $feud = '(FEUD: '.prettyValue(int($amount/0.85)).') ';
185 $value = prettyValue(($amount*$ship[4]/100));
186 my $text = "To stop $amount $feud $ship[0] ($ship[5]:$value) you need:";
187 my $st = $ND::DBH->prepare(q{
188 SELECT name,"class","type",damage,metal+crystal+eonium,init,target,guns,race
189 FROM ship_stats WHERE "target" = ?
191 $st->execute($ship[6]);
192 while (my @stopper = $st->fetchrow()){
193 my $needed = $stopper[2] eq 'Emp' ? ceil($amount*100/(100-$ship[7])/$stopper[7]) : ceil($amount*$ship[3]/$stopper[3]);
194 $value = prettyValue($needed*$stopper[4]/100);
195 if (($stopper[1] eq $ship[1]) and ($ship[5] <= $stopper[5])){
196 $stopper[5] = "${ND::C}04$stopper[5]$ND::C";
197 }elsif(($stopper[1] eq $ship[1]) and ($ship[5] > $stopper[5])){
198 $stopper[5] = "${ND::C}12$stopper[5]$ND::C";
200 $stopper[0] = "${ND::C}04$stopper[0]$ND::C" if $stopper[2] eq 'Norm' || $stopper[2] eq 'Cloak';
201 $stopper[0] = "${ND::C}12$stopper[0]$ND::C" if $stopper[2] eq 'Emp';
202 $stopper[0] = "${ND::C}13$stopper[0]$ND::C" if $stopper[2] eq 'Steal';
203 $text .= " $ND::B$needed$ND::B $stopper[0] ($stopper[5]:$value),";
206 $ND::server->command("notice $ND::nick $text");
214 my ($x,$y,$z,$roids,$cap);
215 if(defined $msg && $msg =~ /^(\d+)\D+(\d+)\D+(\d+)(?:[^\.\d]+(\d+))?(?:[^\.\d]+(\d*\.\d+))?$/){
222 $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");
226 my ($avalue,$ascore) = $ND::DBH->selectrow_array(q{
227 SELECT value,score FROM current_planet_stats WHERE
228 id = (SELECT planet FROM users WHERE hostmask ILIKE ?);
229 }, undef, $ND::address);
230 my ($tvalue,$tscore,$tsize) = $ND::DBH->selectrow_array(q{
231 SELECT value,score,size FROM current_planet_stats WHERE
232 x = ? AND y = ? and z = ?;
234 $cap = 0.25 unless $cap;
236 $roids = int($tsize*$cap);
237 }elsif ($roids < 10){
238 $tsize = ceil($tsize*.75**($roids-1));
239 $roids = int($cap*$tsize);
242 unless (defined $avalue && defined $ascore){
243 $ND::server->command("notice $ND::nick You don't have a planet specified");
246 unless (defined $tvalue && defined $tscore){
247 $ND::server->command("notice $ND::nick Doesn't seem to be a planet at $x:$y:$z");
250 my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
251 my $score = 60 * $xp;
252 my $value = $roids*200;
253 my $totscore = prettyValue($score + $value);
254 $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,");
258 my ($stolen, $command) = @_;
260 my $tick = $ND::tick;
263 if (defined $stolen && $stolen =~ /(\d+) (\d+) (\d+)/){
267 }elsif (defined $stolen && $stolen =~ /(\d+) (\d+)/){
271 $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");
275 my ($value,$score) = $ND::DBH->selectrow_array(q{
276 SELECT value,score FROM planet_stats WHERE
277 id = (SELECT planet FROM users WHERE hostmask ILIKE ?) AND tick = ?;
278 }, undef, $ND::address,$tick);
280 $ND::server->command("notice $ND::nick No value found for tick $tick, can't find your cov opper.");
283 my $attackers = $ND::DBH->prepare(q{
284 SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE
285 ps.tick = $1 AND (2000*$2*$3/ps.value)::int = $4 ;
287 $attackers->execute($tick,$agents,$value,$stolen);
288 if ($attackers->rows == 0){
289 $ND::server->command("notice $ND::nick No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
293 while (my $attacker = $attackers->fetchrow_hashref){
294 $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
296 $ND::server->command("notice $ND::nick The planet that cov opped you is one of: $coords");