]> ruin.nu Git - NDIRC.git/blobdiff - PA.pm
Bugfix, use we need logical, not bitwise, or
[NDIRC.git] / PA.pm
diff --git a/PA.pm b/PA.pm
index e6a2e330a85eaee3c6cbf6ccf68e29f684061c99..7a4a4b81e1c98c91971e6f746d23b22a895fa874 100644 (file)
--- a/PA.pm
+++ b/PA.pm
@@ -28,21 +28,21 @@ require Exporter;
 
 our @ISA = qw/Exporter/;
 
-our @EXPORT = qw/checkPlanet checkGal shipEff shipStop parseValue prettyValue calcXp/;
+our @EXPORT = qw/checkPlanet checkGal shipEff shipStop parseValue prettyValue calcXp findCovOpper/;
 
 sub checkPlanet {
        my ($msg) = @_;
 
-       DB();
        my ($x,$y,$z,$nick);
        if ($msg =~ /(\d+)\D+(\d+)\D+(\d+)/){
                $x = $1;
                $y = $2;
                $z = $3;
-       }elsif (officer()){
+       }elsif ((officer() || ia() || intel()) && defined $msg){
                $nick = $msg;
        }else{
-               $ND::server->command("notice $ND::target usage .p X:Y:Z".(officer() ? ' or .p nick' : ''));
+               $ND::server->command("notice $ND::nick usage .p X:Y:Z".(officer() || ia() ? ' or .p nick' : ''));
+               return;
        }
        my $f = $ND::DBH->prepare(q{SELECT coords(x,y,z),ruler,planet,race,score,size,value,scorerank,sizerank,
                valuerank, xp, xprank, alliance, relationship, nick, planet_status, hit_us, channel
@@ -54,143 +54,163 @@ sub checkPlanet {
                        $planet->{$_} = valuecolor(1,$planet->{$_});
                }
                my $ally = "";
-               if (officer() || dc()){
+               if (officer() || ia() || dc() || intel()){
                        $ally = "Alliance=$planet->{alliance} ($planet->{relationship}), Nick=$planet->{nick} ($planet->{planet_status}), Channel: $planet->{channel}, Hostile Count: $planet->{hit_us},";
                }
-               $ND::server->command("notice $ND::target $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})");
+               $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})");
        }else{
-               $ND::server->command("notice $ND::target Couldn't find planet: $msg");
+               $ND::server->command("notice $ND::nick Couldn't find planet: $msg");
        }
 }
 sub checkGal {
-       my ($x,$y) = @_;
-       DB();
-       my $f = $ND::DBH->prepare("SELECT name,score,size,value FROM galaxies WHERE x = ? AND y = ? and tick = (SELECT max(tick) from galaxies)");
+       my ($msg) = @_;
+
+       my ($x,$y,);
+       if ($msg =~ /(\d+)\D+(\d+)/){
+               $x = $1;
+               $y = $2;
+       }else{
+               $ND::server->command("notice $ND::nick syntax: .g X:Y");
+       }
+       my $f = $ND::DBH->prepare(q{SELECT score,scorerank,size,sizerank,value,valuerank,planets
+               FROM galaxies WHERE x = ? AND y = ? AND tick = (SELECT max(tick) from galaxies)
+       });
        $f->execute($x,$y);
        while (my @row = $f->fetchrow()){
                @row = map (valuecolor(1),@row);
-               $ND::server->command("notice $ND::target $x:$y $row[0], Score=$row[1], Size=$row[2], Value=$row[3]");
+               $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]");
        }
 }
 
 sub shipEff {
-       my ($msg,$value) = @_;
-       my ($amount,$ship);
-       if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)$/){
-               if (defined $value){
-                       $value = parseValue($1);
+       my ($msg,$command) = @_;
+       my ($amount,$ship,$value,$target);
+       my $eff = 1;
+       $eff = 0 if $command =~ /stop/;
+       if(defined $msg && $msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)(?: (\w+))?/){
+               $ship = "\%$2\%";
+               $target = ($3 || '%');
+               my $am = $1;
+               if ($command =~ /^v.+$/){
+                       $value = parseValue($am);
                        $value *= -1.5 if $value < 0;
                        my $feud = '';
                }else{
-                       $amount = parseValue($1);
+                       $amount = parseValue($am);
                }
-               $ship = "\%$2\%";
        }else{
-               my $command = (defined $value ? "veff" : "eff");
-               $ND::server->command("notice $ND::nick syntax: .$command amount ship");
+               $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)");
                return;
        }
        my $feud = '';
 
-       my @ship = $ND::DBH->selectrow_array(q{
-SELECT name,target,"type",damage,metal+crystal+eonium,init,"class",guns,race
-FROM ship_stats WHERE name ILIKE ?
+       my $s= $ND::DBH->selectrow_hashref(q{
+               SELECT name,t1,t2,t3,"type",damage
+                       ,metal+crystal+eonium AS cost
+                       ,init,"class",guns,race,eres,armor
+               FROM ship_stats WHERE name ILIKE ?
                }, undef, $ship);
-       if (@ship){
-               my $type = "kill";
-               $type = "stun" if $ship[2] eq 'Emp';
-               $type = "steal" if ($ship[2] eq 'Steal') or ($ship[2] eq 'Pod');
-
+       if ($s){
                if (defined $value){
-                       $amount = int(($value*100/$ship[4]));
-                       $feud = '(FEUD: '.prettyValue(int($amount/0.80)).') ';
+                       $amount = int(($value*100/$s->{cost}));
+                       $feud = '(FEUD: '.prettyValue(int($amount/0.86)).') ';
                }
-               $value = prettyValue(($amount*$ship[4]/100));
-               my $text = prettyValue($amount)." $feud $ship[0] ($ship[5]:$value) will $type:";
-               my $st = $ND::DBH->prepare(q{
-                       SELECT name,"class","type",armor,metal+crystal+eonium,init,target,eres,race
-                       FROM ship_stats WHERE "class" = ?
-                       });
-               $st->execute($ship[1]);
-               while (my @target = $st->fetchrow()){
-                       my $dead = $ship[2] eq 'Emp' ? int($amount*$ship[7]*(100-$target[7])/100) : int($amount*$ship[3]/$target[3]);
-                       $value = prettyValue($dead*$target[4]/100);
-                       if (($target[6] eq $ship[6]) and ($target[5] <= $ship[5])){
-                               $target[5] = "${ND::C}04$target[5]$ND::C";
-                       }elsif(($target[6] eq $ship[6]) and ($target[5] > $ship[5])){
-                               $target[5] = "${ND::C}12$target[5]$ND::C";
+               $value = prettyValue(($amount*$s->{cost}/100));
+               my $name = shipColor($s->{name},$s->{type});
+               my $text = prettyValue($amount)." $name ($s->{init}:$value) :";
+               for my $tn ('t1','t2','t3'){
+                       next if ($eff && not defined $s->{$tn});
+                       $text .= " $ND::B${ND::C}03" . ($eff ? $s->{$tn} : $tn) . "$ND::O: ";
+                       my $st = q{
+                               SELECT name,"class","type",armor
+                                       ,metal+crystal+eonium AS cost
+                                       ,init,t1,t2,t3,eres,race
+                                       ,damage,guns
+                               FROM ship_stats 
+                               };
+                       if ($eff){
+                               $st = $ND::DBH->prepare($st . q{
+                               WHERE "class" = $1
+                                       AND ("class" ILIKE $2 OR race ILIKE $2)
+                               });
+                               $st->execute($s->{$tn},$target);
+                       }else{
+                               $st = $ND::DBH->prepare($st . qq{
+                               WHERE $tn = \$1
+                                       AND ("class" ILIKE \$2 OR race ILIKE \$2)
+                               });
+                               $st->execute($s->{class},$target);
                        }
-                       $target[0] = "${ND::C}04$target[0]$ND::C" if $target[2] eq 'Norm' || $target[2] eq 'Cloak';
-                       $target[0] = "${ND::C}12$target[0]$ND::C" if $target[2] eq 'Emp';
-                       $target[0] = "${ND::C}13$target[0]$ND::C" if $target[2] eq 'Steal';
-                       $text .= " $ND::B$dead$ND::B $target[0] ($target[5]:$value),";
+                       while (my $t = $st->fetchrow_hashref()){
+                               my $number = calcEff($s,$t,$amount,$eff);
+                               if ($eff){
+                                       $number *= 0.60 if $tn eq 't2';
+                                       $number *= 0.30 if $tn eq 't3';
+                               }else{
+                                       $number /= 0.60 if $tn eq 't2';
+                                       $number /= 0.30 if $tn eq 't3';
+                               }
+                               $number = int($number);
+                               $value = prettyValue($number*$t->{cost}/100);
+                               my $name = shipColor($t->{name},$t->{type});
+                               $text .= " $ND::B$number$ND::O $name ($t->{init}:$value),";
+                       }
+                       chop $text;
                }
-               chop $text;
-               $ND::server->command("notice $ND::target $text");
+               $ND::server->command("notice $ND::nick $text");
        }
-       #print $text;
 }
 
-sub shipStop {
-       my ($msg,$value) = @_;
-       my ($amount,$ship);
-       if($msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)$/){
-               if (defined $value){
-                       $value = parseValue($1);
-                       $value *= -1.5 if $value < 0;
-                       my $feud = '';
-               }else{
-                       $amount = parseValue($1);
-               }
-               $ship = "\%$2\%";
+sub calcEff {
+       my ($s,$t,$amount,$eff) = @_;
+
+       my $number = 0;
+       if ($eff){
+               $number = $s->{type} eq 'Emp' ?
+                       ($amount*$s->{guns}*(100-$t->{eres})/100)
+                       : ($amount*$s->{damage}/$t->{armor});
        }else{
-               my $command = (defined $value ? "vstop" : "stop");
-               $ND::server->command("notice $ND::nick syntax: .$command amount ship");
-               return;
+               $number = $t->{type} eq 'Emp' ?
+                       ($amount*100/(100 - $s->{eres})/$t->{guns})
+                       : ($amount*$s->{armor}/$t->{damage});
        }
-       my $feud = '';
 
-       my @ship = $ND::DBH->selectrow_array(q{
-SELECT name,target,"type",armor,metal+crystal+eonium,init,"class",eres,race
-FROM ship_stats WHERE name ILIKE ?
-               }, undef, $ship);
-       if (@ship){
-               $ship[0] = "${ND::C}04$ship[0]$ND::C" if $ship[2] eq 'Norm';
-               $ship[0] = "${ND::C}12$ship[0]$ND::C" if $ship[2] eq 'Emp';
-               $ship[0] = "${ND::C}13$ship[0]$ND::C" if $ship[2] eq 'Steal';
+       for my $tn ('t1','t2','t3'){
+               my ($s1,$t1) = $eff ? ($s,$t) : ($t,$s);
+               next unless (defined $t1->{$tn});
+               next unless ($t1->{$tn} eq $s1->{class});
 
-               if (defined $value){
-                       $amount = int(($value*100/$ship[4]));
-                       $feud = '(FEUD: '.prettyValue(int($amount/0.80)).') ';
-               }
-               $value = prettyValue(($amount*$ship[4]/100));
-               my $text = "To stop $amount $feud $ship[0] ($ship[5]:$value) you need:";
-               my $st = $ND::DBH->prepare(q{
-                       SELECT name,"class","type",damage,metal+crystal+eonium,init,target,guns,race
-                       FROM ship_stats WHERE "target" = ?
-                       });
-               $st->execute($ship[6]);
-               while (my @stopper = $st->fetchrow()){
-                       my $needed = $stopper[2] eq 'Emp' ? ceil($amount*100/(100-$ship[7])/$stopper[7]) : ceil($amount*$ship[3]/$stopper[3]);
-                       $value = prettyValue($needed*$stopper[4]/100);
-                       if (($stopper[1] eq $ship[1]) and ($ship[5] <= $stopper[5])){
-                               $stopper[5] = "${ND::C}04$stopper[5]$ND::C";
-                       }elsif(($stopper[1] eq $ship[1]) and ($ship[5] > $stopper[5])){
-                               $stopper[5] = "${ND::C}12$stopper[5]$ND::C";
-                       }
-                       $stopper[0] = "${ND::C}04$stopper[0]$ND::C" if $stopper[2] eq 'Norm' || $stopper[2] eq 'Cloak';
-                       $stopper[0] = "${ND::C}12$stopper[0]$ND::C" if $stopper[2] eq 'Emp';
-                       $stopper[0] = "${ND::C}13$stopper[0]$ND::C" if $stopper[2] eq 'Steal';
-                       $text .= " $ND::B$needed$ND::B $stopper[0] ($stopper[5]:$value),";
+               if($t1->{init} <= $s1->{init}){
+                       $t->{init} = "${ND::C}04$t->{init}$ND::O";
+               }else{
+                       $t->{init} = "${ND::C}12$t->{init}$ND::O";
                }
-               chop $text;
-               $ND::server->command("notice $ND::target $text");
        }
-       #print $text;
+       return $number;
+}
+
+sub shipColor {
+       my ($string,$type) = @_;
+       my $c = 04;
+       $c = 12 if $type eq 'Emp';
+       $c = 13 if $type eq 'Steal';
+       return "$ND::C$c$string$ND::O";
 }
 
 sub calcXp {
-       my ($x,$y,$z,$roids,$cap) = @_;
+       my ($msg) = @_;
+
+       my ($x,$y,$z,$roids,$cap);
+       if(defined $msg && $msg =~ /^(\d+)\D+(\d+)\D+(\d+)(?:[^\.\d]+(\d+))?(?:[^\.\d]+(\d*\.\d+))?$/){
+               $x = $1;
+               $y = $2;
+               $z = $3;
+               $roids = $4;
+               $cap = $5;
+       }else{
+               $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");
+               return;
+       }
 
        my ($avalue,$ascore) = $ND::DBH->selectrow_array(q{
                SELECT value,score FROM current_planet_stats WHERE 
@@ -209,44 +229,60 @@ sub calcXp {
        }
        $tsize -= $roids;
        unless (defined $avalue && defined $ascore){
-               $ND::server->command("notice $ND::target You don't have a planet specified");
+               $ND::server->command("notice $ND::nick You don't have a planet specified");
                return;
        }
        unless (defined $tvalue && defined $tscore){
-               $ND::server->command("notice $ND::target Doesn't seem to be a planet at $x:$y:$z");
+               $ND::server->command("notice $ND::nick Doesn't seem to be a planet at $x:$y:$z");
                return;
        }
        my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
        my $score = 60 * $xp;
        my $value = $roids*200;
        my $totscore = prettyValue($score + $value);
-       $ND::server->command("notice $ND::target 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,");
+       $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,");
 }
 
 sub findCovOpper {
-       my ($stolen) = @_;
+       my ($stolen, $command) = @_;
 
        my $tick = $ND::tick;
        my $agents;
 
-       if ($stolen =~ /(\d+) (\d+) (\d+)/){
+       if (defined $stolen && $stolen =~ /(\d+) (\d+) (\d+)/){
                $tick = $1;
                $agents = $2;
                $stolen = $3;
-       }elsif ($stolen =~ /(\d+) (\d+)/){
-               $tick = $1;
-               $stolen = $3;
+       }elsif (defined $stolen && $stolen =~ /(\d+) (\d+)/){
+               $agents = $1;
+               $stolen = $2;
+       }else{
+               $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");
+               return;
        }
 
        my ($value,$score) = $ND::DBH->selectrow_array(q{
                SELECT value,score FROM planet_stats WHERE 
                        id = (SELECT planet FROM users WHERE hostmask ILIKE ?) AND tick = ?;
                }, undef, $ND::address,$tick);
-       my ($coords) = $ND::DBH->selectrow_array(q{
-               SELECT coords(p.x,p.y,p.z) FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE 
-               ps.tick = ? AND (2000*?*?/ps.value)::int = $stolen ;
-               }, undef, $tick,$agents,$value,$stolen);
-       $ND::server->command("notice $ND::target The planet that cov opped you is: $coords");
+       unless ($value){
+               $ND::server->command("notice $ND::nick No value found for tick $tick, can't find your cov opper.");
+               return;
+       }
+       my $attackers = $ND::DBH->prepare(q{
+               SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p JOIN planet_stats ps using (id) WHERE 
+               ps.tick = $1 AND (2000.0*$2*$3/ps.value)::int = $4 ;
+               });
+       $attackers->execute($tick,$agents,$value,$stolen);
+       if ($attackers->rows == 0){
+               $ND::server->command("notice $ND::nick No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
+               return;
+       }
+       my $coords = '';
+       while (my $attacker = $attackers->fetchrow_hashref){
+               $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
+       }
+       $ND::server->command("notice $ND::nick The planet that cov opped you is one of: $coords");
 }
 
 1;