1 #**************************************************************************
2 # Copyright (C) 2008 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 #**************************************************************************/
20 package NDIRC::Commands::PA;
27 use MooseX::MethodAttributes;
35 : Help(Lists bcalc and stats info)
37 my ($self, $c, $msg) = @_;
38 $c->reply("http://game.planetarion.com/bcalc.pl http://game.planetarion.com/manual.php?page=stats");
42 : Help(usage: .p X:Y:Z | or .p nick with high enough access)
44 my ($self, $c, $msg) = @_;
47 if ($msg =~ /(\d+)\D+(\d+)\D+(\d+)/){
51 }elsif ($msg && $c->check_user_roles(qw/irc_p_nick/)){
57 my $f = $c->model->prepare(q{
58 WITH p AS (SELECT pid,coords(x,y,z),ruler,planet,race,score,size,value,scorerank,sizerank,
59 valuerank, xp, xprank, alliance, relationship, nick, planet_status, hit_us, channel
60 FROM current_planet_stats
61 WHERE (x = $1 AND y = $2 and z = $3) OR nick ILIKE $4 LIMIT 1
62 ), t AS (SELECT tag,bool_or(uid = $5) AS own,max(time) AS time
64 WHERE pid = (SELECT pid FROM p)
68 ), tags AS (SELECT array_to_string(array_agg(tag || CASE WHEN own THEN '*' ELSE '' END),' ') AS tags
71 SELECT * FROM p, tags;
73 $f->execute($x,$y,$z,$nick,$c->uid,$c->check_user_roles(qw/irc_p_intel/) // 0);
74 if (my $planet = $f->fetchrow_hashref()){
75 for (keys %{$planet}){
76 $planet->{$_} = valuecolor(1,$planet->{$_});
79 if ($c->check_user_roles(qw/irc_p_intel/)){
80 $ally = "Alliance=$planet->{alliance} ($planet->{relationship}), Nick=$planet->{nick} ($planet->{planet_status}), Channel: $planet->{channel}, Hostile Count: $planet->{hit_us},";
82 $c->reply("$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}) TAGS: $planet->{tags}");
84 $c->reply("Couldn't find planet: $msg");
91 my ($self, $c, $msg) = @_;
93 my ($x,$y) = ($msg =~ /(\d+)\D+(\d+)/) or die 'ARGS';
96 my $f = $dbh->prepare(q{
97 SELECT score,scorerank,size,sizerank,value,valuerank,planets
98 FROM galaxies WHERE x = ? AND y = ? AND tick = (SELECT max(tick) from galaxies)
101 my @row = $f->fetchrow;
103 $c->reply("No planet at $x:$y");
107 if ($c->check_user_roles(qw/irc_g_intel/)) {
108 my $query = $dbh->prepare(q{
109 SELECT z,COALESCE(nick,'?') AS nick,COALESCE(alliance,'?') AS alliance
110 FROM current_planet_stats
111 WHERE x = $1 AND y = $2 ORDER BY z
113 $query->execute($x,$y);
114 while(my $p = $query->fetchrow_hashref){
115 push @planets, "$p->{z} [$p->{nick}/$p->{alliance}]";
118 @row = map (valuecolor(1),@row);
119 $c->reply("$x:$y Score=$row[0] ($row[1]), Size=$row[2] ($row[3]), Value=$row[4] ($row[5]), Planets=$row[6] - "
120 . join " ", @planets);
124 : Help(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.)
126 my ($self, $c, $msg) = @_;
127 my ($tick,$timezone) = $msg =~ /^(\d+)?\s*(\S+)?$/ or die 'ARGS';
130 $tick //= $c->model->selectrow_array(q{SELECT tick()});
132 my $query = $c->model->prepare(q{
133 SELECT date_trunc('seconds',now() + (($1 - tick()) || ' hr')::interval) AT TIME ZONE $2
135 $query->execute($tick,$timezone);
136 my $time = $query->fetchrow_array;
137 $c->reply("Time at tick <b>$tick</b>, timezone <b>$timezone</b>: <b>$time</b>");
140 when(/time zone "(.+?)" not recognized/){
141 $c->reply("<c04>$1</c> is not a valid timezone.");
148 : Help(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 cap according to your value)
150 my ($self, $c, $msg) = @_;
152 my ($x,$y,$z,$roids,$cap) = $msg =~ /^(\d+)\D+(\d+)\D+(\d+)(?:[^\.\d]+(\d+))?(?:[^\.\d]+(\d*\.\d+))?$/
155 my ($avalue,$ascore) = $c->model->selectrow_array(q{
156 SELECT value,score FROM current_planet_stats
157 WHERE pid = (SELECT pid FROM users WHERE uid = ?)
159 my ($tvalue,$tscore,$tsize) = $c->model->selectrow_array(q{
160 SELECT value,score,size FROM current_planet_stats
161 WHERE x = ? AND y = ? and z = ?
163 $cap //= min(0.25,0.25 * pow($tvalue/$avalue , 0.5));
165 $roids = int($tsize*$cap);
166 }elsif ($roids < 10){
167 $tsize = int($tsize*.75**($roids-1));
168 $roids = int($cap*$tsize);
171 unless (defined $avalue && defined $ascore){
172 $c->reply("You don't have a planet specified");
175 unless (defined $tvalue && defined $tscore){
176 $c->reply("No planet found at $x:$y:$z");
179 my $xp = pa_xp($roids,$ascore,$avalue,$tscore,$tvalue);
180 my $score = 60 * $xp;
181 my $value = $roids*200;
182 my $totscore = prettyValue($score + $value);
183 $cap = sprintf "%.1f", $cap*100;
184 $c->reply("You will gain <b>$xp</b> XP, <b>$score</b> score, if you steal <b>$roids</b> roids (<b>$value</b> value, <b>$cap%</b> cap), from <b>$x:$y:$z</b>, who will have <b>$tsize</b> roids left, total score gain will be: <b>$totscore</b> in total,");
188 : Help(syntax: .fco agents stolen [tick] | 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)
190 my ($self, $c, $msg) = @_;
192 my ($agents,$stolen,$tick) = $msg =~ /^(\d+)\s+(\d+)\s*(\d+)?$/ or die 'ARGS';
194 $tick //= $c->model->selectrow_array(q{SELECT tick()});
196 my ($value,$score) = $c->model->selectrow_array(q{
197 SELECT value,score FROM planet_stats WHERE tick = $2 AND
198 pid = (SELECT pid FROM users WHERE uid = $1)
199 }, undef, $c->uid,$tick);
201 $c->reply("You don't have a planet registered.");
204 my $attackers = $c->model->prepare(q{
205 SELECT coords(p.x,p.y,p.z), ruler, planet FROM current_planet_stats p
206 JOIN planet_stats ps using (pid)
207 WHERE ps.tick = $1 AND trunc(2000.0*$2*$3/ps.value)::int = $4
209 $attackers->execute($tick,$agents,$value,$stolen);
210 if ($attackers->rows == 0){
211 $c->reply("No cov opper found, did you specify the right tick, and was the stolen amount not capped?");
214 while (my $attacker = $attackers->fetchrow_hashref){
215 $coords .= " ($attacker->{coords} : $attacker->{ruler} OF $attacker->{planet})";
217 $c->reply("The planet that cov opped you is one of: $coords");
222 : Alias(qw/veff stop vstop/)
223 : Help( syntax: .eff 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) | veff, stop and vstop are variations of this command)
225 my ($self, $c, $msg) = @_;
226 my ($amount,$ship,$target) = $msg =~ /^(-?\d+(?:\.\d+)?[hkMG]?) (\w+)(?: (\w+))?/
229 my $eff = ($self->name =~ /(eff)/);
233 if ($self->name =~ /^v.+$/){
234 $value = parseValue($amount);
235 $value *= -1.5 if $value < 0;
237 $amount = parseValue($amount);
242 my $s= $c->model->selectrow_hashref(q{
243 SELECT name,t1,t2,t3,"type",damage
244 ,metal+crystal+eonium AS cost
245 ,init,"class",guns,race,eres,armor
246 FROM ship_stats WHERE name ILIKE ?
250 $amount = int(($value*100/$s->{cost}));
251 $feud = '(FEUD: '.prettyValue(int($amount/0.86)).') ';
253 $value = prettyValue(($amount*$s->{cost}/100));
254 my $name = shipColor($s->{name},$s->{type});
255 my $text = prettyValue($amount)." $name ($s->{init}:$value) :";
256 for my $tn ('t1','t2','t3'){
257 next if ($eff && not defined $s->{$tn});
258 $text .= " <b><c03>" . ($eff ? $s->{$tn} : $tn) . "</c></b>: ";
260 SELECT name,"class","type",armor
261 ,metal+crystal+eonium AS cost
262 ,init,t1,t2,t3,eres,race
267 $st = $c->model->prepare($st . q{
269 AND ("class" ILIKE $2 OR race ILIKE $2)
271 $st->execute($s->{$tn},$target);
273 $st = $c->model->prepare($st . qq{
275 AND ("class" ILIKE \$2 OR race ILIKE \$2)
277 $st->execute($s->{class},$target);
279 while (my $t = $st->fetchrow_hashref()){
280 my $number = calcEff($s,$t,$amount,$eff);
282 $number *= 0.60 if $tn eq 't2';
283 $number *= 0.30 if $tn eq 't3';
285 $number /= 0.60 if $tn eq 't2';
286 $number /= 0.30 if $tn eq 't3';
288 $number = int($number);
289 $value = prettyValue($number*$t->{cost}/100);
290 my $name = shipColor($t->{name},$t->{type});
291 $text .= " <b>$number</b> $name ($t->{init}:$value),";
300 my ($s,$t,$amount,$eff) = @_;
304 $number = $s->{type} eq 'Emp' ?
305 ($amount*$s->{guns}*(100-$t->{eres})/100)
306 : ($amount*$s->{damage}/$t->{armor});
308 $number = $t->{type} eq 'Emp' ?
309 ($amount*100/(100 - $s->{eres})/$t->{guns})
310 : ($amount*$s->{armor}/$t->{damage});
313 for my $tn ('t1','t2','t3'){
314 my ($s1,$t1) = $eff ? ($s,$t) : ($t,$s);
315 next unless (defined $t1->{$tn});
316 next unless ($t1->{$tn} eq $s1->{class});
318 if($t1->{init} <= $s1->{init}){
319 $t->{init} = "<c04>$t->{init}</c>";
321 $t->{init} = "<c12>$t->{init}</c>";
328 my ($string,$type) = @_;
330 $c = 12 if $type eq 'Emp';
331 $c = 13 if $type eq 'Steal';
332 return "<c$c>$string</c>";