The Real HivebOt - Part 1
Jul 24 2009 Games Programming

Another IRC bOt. This one helped me dominate the hive game.
Now it can work for you too!  

Well it's not really the real hivebot. the real hivebot runs on mIRC using it's own exclusive virtual machine for 27% cpu. The real hivebot does three things: gives you the link to the forum, gives the link to the battle calculator, and logs the channel. I offered the admin to code a bot that didn't need a windows VM and he was aware of all the functionality this bOt included. But he said he was fine with the current and instead wanted me to help with some uninteresting bad idea.

Illusion is a really nice guy and I hate to say bad things about him. But this was just a really bad decision.

Here's the code for the ship calculations, and scans. Download link is at the bottom.


#!/usr/bin/perl
# e dziewa august 2008, february 2009

use warnings;
use strict;
use vars qw($VERSION %IRSSI);
use Irssi qw(command_bind signal_add); #signal_add_last
use TheHiveUnitsR4;
use POSIX;

$VERSION = '3';
%IRSSI = (
        authors                 => 'E. Dziewa',
        contact                 => 'eric@dziewa.com',
        name                    => 'The-Hive Calculator',
        description             => 'Calculates useful Hive stats',
        license                 => 'GNU GPL 3',
        url                     => 'http://eric.dziewa.com'
);

our $e = "\003";

sub private_mess {
    my ( $server, $msg, $nick, $address ) = @_;
    hivebot($server, $msg, $nick, $nick, $address );
}

sub public_mess {
        my ($server, $msg, $nick, $address, $target) = @_;
        hivebot($server, $msg, $nick, $target, $address );
}
sub hivebot { # $server, $msg, $nick, $target, $address
        my ($server, $msg, $nick, $target, $address ) = @_;

    my @match = (
    'Gladius', 'Weaver', 'Reaper', 'Moth', 'Phantom', 'Zombie', 'Mirage', 'Tarantula', 'Vinegaroon', 'Khopesh', 'Dragonfly',
    'Mine', 'Firefly', 'Bee', 'Taipan', 'Starbase', 'Mayfly', 'Necromancer', 'Harvestmen', 'Gatling gun', 'Wakizashi',
    'King Cobra', 'Mite', 'Nodachi', 'Krait', 'Orbweaver', 'Trapper', 'Boomslang', 'Junebug', 'Butterfly', 'Anaconda',
    'Gnat', 'Shrieker', 'Ghost', 'Cantil', 'Recluse', 'Broadsword', 'Midge', 'Black Mamba', 'Tick', 'Falcata',
    'Fiend', 'Thrip', 'Copperhead', 'Rattlesnake', 'Warlock', 'Vampire', 'Shamshir', 'Scorpion', 'Dirk', 'Rapier',
    'Death Adder', 'Katana', 'Meshweaver' );

    $_ = $msg;

    if ( /^![Tt][Aa][Rr][Gg][Ee][Tt] (\d{1,6}) ([A-Za-z ]{3,16}) [Ww][Ii][Tt][Hh] (\d{1,6}) ([A-Za-z ]{3,16})$/ ) {
    my $defnum = $1; my $def = $2; my $attnum = $3; my $att = $4;
    my $string; my ( $foundD, $foundA ) = 0;

    if ( ! $defnum > 0 || ! $attnum > 0 ) { print "not greater than zero"; $server->command("msg $target Numbers out of range $nick"); return }
    if ( $defnum =~ /^0.+$/ || $attnum =~ /^0.+$/ ) { print "not greater than zero"; $server->command("msg $target Leading zero numbers out of range $nick"); return }
    foreach ( @match ) { next unless /^$def/i; $def = $_; $foundD++; last }
        if ( $foundD != 1 ) { $server->command("msg $target typo $def $nick"); return }
    foreach ( @match ) { next unless /^$att/i; $att = $_; $foundA++; last }
        if ( $foundA != 1 ) { $server->command("msg $target typo $att $nick"); return }


    attack( $defnum, $def, $attnum, $att, $server, $target, $nick );

    sub attack { # number, defender, number, attacker

    my $noofd = $_[0];
    my $defender = TheHiveUnitsR4->get_unit("$_[1]");
    my $noofa = $_[2];
    my $attacker = TheHiveUnitsR4->get_unit("$_[3]");
    my $stealvar = 4.65;
    my ( $server, $target, $nick ) = ( $_[4], $_[5], $_[6] );
    my $string;

    if ( $attacker->[1][16] =~ /PDS/ ) {
        $server->command("msg $target can't atack with PDS $nick. Hint -> They can defend in the first position");
        return
    }

    my ( $a_type, $d_type ); # emp, steal, kill etc
    if (   $attacker->[1][1] =~ $defender->[1][0] || $attacker->[1][2] =~ $defender->[1][0] || $attacker->[1][3] =~ $defender->[1][0] ) { # attacker targets, now check defender
        if (  $defender->[1][1] =~ $attacker->[1][0] || $defender->[1][2] =~ $attacker->[1][0] || $defender->[1][3] =~ $attacker->[1][0] ) { # call sub two arguments
            if ( $attacker->[1][4] < $defender->[1][4] ) { # check initiative, defender winning ties

                if ( $attacker->[1][16] =~ /Steal/ && $defender->[1][16] =~ /PDS/ ) {
                    $string = sprintf("$e%02d,%02d$attacker->[0]$e cannot steal $e%02d,%02d$defender->[0]$e sorry. ",
                    $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18] );
                }
                else {
                    my $kills = int($attacker->[1][7] * $noofa / fight( $attacker, $defender, $a_type )); # guns * ships / guns to kill
                    if ( $kills > $noofd ) { $kills = $noofd }
                    $string = sprintf("\( $noofa $e%02d,%02d$attacker->[0]$e $a_type -> $kills $e%02d,%02d$defender->[0]$e \)-\( %s ",
                    $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18], commie((worth($defender)*$kills)) );
                    if ( $attacker->[1][16] =~ /Steal/ ) {
                        my $lost = ceil( $kills * worth( $defender ) / worth( $attacker ) / $stealvar );
                        $string .= sprintf("cost of $lost $e%02d,%02d$attacker->[0]$e \)-\( %s ", $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$lost)));
                        $noofa = $noofa - $lost;
                    }
                    else { $string .= ') ' }
                
                    $noofd = $noofd - int($kills); # subtract those killed
                }

                my $kills2 = int($defender->[1][7] * $noofd / fight( $defender, $attacker, $d_type )); # guns * ships / guns to kill
                if ( $kills2 > $noofa ) { $kills2 = $noofa }
                $string .= sprintf("\( $noofd $e%02d,%02d$defender->[0]$e $d_type -> $kills2 $e%02d,%02d$attacker->[0]$e \)-\( %s %s",
                $defender->[1][20], $defender->[1][18], $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$kills2)),
                $d_type =~ /Steal/ ? ')-( ' : "" );

                if ( $defender->[1][16] =~ /Steal/ ) {
                    my $lost = ceil( $kills2 * worth( $attacker ) / worth( $defender ) / $stealvar );
                    $string .= sprintf("cost of $lost $e%02d,%02d$defender->[0]$e \)-\( %s \)", $defender->[1][20], $defender->[1][18], commie((worth($defender)*$lost)));
                }
                else { $string .= ')' }
                $server->command("msg $target $string");
            }
            else { # defender first
                my $kills2 = int($defender->[1][7] * $noofd / fight( $defender, $attacker, $d_type )); # guns * ships / guns to kill
                if ( $kills2 > $noofa ) { $kills2 = $noofa }
                $string = sprintf("\( $noofd $e%02d,%02d$defender->[0]$e $d_type -> $kills2 $e%02d,%02d$attacker->[0]$e \)-\( %s %s",
                $defender->[1][20], $defender->[1][18], $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$kills2)),
                $d_type =~ /Steal/ ? ')-( ' : "" );

                if ( $defender->[1][16] =~ /Steal/ ) {
                    my $lost = ceil( $kills2 * worth( $attacker ) / worth( $defender ) / $stealvar );
                    $string .= sprintf("cost of $lost $e%02d,%02d$defender->[0]$e \)-\( %s ) ", $defender->[1][20], $defender->[1][18], commie((worth($defender)*$lost)) );
                    $noofd = $noofd - $lost;
                }
                else { $string .= ') ' }

                $noofa = $noofa - int($kills2); # subtract those killed

                if ( $attacker->[1][16] =~ /Steal/ && $defender->[1][16] =~ /PDS/ ) {
                    $string .= sprintf("\( $e%02d,%02d$attacker->[0]$e cannot steal $e%02d,%02d$defender->[0]$e, sorry \) ",
                            $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18] );
                }
                else {
                    my $kills = int($attacker->[1][7] * $noofa / fight( $attacker, $defender, $a_type )); # guns * ships / guns to kill
                    if ( $kills > $noofd ) { $kills = $noofd }
                    $string .= sprintf("\( $noofa $e%02d,%02d$attacker->[0]$e $a_type -> $kills $e%02d,%02d$defender->[0]$e \)-\( %s %s",
                            $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18], commie((worth($defender)*$kills)),
                            $a_type =~ /Steal/ ? ')-( ' : "" );

                    if ( $attacker->[1][16] =~ /Steal/ ) {
                        my $lost = ceil( $kills * worth( $defender ) / worth( $attacker ) / $stealvar );
                        $string .= sprintf("cost of $lost $e%02d,%02d$attacker->[0]$e \)-\( %s \)", $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$lost)) );
                    }
                    else { $string .= ')' }
                }
                $server->command("msg $target $string");
            }

        }
        else { # call sub one argument attacker only
            if ( $attacker->[1][16] =~ /Steal/ && $defender->[1][16] =~ /PDS/ ) {
                $string = sprintf("$e%02d,%02d$attacker->[0]$e cannot steal $e%02d,%02d$defender->[0]$e sorry ",
                    $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18] );
            }
            else {
                my $kills = int($attacker->[1][7] * $noofa / fight( $attacker, $defender, $a_type )); # guns * ships / guns to kill
                if ( $kills > $noofd ) { $kills = $noofd }
                $string = sprintf("\( $noofa $e%02d,%02d$attacker->[0]$e $a_type -> $kills $e%02d,%02d$defender->[0]$e \)-( %s %s",
                    $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18],
                    commie((worth($defender)*$kills)), $a_type =~ /Steal/ ? ')-( ' : "" );

                if ( $attacker->[1][16] =~ /Steal/ ) {
                    my $lost = ceil( $kills * worth( $defender ) / worth( $attacker ) / $stealvar );
                    $string .= sprintf("cost of $lost $e%02d,%02d$attacker->[0]$e \)-\( %s \)",
                    $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$lost)) );
                }
                else { $string .= ')' }
            }
            $server->command("msg $target $string");
        }
    }

    # defender only
    elsif ( $defender->[1][1] =~ $attacker->[1][0] || $defender->[1][2] =~ $attacker->[1][0] || $defender->[1][3] =~ $attacker->[1][0] ) { # defender only

        $string = sprintf("\( $e%02d,%02d$attacker->[0]$e doesn't target $e%02d,%02d$defender->[0]$e \) ",
            $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18] );

        if ( $defender->[1][16] =~ /Steal/ && $attacker->[1][16] =~ /PDS/ ) {
            $string .= sprintf("\( $e%02d,%02d$defender->[0]$e cannot steal $e%02d,%02d$attacker->[0]$e, sorry \)",
                $defender->[1][20], $defender->[1][18], $attacker->[1][20], $attacker->[1][18] );
        }
        else {

            my $kills2 = int($defender->[1][7] * $noofd / fight( $defender, $attacker, $d_type )); # guns * ships / guns to kill
            if ( $kills2 > $noofa ) { $kills2 = $noofa }
            $string .= sprintf("\( $noofd $e%02d,%02d$defender->[0]$e $d_type -> $kills2 $e%02d,%02d$attacker->[0]$e \)-\( %s %s",
                $defender->[1][20], $defender->[1][18], $attacker->[1][20], $attacker->[1][18], commie((worth($attacker)*$kills2)), $d_type =~ /Steal/ ? ')-( ' : ""   );

            if ( $defender->[1][16] =~ /Steal/ && $attacker->[1][16] !~ /PDS/ ) {
                my $lost = ceil( $kills2 * worth( $attacker ) / worth( $defender ) / $stealvar );
                $string .= sprintf("cost of $lost $e%02d,%02d$defender->[0]$e \)-\( %s \)", $defender->[1][20], $defender->[1][18], commie((worth($defender)*$lost)) );
            }
            else { $string .= ')' }
        }
        $server->command("msg $target $string");
    }

    else { $string = sprintf("\( $e%02d,%02d$attacker->[0]$e doesn't target $e%02d,%02d$defender->[0]$e \) \( $e%02d,%02d$defender->[0]$e doesn't target $e%02d,%02d$attacker->[0]$e \)",
            $attacker->[1][20], $attacker->[1][18], $defender->[1][20], $defender->[1][18], $defender->[1][20], $defender->[1][18], $attacker->[1][20], $attacker->[1][18] );
        $server->command("msg $target $string");
    }
}
sub fight { # attacker, defender, type
    if ( $_[0]->[1][16] =~ /^EMP$/ ) {
        my $stunone;
        $_[2] = 'EMP';
        if ( $_[1]->[1][10] == 100 ) { # trap divide by zero for Mine
            $stunone = 1000000;
        }
        else {
            $stunone = 100 / ( 100 - $_[1]->[1][10] ); ### 100 / ( 100 - emp resistance
        }
        return $stunone;
    }
    
    elsif ( $_[0]->[1][16] =~ /^Steal$/ ) {
        $_[2] = 'Steal';
        my $hitchance = ( 25 + $_[0]->[1][6] - $_[1]->[1][5] ) / 100; ### ( 25 + weaponspeed - agility ) / 100
        if ( $hitchance > 0 ) {
            my $hitstostealone = ceil( $_[1]->[1][9] / $_[0]->[1][8] ); ### ceil armor / power
            my $tostealone = $hitstostealone / $hitchance;
            return $tostealone;
        }
    }

    else {
        $_[2] = 'kill';
        my $hitchance = ( 25 + $_[0]->[1][6] - $_[1]->[1][5] ) / 100; ### ( 25 + weaponspeed - agility ) / 100
        if ( $hitchance > 0 ) {
            my $hitstokillone = ceil( $_[1]->[1][9] / $_[0]->[1][8] ); ### ceil armor / power
            my $tokillone = $hitstokillone / $hitchance;
            return $tokillone;
        }
        else { print "hit chance is less than zero" }
    }
}

sub worth { # give a ship
    my $worth = ( $_[0]->[1][11] + $_[0]->[1][12] + $_[0]->[1][13] ) * .02;
    return $worth;
}

} # <- if target end

elsif ( /^![Tt][Aa][Rr][Gg][Ee][Tt] ([A-Za-z ]{3,16})$/ ) {
    my $unit = $1; my $found = 0;
    foreach ( @match ) { next unless /^$unit/i; $unit = $_; $found++; last }
    if ( $found != 1 ) { $server->command("msg $target typo $unit $nick"); return }

    targets( $unit, $server, $target, $nick );

sub targets {
    no strict;
    my $attacker = TheHiveUnitsR4->get_unit("$_[0]");
    my $target1 =  TheHiveUnitsR4->get_targets("$_[0]", 1 );
    my $target2 =  TheHiveUnitsR4->get_targets("$_[0]", 2 );
    my $target3 =  TheHiveUnitsR4->get_targets("$_[0]", 3 );
    my ( $server, $target, $nick ) = ( $_[1], $_[2], $_[3] );
    my ( $ts1, $ts2, $ts3 ) = "";
    if ( defined( $target1 ) ) {
        if ( $attacker->[1][1] =~ /^--$/ ) {
            $ts1 = sprintf("$e%02d,%02d$attacker->[0]$e target two dashes, watch out", $attacker->[1][20], $attacker->[1][18] );
            $server->command("msg $target $ts1");
            return
        }
        elsif ( $attacker->[0] =~ /^Katana$/ ) {
            $ts1 = sprintf("$e%02d,%02d$attacker->[0]$e target two asteriks, watch out", $attacker->[1][20], $attacker->[1][18] );
            $server->command("msg $target $ts1");
            return
        }
        else {
            $ts1 .=  sprintf("$e%02d,%02d$attacker->[0]$e \($e%02d$attacker->[1][0]$e\) targets first  \($e%02d$attacker->[1][1]$e\) -> ",
            $attacker->[1][20], $attacker->[1][18], $attacker->[1][19], target_c( $attacker->[1][1] ) );
            foreach ( @$target1 ) { $ts1 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2]$e ", $_->[3] ); }
            $server->command("msg $target $ts1");
        }
    }
    if ( defined( $target2 ) ) {
        if ( $attacker->[1][2] =~ /^--$/ ) { return }
        else {
            $ts2 .=
            sprintf("$e%02d,%02d$attacker->[0]$e \($e%02d$attacker->[1][0]$e\) targets second \($e%02d$attacker->[1][2]$e\) -> ",
            $attacker->[1][20], $attacker->[1][18], $attacker->[1][19], target_c( $attacker->[1][2] ) );
            foreach ( @$target2 ) { $ts2 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2]$e ", $_->[3] ); }
            $server->command("msg $target $ts2");
        }
    }
    if ( defined( $target3 ) ) {
        if ( $attacker->[1][3] =~ /^--$/ ) { return }
        else {
            $ts3 .=
            sprintf("$e%02d,%02d$attacker->[0]$e \($e%02d$attacker->[1][0]$e\) targets third  \($e%02d$attacker->[1][3]$e\) -> ",
            $attacker->[1][20], $attacker->[1][18], $attacker->[1][19], target_c( $attacker->[1][3] ) );
            foreach ( @$target3 ) { $ts3 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2] ", $_->[3] ); }
            $server->command("msg $target $ts3");
        }
    }
}


} # <- elsif


elsif ( /^![Tt][Aa][Rr][Gg][Ee][Tt] ([Ff][Ii]|[Cc][Oo]|[Ff][Rr]|[Dd][Ee]|[Cc][Rr]|[Bb][Ss])$/ ) {
    our @sorts = qw/Fi Co Fr De Cr Bs/;
    my $types = $1; my $found = 0;
    foreach ( @sorts ) { next unless /$types/i; $types = $_; $found++; last }
    if ( $found != 1 ) { $server->command("msg $target typo $types $nick"); return }

    targetted( $types, $server, $target, $nick );

sub targetted {

my ( $str1, $str2, $str3 ) = "";
    no strict;
    my $attackee = "$_[0]";
    my $target1 =  TheHiveUnitsR4->target_by( $attackee, 1 );
    my $target2 =  TheHiveUnitsR4->target_by( $attackee, 2 );
    my $target3 =  TheHiveUnitsR4->target_by( $attackee, 3 );
    my ( $server, $target, $nick ) = ( $_[1], $_[2], $_[3] );

    if ( defined( $target1 ) ) {
        $str1 .= sprintf("$e%02d$attackee$e targetted first  by -> ",
        target_c( $attackee ) );
        foreach my $type ( @sorts ) {
            $str1 .= sprintf("$e%02d$type$e ", target_c( $type ) );
                foreach my $handle ( @$target1{$type} ) {
                    foreach ( @$handle ) {
                        $str1 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2] ", $_->[3] );
                    }
                }
        }
        cull( \$str1 );       ###
        $server->command("msg $target $str1");
    }

    if ( defined( $target2 ) ) {
        $str2 .= sprintf("$e%02d$attackee$e targetted second by -> ", target_c( $attackee ) );
        
        foreach my $type ( @sorts ) {
            $str2 .= sprintf("$e%02d$type$e ", target_c( $type ) );
                foreach my $handle ( @$target2{$type} ) {
                    foreach ( @$handle ) {
                        $str2 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2] ", $_->[3] );
                    }
                }
        }
        cull( \$str2 );
        $server->command("msg $target $str2");
    }

    if ( $target3 ) {
        $str3 .= sprintf("$e%02d$attackee$e targetted third  by -> ", target_c( $attackee ) );
        foreach my $type ( @sorts ) {
            $str3 .= sprintf("$e%02d$type$e ", target_c( $type ) );
                foreach my $handle ( @$target3{$type} ) {
                    foreach ( @$handle ) {
                        $str3 .= sprintf("$e%02d,$_->[0]$_->[1]$_->[2] ", $_->[3] );
                    }
                }  
        }
        if ( $str3 =~ /\00311Fi\003 \00313Co\003 \00312Fr\003 \00308De\003 \00309Cr\003 \00304Bs\003 $/ ) { return }
        else { cull( \$str3 ); $server->command("msg $target $str3"); }
    }
}

sub cull {
    $_ = $_[0];
    $$_ =~ s/(\00311Fi\003 )(\00313Co\003 )/$2/g;
    $$_ =~ s/(\00313Co\003 )(\00312Fr\003 )/$2/g;
    $$_ =~ s/(\00312Fr\003 )(\00308De\003 )/$2/g;
    $$_ =~ s/(\00308De\003 )(\00309Cr\003 )/$2/g;
    $$_ =~ s/(\00309Cr\003 )(\00304Bs\003 )/$2/g;
    $$_ =~ s/(\00304Bs\003 $)//g
}


} # <- elsif end

elsif ( /^![Tt][Aa][Rr][Gg][Ee][Tt]$/ ) {
    $server->command("msg $target example 1 -> !target 100 man o war with 500 bouncer");
    $server->command("msg $target example 2 -> !target pegasus");
    $server->command("msg $target example 3 -> !target Fi");
}

elsif ( /^![Ww][Oo][Rr][Kk][Ee][Rr] (\d+) (\d+)$/ ) {

calc_workers( $1, $2, $server, $target, $nick );

sub calc_workers {
    my $string;
    my $ticks = 984;

    #my ( $increment, $length, $turnnumber ) = @_; <- fix this if auction returns
    my ( $increment, $turnnumber, $server, $target, $nick ) = @_; my $length = 1;
    if ( $increment > 10000 || $length > 40 || $turnnumber > $ticks ) {
        $server->command("msg $target Those values are out of range $nick");
        return
    }
    if ( $increment =~ /^0.*$/ || $length =~ /^0.*$/ || $turnnumber =~ /^0.*$/ ) {
        $server->command("msg $target Leading zero numbers out of range $nick");
        return
    }

    my $turnsleft = $ticks - $turnnumber;
    $string = "$increment workers, $turnsleft turns remaining, will produce -> ";

    my $total = 0;

    for ( 1..$length ) {

        # no warnings
        # Useless use of private variable in void context
        # BS!

        no warnings;
        my $loopleft = $turnsleft;
        for( $loopleft; $loopleft > 0; $loopleft-- ) {
            $total += $increment * 350;
        }

    }
    
    $string .= commie( $total );
    $server->command("msg $target $string total resources");
}
} # <- end  elsif

elsif ( /^![Ww][Oo][Rr][Kk][Ee][Rr]$/ ) {
    $server->command("msg $target Returns resource accumulation, give it an amount and the tick number");
    $server->command("msg $target example -> !worker 1000 750");
}

elsif ( /^![Ss][Cc][Aa][Nn] (\d+) (\d+) (\d+) (\d+)$/ ) {

    scan( $1, $2, $3, $4, $server, $target, $nick );

sub scan_success {
    my $chance = $_[0] * ( 1 + ( ( $_[1] / $_[2] ) - ( $_[3] / $_[4] ) ) );
    if ( $chance < 0 ) { $chance = 0 }
    return $chance;
}

sub scan {
    my ( $server, $target, $nick ) = ( $_[4], $_[5], $_[6] );

    if ( $_[0] > 100000 ) { $server->command("msg $target unrealistic number of spies $nick"); return }
    elsif ( $_[0] =~ /^0.+/ ) { $server->command("msg $target leading zeroes numbers not accepted $nick"); return }
    elsif ( $_[1] > 50000 ) { $server->command("msg $target unrealistic number of workers $nick"); return }
    elsif ( $_[1] =~ /^0.*/ ) { $server->command("msg $target unacceptable number of workers $nick"); return }
    elsif ( $_[2] > 100000 ) { $server->command("msg $target unrealistic number of blockers $nick"); return }
    elsif ( $_[2] =~ /^0.+/ ) { $server->command("msg $target leading zeroes numbers not accepted $nick"); return }
    elsif ( $_[3] > 50000 ) { $server->command("msg $target unrealistic number of target workers $nick"); return }
    elsif ( $_[3] =~ /^0.*/ ) { $server->command("msg $target unacceptable number of target workers $nick"); return }
    else {

        my %s_types = (
        "Sector"      =>  "30",
        "Unit"            =>  "25",
        "Gds"         =>  "20",
        "Production"  =>  "15",
        "News"            =>  "15",
        "Military"        =>  "15",
        "Sabatoge"        =>  "8",
        "BRep"            =>  "10",
        "Infiltration"    =>  "4"
        );
        my $output = "";
        $server->command("msg $target Using $_[0] spies from a $_[1] worker planet, on a $_[3] worker planet which you assume has $_[2] blockers");

        for ( keys %s_types ) {
            $output .= sprintf("$_ -> %d%% ", scan_success( $s_types{$_}, $_[0], $_[1], $_[2], $_[3] ) );
        }
        $server->command("msg $target $output");
    }
}
} # <- end scan elsif

elsif ( /^![Ss][Cc][Aa][Nn]$/ ) {
    $server->command("msg $target Returns all scan success percentages. Give it in this order: spies, workers, target blockers, target workers");
    $server->command("msg $target example -> !scan 2000 500 1000 500");
}

elsif ( /^![Oo][Ww][Nn][Ss][Cc][Aa][Nn]$/ ) {
    $server->command("msg $target Returns the percentage for a successful worker scan. example ->  !ownscan 50 50 ( spies, source workers )" );
    $server->command("msg $target You can also give a third number ( 30 or less ) to simulate that many successive attempts.");
}

elsif ( /^![Oo][Ww][Nn][Ss][Cc][Aa][Nn] \d+ \d+(?: \d+)?$/ ) {
    my  ( $spies, $s_size, $dumbnumb, $multiplier, $outstring, $scans );

    if ( /^![Oo][Ww][Nn][Ss][Cc][Aa][Nn] (\d+) (\d+) (\d+)$/ ) { ( $spies, $s_size, $scans ) = ( $1, $2, $3 ); }
    elsif ( /^![Oo][Ww][Nn][Ss][Cc][Aa][Nn] (\d+) (\d+)$/ ) { ( $spies, $s_size ) = ( $1, $2 ); }
    else { print "wtf" }

    if ( $spies > 20000 || $s_size > 5000 || $spies =~ /^0.*$/ ) { $server->command("msg $target Values out of range $nick"); return }
        else {

            if ( $s_size == 0 || $s_size =~ /^0.+$/ ) {
                $server->command("msg $target Can't divide by your size zero planet $nick"); return; }
            if ( $spies == 0 ) {
                $outstring = sprintf("Worker scan using $spies spies, for a size $s_size planet -> %%10");
                $server->command("msg $target $outstring");
            }
            else {
                if ( $s_size <= 200 ) { $multiplier = 2; $dumbnumb = 1 }
                elsif ( $s_size > 200 ) { $multiplier = 3; $dumbnumb = 0 }
                else { print "wtf part 2" }
        
                unless($scans) {    
                    $outstring = sprintf("%.2f%% success",
                    (25 * ( $dumbnumb + ( $spies / ( $s_size * $multiplier ) ) ) ) );
                    $server->command("msg $target Worker scan using $spies spies, for a size $s_size planet -> $outstring");
                }
                else {
                    no warnings; # useless use of private variable bs
                    if ( $scans > 30 || $scans == 0 ) { $server->command("msg $target 1 through 30 $nick"); return }
                    my $found = 0;
                    $outstring = "";
                    for ( $scans; $scans > 0; $scans-- ) {
                        $b = sprintf("%.2f",
                        (25 * ( $dumbnumb + ( $spies / ( $s_size * $multiplier ) ) ) ) );
                        $outstring .= $b;
                        if ( int(rand(100)+1) <= int($b) ) {
                            $s_size++; $found++;
                            $outstring .= sprintf(" \003%02d$found\003 ", 4 );
                        }
                        $outstring .= " ";
                    }
                    $server->command("msg $nick $outstring");
                }
            }
        }
}

elsif ( /^![Cc][Oo][Ss][Tt] (\d+) ([A-Za-z ]{3,16})$/ ) {
    my $count = $1; my $unit = $2; my $found = 0;
    if ( ! $count > 0 || $count =~ /^0.*/ || $count > 1000000 ) { $server->command("msg $target $count unacceptable $nick"); return }
    foreach ( @match ) { next unless /$unit/i; $unit = $_; $found++; last }
    if ( $found != 1 ) { $server->command("msg $target typo $unit $nick"); return }
    else {
        my $unitref = TheHiveUnitsR4->get_unit("$unit");
        my $ti = $unitref->[1][11] * $count;
        my $si = $unitref->[1][12] * $count;
        my $po = $unitref->[1][13] * $count;
        my $to = ( $ti + $si + $po );
        my $sc = $to * .02;

        if ( $unitref->[1][12] == 0 ) { # seeker
            my $out = sprintf("Cost of $count $e%02d,%02d$unitref->[0]$e -> \( %s T \) \( %s total \) \( %s score \)",
                $unitref->[1][20], $unitref->[1][18],
                commie( $ti ),
                commie( $to ),
                commie( $sc )
            );
            $server->command("msg $target $out");
        }
        elsif ( $unitref->[1][13] == 0 ) { # cheetah
            my $out = sprintf("Cost of $count $e%02d,%02d$unitref->[0]$e -> \( %s T \) \( %s S \) \( %s total \) \( %s score \)",
                $unitref->[1][20], $unitref->[1][18],
                commie( $ti ),
                commie( $si ),
                commie( $to ),
                commie( $sc )
            );
            $server->command("msg $target $out");
        }
        else {
            my $out = sprintf("Cost of $count $e%02d,%02d$unitref->[0]$e -> \( %s T \) \( %s S \) \( %s P \) \( %s total \) \( %s score \)",
                $unitref->[1][20], $unitref->[1][18],
                commie( $ti ),
                commie( $si ),
                commie( $po ),
                commie( $to ),
                commie( $sc )
            );
            $server->command("msg $target $out");
        }
    }
}  

elsif ( /^![Cc][Oo][Ss][Tt]$/ ) {
    $server->command("msg $target returns cost of each resource, combined resource costs, and score of given ships.");
    $server->command("msg $target example -> !cost 100 mer");
}

    elsif ( /^![Hh][Ii][Vv][Ee]$/ ) {
        $server->command("msg $target The Hive commands are -> !target, !worker, !scan, !ownscan, !cost. Type a command alone for an example. " );
    }

    else { return; }

sub commie {
    my $txt = reverse $_[0];
    $txt =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
    return scalar reverse $txt;
}

sub target_c {
    if ( $_[0] =~ /Fi/ ) { return "11" }
    elsif ( $_[0] =~ /Co/ ) { return "13" }
    elsif ( $_[0] =~ /Fr/ ) { return "12" }
    elsif ( $_[0] =~ /De/ ) { return "8" }
    elsif ( $_[0] =~ /Cr/ ) { return "9" }
    else { return "4" }
}

} # <- hivebot function close

signal_add("message public", "public_mess");
signal_add("message private", "private_mess");


Download
Companion Module

   
Comments
Aug 6 2009
Comment #1 posted by Monarch at 7:03 am

Why can't I think of a sufficiently awesome comment for this awesome script. >.>

Jan 19 2014
Comment #2 posted by eduzwsqp at 7:22 am

m52m3z5q

cjjoukpx

insurance

tu7tvsgb

n2u7p096

Nov 29 2014
Comment #3 posted by ewpsxigq at 12:51 pm

v1bxy15l

hnbb99zs

insurance

x1net6q9

ix0u98zo

Dec 2 2014
Comment #4 posted by ewpsxigq at 3:32 pm

qjyzc44u

v19eqyic

insurance

cbq3gbhk

ci4ed4gj

Dec 4 2014
Comment #5 posted by ewpsxigq at 7:06 pm

oxscd8pj

ql6vkyq7

insurance

v3lnfutd

xrkovqkg

Comments for this entry available via RSS.
Comment Area
Your Name
Your Email (will not be published)
Your Website
Your Comment
Profanity is Prohibited
eric.dziewa.com is running WordPress.
WhiteSpace theme designed by E. Dziewa.
All content © E. Dziewa.
Thanks for stopping by.