]> ruin.nu Git - NDIRC.git/blob - PA.pm
findCovOpper function implemented
[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.80)).') ';
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.80)).') ';
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 ($x,$y,$z,$roids,$cap) = @_;
199
200         my ($avalue,$ascore) = $ND::DBH->selectrow_array(q{
201                 SELECT value,score FROM current_planet_stats WHERE 
202                         id = (SELECT planet FROM users WHERE hostmask ILIKE ?);
203                 }, undef, $ND::address);
204         my ($tvalue,$tscore,$tsize) = $ND::DBH->selectrow_array(q{
205                 SELECT value,score,size FROM current_planet_stats WHERE 
206                 x = ? AND y = ? and z = ?;
207                 }, undef, $x,$y,$z);
208         $cap = 0.25 unless $cap;
209         unless($roids){
210                 $roids = int($tsize*$cap);
211         }elsif ($roids < 10){
212                 $tsize = ceil($tsize*.75**($roids-1));
213                 $roids = int($cap*$tsize);
214         }
215         $tsize -= $roids;
216         unless (defined $avalue && defined $ascore){
217                 $ND::server->command("notice $ND::nick You don't have a planet specified");
218                 return;
219         }
220         unless (defined $tvalue && defined $tscore){
221                 $ND::server->command("notice $ND::nick Doesn't seem to be a planet at $x:$y:$z");
222                 return;
223         }
224         my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
225         my $score = 60 * $xp;
226         my $value = $roids*200;
227         my $totscore = prettyValue($score + $value);
228         $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,");
229 }
230
231 sub findCovOpper {
232         my ($stolen, $command) = @_;
233
234         my $tick = $ND::tick;
235         my $agents;
236
237         if (defined $stolen && $stolen =~ /(\d+) (\d+) (\d+)/){
238                 $tick = $1;
239                 $agents = $2;
240                 $stolen = $3;
241         }elsif (defined $stolen && $stolen =~ /(\d+) (\d+)/){
242                 $agents = $1;
243                 $stolen = $2;
244         }else{
245                 $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");
246                 return;
247         }
248
249         my ($value,$score) = $ND::DBH->selectrow_array(q{
250                 SELECT value,score FROM planet_stats WHERE 
251                         id = (SELECT planet FROM users WHERE hostmask ILIKE ?) AND tick = ?;
252                 }, undef, $ND::address,$tick);
253         unless ($value){
254                 $ND::server->command("notice $ND::nick No value found for tick $tick, can't find your cov opper.");
255                 return;
256         }
257         my $attackers = $ND::DBH->prepare(q{
258                 SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE 
259                 ps.tick = $1 AND (2000*$2*$3/ps.value)::int = $4 ;
260                 });
261         $attackers->execute($tick,$agents,$value,$stolen);
262         if ($attackers->rows == 0){
263                 $ND::server->command("notice $ND::nick No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
264                 return;
265         }
266         my $coords = '';
267         while (my $attacker = $attackers->fetchrow_hashref){
268                 $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
269         }
270         $ND::server->command("notice $ND::nick The planet that cov opped you is one of: $coords");
271 }
272
273 1;