]> ruin.nu Git - NDIRC.git/blob - PA.pm
2f708ec5b738b5ba2641bf11f50b0aa307096484
[NDIRC.git] / PA.pm
1 #**************************************************************************
2 #   Copyright (C) 2006 by Michael Andreen <harvATruinDOTnu>               *
3 #                                                                         *
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.                                   *
8 #                                                                         *
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.                          *
13 #                                                                         *
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 #**************************************************************************/
19 package NDIRC::PA;
20 use strict;
21 use warnings;
22 use ND::DB;
23 use ND::Include;
24 use NDIRC::Access;
25 use NDIRC::Misc;
26 use POSIX;
27 require Exporter;
28
29 our @ISA = qw/Exporter/;
30
31 our @EXPORT = qw/checkPlanet checkGal shipEff shipStop parseValue prettyValue calcXp findCovOpper/;
32
33 sub checkPlanet {
34         my ($msg) = @_;
35
36         my ($x,$y,$z,$nick);
37         if ($msg =~ /(\d+)\D+(\d+)\D+(\d+)/){
38                 $x = $1;
39                 $y = $2;
40                 $z = $3;
41         }elsif (officer() && defined $msg){
42                 $nick = $msg;
43         }else{
44                 $ND::server->command("notice $ND::nick usage .p X:Y:Z".(officer() ? ' or .p nick' : ''));
45                 return;
46         }
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
50         });
51         $f->execute($x,$y,$z,$nick);
52         if (my $planet = $f->fetchrow_hashref()){
53                 for (keys %{$planet}){
54                         $planet->{$_} = valuecolor(1,$planet->{$_});
55                 }
56                 my $ally = "";
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},";
59                 }
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})");
61         }else{
62                 $ND::server->command("notice $ND::nick Couldn't find planet: $msg");
63         }
64 }
65 sub checkGal {
66         my ($msg) = @_;
67
68         my ($x,$y,);
69         if ($msg =~ /(\d+)\D+(\d+)/){
70                 $x = $1;
71                 $y = $2;
72         }else{
73                 $ND::server->command("notice $ND::nick syntax: .g X:Y");
74         }
75         my $f = $ND::DBH->prepare("SELECT score,size,value FROM galaxies WHERE x = ? AND y = ? and tick = (SELECT max(tick) from galaxies)");
76         $f->execute($x,$y);
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]");
80         }
81 }
82
83 sub shipEff {
84         my ($msg,$command) = @_;
85         my ($amount,$ship,$value);
86         if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)/){
87                 if ($command eq 'veff'){
88                         $value = parseValue($1);
89                         $value *= -1.5 if $value < 0;
90                         my $feud = '';
91                 }else{
92                         $amount = parseValue($1);
93                 }
94                 $ship = "\%$2\%";
95         }else{
96                 $ND::server->command("notice $ND::nick syntax: .$command amount ship");
97                 return;
98         }
99         my $feud = '';
100
101         my @ship = $ND::DBH->selectrow_array(q{
102 SELECT name,target,"type",damage,metal+crystal+eonium,init,"class",guns,race
103 FROM ship_stats WHERE name ILIKE ?
104                 }, undef, $ship);
105         if (@ship){
106                 my $type = "kill";
107                 $type = "stun" if $ship[2] eq 'Emp';
108                 $type = "steal" if ($ship[2] eq 'Steal') or ($ship[2] eq 'Pod');
109
110                 if (defined $value){
111                         $amount = int(($value*100/$ship[4]));
112                         $feud = '(FEUD: '.prettyValue(int($amount/0.85)).') ';
113                 }
114                 $value = prettyValue(($amount*$ship[4]/100));
115                 my $text = prettyValue($amount)." $feud $ship[0] ($ship[5]:$value) will $type:";
116                 my $st = $ND::DBH->prepare(q{
117                         SELECT name,"class","type",armor,metal+crystal+eonium,init,target,eres,race
118                         FROM ship_stats WHERE "class" = ?
119                         });
120                 $st->execute($ship[1]);
121                 while (my @target = $st->fetchrow()){
122                         my $dead = $ship[2] eq 'Emp' ? int($amount*$ship[7]*(100-$target[7])/100) : int($amount*$ship[3]/$target[3]);
123                         $value = prettyValue($dead*$target[4]/100);
124                         if (($target[6] eq $ship[6]) and ($target[5] <= $ship[5])){
125                                 $target[5] = "${ND::C}04$target[5]$ND::C";
126                         }elsif(($target[6] eq $ship[6]) and ($target[5] > $ship[5])){
127                                 $target[5] = "${ND::C}12$target[5]$ND::C";
128                         }
129                         $target[0] = "${ND::C}04$target[0]$ND::C" if $target[2] eq 'Norm' || $target[2] eq 'Cloak';
130                         $target[0] = "${ND::C}12$target[0]$ND::C" if $target[2] eq 'Emp';
131                         $target[0] = "${ND::C}13$target[0]$ND::C" if $target[2] eq 'Steal';
132                         $text .= " $ND::B$dead$ND::B $target[0] ($target[5]:$value),";
133                 }
134                 chop $text;
135                 $ND::server->command("notice $ND::nick $text");
136         }
137         #print $text;
138 }
139
140 sub shipStop {
141         my ($msg,$command) = @_;
142         my ($amount,$ship,$value);
143         if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)/){
144                 if ($command eq 'vstop'){
145                         $value = parseValue($1);
146                         $value *= -1.5 if $value < 0;
147                         my $feud = '';
148                 }else{
149                         $amount = parseValue($1);
150                 }
151                 $ship = "\%$2\%";
152         }else{
153                 $ND::server->command("notice $ND::nick syntax: .$command amount ship");
154                 return;
155         }
156         my $feud = '';
157
158         my @ship = $ND::DBH->selectrow_array(q{
159 SELECT name,target,"type",armor,metal+crystal+eonium,init,"class",eres,race
160 FROM ship_stats WHERE name ILIKE ?
161                 }, undef, $ship);
162         if (@ship){
163                 $ship[0] = "${ND::C}04$ship[0]$ND::C" if $ship[2] eq 'Norm';
164                 $ship[0] = "${ND::C}12$ship[0]$ND::C" if $ship[2] eq 'Emp';
165                 $ship[0] = "${ND::C}13$ship[0]$ND::C" if $ship[2] eq 'Steal';
166
167                 if (defined $value){
168                         $amount = int(($value*100/$ship[4]));
169                         $feud = '(FEUD: '.prettyValue(int($amount/0.85)).') ';
170                 }
171                 $value = prettyValue(($amount*$ship[4]/100));
172                 my $text = "To stop $amount $feud $ship[0] ($ship[5]:$value) you need:";
173                 my $st = $ND::DBH->prepare(q{
174                         SELECT name,"class","type",damage,metal+crystal+eonium,init,target,guns,race
175                         FROM ship_stats WHERE "target" = ?
176                         });
177                 $st->execute($ship[6]);
178                 while (my @stopper = $st->fetchrow()){
179                         my $needed = $stopper[2] eq 'Emp' ? ceil($amount*100/(100-$ship[7])/$stopper[7]) : ceil($amount*$ship[3]/$stopper[3]);
180                         $value = prettyValue($needed*$stopper[4]/100);
181                         if (($stopper[1] eq $ship[1]) and ($ship[5] <= $stopper[5])){
182                                 $stopper[5] = "${ND::C}04$stopper[5]$ND::C";
183                         }elsif(($stopper[1] eq $ship[1]) and ($ship[5] > $stopper[5])){
184                                 $stopper[5] = "${ND::C}12$stopper[5]$ND::C";
185                         }
186                         $stopper[0] = "${ND::C}04$stopper[0]$ND::C" if $stopper[2] eq 'Norm' || $stopper[2] eq 'Cloak';
187                         $stopper[0] = "${ND::C}12$stopper[0]$ND::C" if $stopper[2] eq 'Emp';
188                         $stopper[0] = "${ND::C}13$stopper[0]$ND::C" if $stopper[2] eq 'Steal';
189                         $text .= " $ND::B$needed$ND::B $stopper[0] ($stopper[5]:$value),";
190                 }
191                 chop $text;
192                 $ND::server->command("notice $ND::nick $text");
193         }
194         #print $text;
195 }
196
197 sub calcXp {
198         my ($msg) = @_;
199
200         my ($x,$y,$z,$roids,$cap);
201         if(defined $msg && $msg =~ /^(\d+)\D+(\d+)\D+(\d+)(?:[^\.\d]+(\d+))?(?:[^\.\d]+(\d*\.\d+))?$/){
202                 $x = $1;
203                 $y = $2;
204                 $z = $3;
205                 $roids = $4;
206                 $cap = $5;
207         }else{
208                 $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");
209                 return;
210         }
211
212         my ($avalue,$ascore) = $ND::DBH->selectrow_array(q{
213                 SELECT value,score FROM current_planet_stats WHERE 
214                         id = (SELECT planet FROM users WHERE hostmask ILIKE ?);
215                 }, undef, $ND::address);
216         my ($tvalue,$tscore,$tsize) = $ND::DBH->selectrow_array(q{
217                 SELECT value,score,size FROM current_planet_stats WHERE 
218                 x = ? AND y = ? and z = ?;
219                 }, undef, $x,$y,$z);
220         $cap = 0.25 unless $cap;
221         unless($roids){
222                 $roids = int($tsize*$cap);
223         }elsif ($roids < 10){
224                 $tsize = ceil($tsize*.75**($roids-1));
225                 $roids = int($cap*$tsize);
226         }
227         $tsize -= $roids;
228         unless (defined $avalue && defined $ascore){
229                 $ND::server->command("notice $ND::nick You don't have a planet specified");
230                 return;
231         }
232         unless (defined $tvalue && defined $tscore){
233                 $ND::server->command("notice $ND::nick Doesn't seem to be a planet at $x:$y:$z");
234                 return;
235         }
236         my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
237         my $score = 60 * $xp;
238         my $value = $roids*200;
239         my $totscore = prettyValue($score + $value);
240         $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,");
241 }
242
243 sub findCovOpper {
244         my ($stolen, $command) = @_;
245
246         my $tick = $ND::tick;
247         my $agents;
248
249         if (defined $stolen && $stolen =~ /(\d+) (\d+) (\d+)/){
250                 $tick = $1;
251                 $agents = $2;
252                 $stolen = $3;
253         }elsif (defined $stolen && $stolen =~ /(\d+) (\d+)/){
254                 $agents = $1;
255                 $stolen = $2;
256         }else{
257                 $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");
258                 return;
259         }
260
261         my ($value,$score) = $ND::DBH->selectrow_array(q{
262                 SELECT value,score FROM planet_stats WHERE 
263                         id = (SELECT planet FROM users WHERE hostmask ILIKE ?) AND tick = ?;
264                 }, undef, $ND::address,$tick);
265         unless ($value){
266                 $ND::server->command("notice $ND::nick No value found for tick $tick, can't find your cov opper.");
267                 return;
268         }
269         my $attackers = $ND::DBH->prepare(q{
270                 SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE 
271                 ps.tick = $1 AND (2000*$2*$3/ps.value)::int = $4 ;
272                 });
273         $attackers->execute($tick,$agents,$value,$stolen);
274         if ($attackers->rows == 0){
275                 $ND::server->command("notice $ND::nick No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
276                 return;
277         }
278         my $coords = '';
279         while (my $attacker = $attackers->fetchrow_hashref){
280                 $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
281         }
282         $ND::server->command("notice $ND::nick The planet that cov opped you is one of: $coords");
283 }
284
285 1;