$bot_delay=2000;

$bot_chan="#kr";
$bot_chan_pass="vojnapalcev";
$bot_nick="ZoneBot";
$bot_nick_pass="pipetka";
$bot_owner="0";

$z_tk=0;
$z_derevo=1;
$z_svetles=2;
$z_kanalizacija=3;
$z_warr_guild=97;
$z_barb_guild=98;
$z_thief_guild=99;

$zone_random=1;
$zone_marshr=2;

@zone_descr=(
  $z_tk,' ',0,0,$zone_random,'',
  $z_derevo,' ',1,4,$zone_random,'',
  $z_kanalizacija,'  ',8,9,$zone_marshr,'ddwweesnwwwwweeeee',
  $z_svetles,'  ',5,7,$zone_marshr,'wwwwnenennnnnn',
  $z_warr_guild,'   ',0,0,$zone_random,'',
  $z_barb_guild,'   ',0,0,$zone_random,'',
  $z_thief_guild,'   ',0,0,$zone_random,'',
  -1
);


$l_renta=0;
$l_sklad=3;

$path="";
$pp="";

$s_nothing=0;
$s_zoning=1;
$s_resting=2;
$s_fighting=4;
$s_eat=8;
$s_going=16;
$s_guild=32;
$s_pk=64;

@paths=(
  $z_tk,$z_derevo,'dennwnnn',
  $z_tk,$z_thief_guild,'desssssseed',
  $z_tk,$z_warr_guild,'desssswwwne',
  $z_tk,$z_barb_guild,'desssseeeee',
  $z_tk,$z_svetles,'desssswwwwsswswssw',
  $z_tk,$z_kanalizacija,'desssssswwww',
  $z_derevo,$z_thief_guild,'sssesssssssseed',
  $z_thief_guild,$z_kanalizacija,'eeeeed',
  $z_thief_guild,$z_svetles,'uwwnnwwwwsswswssw',
  -1
);

@rooms_map = (
    0, ' ', '', 0,
    1, ' ', 'u', 0,
    2, ',   -', 's', 0,
    3, '', 'e', 2,
    4, '  .', 'e', 0,
    5, '', 'u', 4,
    6, ' ', 'e', 1,
    7, '  ', 'n', 1,
    8, ' ', 's', 1,
    9, '', 'w', 1,
   10, '', 's', 9,
   11, '', 'e', 10,
   12, '', 's', 11,
  100, '', '', 100,
  101, '', 'w', 100,
  102, '', 'u', 101,
  103, '', 'w', 101,
  104, '', 'w', 103,
  105, '', 'w', 104,
  106, '', 's', 103,
  107, '', 's', 106,
  108, '', 's', 102,
  109, '', 'e', 102,
  110, '', 'd', 103,
  111, '', 'd', 110,
  112, '', 'd', 111,
  200, ' ', '', 200,
  200, '', 'e', 200,
  201, '', 'e', 200,
  202, '', 'e', 201,
  203, '', 'e', 202,
  204, '', 's', 203,
  205, '', 'w', 204,
  206, '', 's', 205,
  207, '', 'w', 206,
  208, '', 's', 207,
  209, '', 's', 208,
  210, '', 's', 209,
  211, '', 's', 210,
  212, '', 's', 211,
  213, '', 's', 212,
  300, '', '', 300,
  301, '', 'u', 300,
  302, '', 'u', 301,
  303, '', 'w', 302,
  304, '', 'w', 303,
  305, '', 'w', 304,
  306, '', 'w', 305,
  307, '', 'w', 306,
  308, '', 'n', 302,
  309, '', 'e', 302,
  310, '', 'e', 309,
  9700, ' ', '', 9700,
  9800, ' ', '', 9800,
  9900, ' ', '', 9900,
  -1
);

sub irc_say {
  local($text)=shift;
  if ($bot_irc) {
    &IRC::ext_print("PRIVMSG $bot_chan :$text");
  }
}

sub get_zone {
  local($i);
  local($loc)=shift;
  use integer;
  for ($i=0;$zone_descr[$i] ne -1;$i+=6) {
    if($zone_descr[$i] eq $loc/100) {return $i;}
  }                            
  no integer;
}

sub irc_connect() {
  &IRC::conn('irc.ru','6669');
  &IRC::print('NICK $bot_nick');
  &IRC::print('USER $bot_nick 0 * bot');
  &IRC::print("NICKSERV IDENTIFY $bot_nick_pass\n");
  &IRC::print("JOIN $bot_chan $bot_chan_pass\n");
}

sub reverce_path {
  local($p)=shift;

  local($i,$t,$c);

  $t='';
  for ($i=0;$i<length($p);$i++) {

    $c=substr($p,length($p)-$i-1,1);

       if ($c eq 'n') {$t.='s';}
    elsif ($c eq 's') {$t.='n';}
    elsif ($c eq 'e') {$t.='w';}
    elsif ($c eq 'w') {$t.='e';}
    elsif ($c eq 'u') {$t.='d';}
    elsif ($c eq 'd') {$t.='u';}
  }

  return $t;
}


sub get_path {
  local($where)=shift;
  local($l1)=shift;
  local($l2)=shift;

  local($i,$l,$p,$t);

  if ($where eq 'z') {

    for($i=0;$paths[$i] ne -1;$i+=3) {
      if (($paths[$i] eq $l1)&&($paths[$i+1] eq $l2)||
          ($paths[$i] eq $l2)&&($paths[$i+1] eq $l1)) {
       
        if ($paths[$i] eq $l1) { return $paths[$i+2]; }
        else { return &reverce_path($paths[$i+2]); }  

      }
    }

  } elsif ($where eq 'r') {

    #     
    use integer;
    if ($l1/100*100 ne $l1) {$l=$l1;} else {$l=$l2; $l2=$l1;}
    $p='';
    $t=$l+1;
    while ($l ne $t) {
      $t=$l;
      for($i=0;$rooms_map[$i] ne -1;$i+=4) {
        if (($rooms_map[$i] eq $l)&&($t eq $l)) {
          $p.=$rooms_map[$i+2];
          $l=$rooms_map[$i+3];
        }
      }
    }

    no integer;

    if ($l1 eq $l2) {return &reverce_path($p);}
    else {return $p;}

  }

  return "";

}

sub calc_path {

  local($l1)=shift;
  local($l2)=shift;

  local($p,$z1,$z2);

  use integer;

  $z1=$l1/100;
  $z2=$l2/100;

  no integer;

  if ($z1 ne $z2) {
    #    .         
    $p.=&get_path('r',$l1,$z1*100);
    $p.=&get_path('z',$z1,$z2);
  }

  $p.=&get_path('r',$z2*100,$l2);

  return $p;
}

sub direction {
  local ($d)=shift;
  if ($d<1) { return 'u'; } 
  if ($d<2) { return 'e'; } 
  if ($d<3) { return 'w'; } 
  if ($d<4) { return 's'; } 
  if ($d<5) { return 'n'; } 
  if ($d<6) { return 'd'; } 
}

sub findroom {
  local ($from)=shift;
  local ($dir)=shift;

  local ($dir2)=&reverce_path("$dir");

  local ($i,$found);

  $found=0;

  for($i=0;$rooms_map[$i] ne -1;$i+=4) {
    if ($rooms_map[$i+3] eq $from) {
      if ($rooms_map[$i+2] eq $dir2) { return $rooms_map[$i]; }
      $found=1;
    }
  }

  for($i=0;$rooms_map[$i] ne -1;$i+=4) {
    if (($rooms_map[$i] eq $from)&&($rooms_map[$i+2] eq $dir)) {
      return $rooms_map[$i+3];
    }
  }

  return -1;
}

$bot_heartbeat = sub {

  local ($r,$z);

  if ((!$bot_name)||(rand(1000)<10)) {sendl("\r\n");}

  if (!$bot_name) {&next_heartbeat; return;}

  if ($bot_say_flags eq 1) {
    $bot_say_flags++; sendl(" "); return;
  } elsif ($bot_say_flags eq 2) {
    $bot_say_flags=0;
    if (defined(@pk)) { sendl(" $bot_owner @pk"); }
    else { sendl(" $bot_owner  "); }
    &next_heartbeat;
    return;
  } elsif ($bot_say_where eq 1) {
    $bot_say_where=0;
    sendl(" $bot_owner $zone_descr[&get_zone($bot_location)+1]");
    &next_heartbeat;
    return;
  }

  if ($U::fighting) {$bot_state|=$s_fighting;} else {$bot_state&=(~$s_fighting);}

  if (($cur_H<$bot_max_H*0.4)&&($U::fighting)) {$bot_rest=100; sendl("stand\r\nflee\r\nflee\r\n");}
  if (($cur_H<$bot_max_H*0.4)&&(!$U::fighting)) {$bot_rest=100; sendl("");}
  if (($cur_V<20)&&(!$U::fighting)) {$bot_rest=100; sendl("");}

  if (($bot_state & $s_eat) eq 0) {
    if ($bot_want_eat) {sendl(" $U::food $U::container\r\n $U::food"); $bot_want_eat++;}
    if ($bot_want_drink) {sendl(" $U::water"); $bot_want_drink++;}
    if (($bot_want_eat>3)||($bot_want_drink>3)) {
      $bot_state=$s_eat;
      echo "<< $bot_name >>   ...   .";
    }
  }

  if ($bot_have_tell) {&irc_say(",  ! $bot_have_tell");}

  if ((!$bot_want_eat)&&(!$bot_want_drink)&&(($bot_state & $s_eat) ne 0)) {$bot_state &= (~$s_eat);}

  if ($bot_state eq $s_nothing) {
    $bot_marsh=0;
    $bot_target="";
    for ($i=0;$zone_descr[$i] ne -1;$i+=6) {
      if (($bot_lev>=$zone_descr[$i+2])&&($bot_lev<=$zone_descr[$i+3])) {
        $path=&calc_path($bot_location,$zone_descr[$i]*100);
        $bot_dest=$zone_descr[$i]*100;
        $bot_state|=$s_zoning;
        $bot_marsh=0;
        echo "<< $bot_name >>  -  $zone_descr[$i+1].";
      }
    }
    if ($path) {
      $bot_state|=$s_going;
    } 
  } elsif (($bot_state & $s_pk) ne 0) {
  } elsif ($bot_rest ne 0) {
    if (($bot_state & $s_fighting) ne 0) {
      sendl("stand\r\nflee\r\n");
    } else {
      $bot_rest--;
      if (!$bot_rest) {sendl("\r\n");}
    }
  } elsif (($bot_state & $s_going) ne 0) {
    if ($path) {
      if (length($path)>1) {
        $pp=substr($path,0,1);
        $path=substr($path,1,length($path));
      } else {
        $pp=$path;
        $path="";
      }
      sendl("$pp");
    } else {
      $bot_state &= (~$s_going);
      $bot_location = $bot_dest;
    }
  } elsif (($bot_state & $s_eat) ne 0) {
    if ($bot_location ne $l_sklad) {
      $path=&calc_path($bot_location,$l_sklad);
      sendl("\r\n");
      $bot_state|=$s_going;
      $bot_dest=$l_sklad;
    } else { 
      sendl(" \r\n \r\n \r\n ");
      $bot_state &= (~$s_eat);
    }
  } elsif (($bot_state & $s_fighting) ne 0) {
  } elsif (($bot_state & $s_guild) ne 0) {
    if (($bot_location ne $z_barb_guild*100)&&
        ($bot_location ne $z_warr_guild*100)&&
        ($bot_location ne $z_thief_guild*100)) {
      if ($U::prof eq '') {
        $path=&calc_path($bot_location,$z_barb_guild*100);
        $bot_dest=$z_barb_guild*100;
      } elsif (($U::prof eq '')||($U::prof eq '')) {
        $path=&calc_path($bot_location,$z_warr_guild*100);
        $bot_dest=$z_warr_guild*100;
      } elsif ($U::prof eq '') {
        $path=&calc_path($bot_location,$z_thief_guild*100);
        $bot_dest=$z_thief_guild*100;
      }
      $bot_state|=$s_going;
      $bot_state&=(~$s_zoning);
    } else {
      sendl(" \r\n");
      $bot_state&=(~$s_guild);
    }
  } elsif (($bot_state & $s_zoning) ne 0) {
    if ($bot_target) {
      sendl(" $bot_target");
      $bot_target="";
      $bot_state|=$s_fighting;
      $bot_search=0;
    } elsif (!$bot_search) {
      sendl("look");
      $bot_search++;
    } elsif ($bot_search eq 1) {
      use integer;
      $r=-1;
      if ($zone_descr[&get_zone($bot_location)+4] eq $zone_random) {
        $z=$bot_location/100;
        while (($r eq -1)||($r/100 ne $z)) {
          $dir=&direction(rand(6));
          $r=&findroom($bot_location,$dir); 
        }
        no integer;
      } elsif ($zone_descr[&get_zone($bot_location)+4] eq $zone_marshr) {
        $dir=substr($zone_descr[&get_zone($bot_location)+5],$bot_marsh,1);
        $bot_marsh++;
        $r=&findroom($bot_location,$dir); 
        if ($bot_marsh>=length($zone_descr[&get_zone($bot_location)+5])) {$bot_state&=(~$s_zoning);}
      }
      sendl("$dir");
      $bot_location=$r;
    }
  }

  &next_heartbeat;

};

sub next_heartbeat {
  $nhb=timeout { &$bot_heartbeat() } (500+rand($bot_delay)), 1;
}

alias { 
  if (!$nhb) {
    $bot_target="";
    $bot_dest=0;
    $bot_name="";
    $bot_want_eat=0;
    $bot_want_drink=0;
    $bot_in_group=0;
    $bot_have_tell="";
    $bot_rest=0;
    $bot_marsh=0;
    $bot_say_flags=0;
    $bot_say_where=0;
    $bot_state=$s_nothing;
    $bot_location=$_[0];
    $bot_max_H=0;
    $bot_max_V=0;
    if (!$bot_location) {$bot_location=$l_renta;}
    enable("ZONEBOT");
    &next_heartbeat();
    echo "  .  : $bot_location";
  } else {
    $nhb->remove;
    undef($nhb);
    echo "  .";
    disable("ZONEBOT");
  }
} "";

alias { 
  $bot_location=$_[0];
  echo " << $bot_name >> !";
} "";

alias { 
  $bot_owner=$_[0];
  echo " << $bot_name >> !";
} "";

alias { 
  $bot_delay=$_[0];
  echo " << $bot_name >> !";
} "";

alias { 
  echo " << $bot_name >> : $bot_name, : $bot_lev, : $bot_owner";
  echo " << $bot_name >> : $bot_location, : $cur_exits, : $bot_state";
  echo " << $bot_name >> : $cur_H\/$bot_max_H, :  $cur_V\/$bot_max_V";
  if ($pk[0]) {echo " << $bot_name >> -: @pk";}
} "";


alias {
  sendl("  "); 
  sendl("   "); 
  sendl("   "); 
  sendl("  "); 
  sendl("  "); 
  sendl(" "); 
  sendl(" "); 
  sendl("  10"); 
} "";

trig { $bot_want_eat++;}	'^  \.$', "1000fn:ZONEBOT";
trig { if ($1 eq $U::food) {$bot_want_eat++;} }	'^   \'([--]+)\'\.$', "1000fn:ZONEBOT";
trig { $bot_want_drink++;}	'^  \.$', "1000fn:ZONEBOT";
trig { $bot_want_drink++;}	'^\.$', "1000fn:ZONEBOT";
trig { $bot_want_eat=0;}	'^ \.$', "1000fn:ZONEBOT";
trig { $bot_want_drink=0;}	'^    \.$', "1000fn:ZONEBOT";
trig { $bot_rest=100; sendl("");}	'^  \.$', "1000fn:ZONEBOT";
trig { $bot_lev++; $bot_state&=(~$s_zoning);}	'^   !$', "1000fn:ZONEBOT";

trig { $bot_have_tell="$1:$3";}	'^([--]+) (||) : "(.*)"$', "1000fn:ZONEBOT";

trig { if (($bot_lev >= 1)&&($bot_lev <= 3)) {$bot_target="";}} '^\(\)    ,   \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 1)&&($bot_lev <= 4)) {$bot_target="";}} '^-    \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 1)&&($bot_lev <= 4)) {$bot_target="";}} '^\(\)   \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 2)&&($bot_lev <= 5)) {$bot_target="";}} '^  - \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 2)&&($bot_lev <= 5)) {$bot_target="";}} '^   \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 3)&&($bot_lev <= 6)) {$bot_target="";}} '^   ,  \.$', "500fn:ZONEBOT";

trig { if (($bot_lev >= 5)&&($bot_lev <= 8)) {$bot_target="";}} '^     \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 5)&&($bot_lev <= 8)) {$bot_target="";}} '^    \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 5)&&($bot_lev <= 8)) {$bot_target="";}} '^     \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 6)&&($bot_lev <= 8)) {$bot_target="";}} '^     \.$', "500fn:ZONEBOT";

trig { if (($bot_lev >= 5)&&($bot_lev <= 6)) {$bot_target="";}} '^     \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 5)&&($bot_lev <= 6)) {$bot_target="";}} '^   ,    \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 5)&&($bot_lev <= 8)) {$bot_target="";}} '^      \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 5)&&($bot_lev <= 8)) {$bot_target="";}} '^   \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 6)&&($bot_lev <= 8)) {$bot_target="";}} '^       \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 6)&&($bot_lev <= 8)) {$bot_target="";}} '^      \.$', "500fn:ZONEBOT";
trig { if (($bot_lev >= 6)&&($bot_lev <= 8)) {$bot_target="";}} '^-    \.$', "500fn:ZONEBOT";


trig { $bot_state&=(~$s_fighting);} '^     -- (\d+)\.$', "1000n:ZONEBOT";
trig { $bot_state&=(~$s_fighting);} '^  (\d+) (||) \.$', "1000fn:ZONEBOT";
trig { $bot_state&=(~$s_fighting);} '^,   \.$', "1000fn:ZONEBOT";
trig { $bot_state|=$s_guild;} '^, ,       \' \'\.$', "1000fn:ZONEBOT";


trig { $bot_name="$1"; $bot_lev=$3;}	'^ [-- ]+ ([--]+), ([--]+) (\d+) \.$', "1000fn:ZONEBOT";
trig {
  $cur_H=$1; $bot_max_H=$2; 
  $cur_V=$3; $bot_max_V=$4; 
}	'^  (\d+)\((\d+)\)  , (\d+)\((\d+)\)  \.$', "1000fn:ZONEBOT";

trig { $bot_state|=$s_pk; sendl("  $U::container\r\n \r\n $U::weapon2\r\n $U::weapon1\r\n $U::light\r\n "); undef(@pk); } '^###     ###', "1000fn:ZONEBOT";
trig { push @pk, "$1( $2)"; } '^  ([--]+)   (\d+) .';
trig { push @pk, "$1( $2)"; } '^  ([--]+)   (\d+) .';

trig { if ($1 eq $bot_owner) {$bot_say_flags=1;} } '^([--]+) (||) : \"\"';
trig { if ($1 eq $bot_owner) {$bot_say_where=1;} } '^([--]+) (||) : \" \"';
 
