#!/usr/bin/perl
use lib '.';
#TO DO:
#- Max Damage
#- Print Mass?

#- Add fire weapons
#- Fix negative attribute points

#require "./cgi-lib.pl";
require "pagelib.pl";
header();
init();
head();
body();
#foot();
page_end();

sub headers_old {
  print "Content-type: text/html\n\n";
}

sub init {
  #ReadParse();
  read_text();
}

sub head_old {
  print "<HTML>\n<HEAD><TITLE>Brikwars Troop Scorer</TITLE>\n</HEAD>\n<BODY>\n";
}

sub body {
    print "<Br>\n";
  @teks = ("Stone Age - CaveMen, Clubs, Big Rox",
	   "Tool Age - TribalMen, Short Bows, Tiki Masks, Horses",
	   "Metal Age - Chariots, Phalanxes, Halberds, Castles",
	   "Rennaisance Age - PirateMen, Cannons, Muskets, Cavalry, Musketeers",
	   "Modern Age - ModernMen, Rifles, Tanx, Bombers, Radios, Cruise Missles",
	   "Space Age - SpaceMen, Phasers, SpaceFleets",
	   "Star Age - StarMen, DeathGuns, Energy Blades, CityStars",
	   "Hyper Age - InterDimentionalMen, Time Machines, Sentient Planets",
	  );
  $tl = $in{tl};
  if(!defined $in{tl}) {
    print "Welcome to the Brikwars 2000 edition troop scorer. This tool is";
    print " provided for Brikwars players who are already at least partially";
    print " familiar with the Brikwars rules. You may wish to have a copy of";
    print " the Brikwars 2000 rules handy while using this tool. For more";
    print " information on Brikwars, please visit the";
    print " <A HREF=\"http://www.brikwars.com/\">official Brikwars homepage</A>";
    print ". If you have any questions/comments about this tool, please feel free";
    print " to <A HREF=\"mailto:dave\@suave.net\">write me an email</A>. Enjoy!<BR><BR>\n";
    print "Please select a Tek Level: <BR>";
    for($i=0;$i<=7;$i++) {
      print "<A HREF=\"$ENV{SCRIPT_NAME}\?tl=$i\">Tek Level $i</A> - $teks[$i]<BR>";
    }
  }
  elsif($in{done}) {
    my($pts,$dmg1,$dmg2,$mp,$skill,$ccskill,$rskill,$mass,$av,$sf,$other,$ccdb,$ccsb,$rdb,$rsb,$ccav);
    @eqs=split /\0/,$in{equip};
    @attrs=split /\0/,$in{att};
    $wahands = 1;
    $ahands = 2;
    $uhands = 0;
    $whands = 0;
    $power = 1;
    foreach (keys %in) {
      if(/att_(.*)$/) { $stats{$1} = $in{$_}; }
    }
    $fig_pts = "";
    @names=($in{base},$in{hand1},$in{hand2},$in{helmet},@eqs,@attrs);
    foreach $n (@names) {
      foreach $i (@items) {
	if($i->{name} eq $n) {
	  if($i->{pts} !~ /^[\+\-]/) {
	    $pts .= "+";
	  }
	  if($i->{pts} !~ /^[\+\-]/ && $i->{type} =~ /base|att/i) {
	    $fig_pts .= "+";
	  }
	  if($i->{minpts} !~ /_/) {
	    my($tmp) = $i->{pts};
	    $tmp =~ s/TL/$tl/g;
	    if(roll_val($tmp) < roll_val($i->{minpts})) {
	      $pts .= $i->{minpts};
	      $fig_pts .= $i->{minpts} if($i->{type} =~ /base|att/i);
	    } else {
	      $pts .= $tmp;
	      $fig_pts .= $tmp if($i->{type} =~ /base|att/i);
	    }
	  } else {
	    $pts .= $i->{pts};
	    $fig_pts .= $i->{pts} if($i->{type} =~ /base|att/i);
	  }

	  if($i->{'2h'} =~ /([\+\-]\d)/) { $wahands += $1; }
	  elsif($i->{'2h'} =~ /1H/) { $uhands++; }
	  elsif($i->{'2h'} =~ /2H/) { $uhands+=2; }
	  if($i->{'type'} =~ /weapon/i) {
	    if($i->{'2h'} =~ /\dH/ && $i->{'range'} !~ /CC/) { $whands++; }
	  }
	  
	  if($i->{type} =~ /weapon/i) {
	    $weap[@weap] = $i->{name};
	    $dmg[@dmg] = $i->{dmg};
	    $range[@range] = $i->{range};
	    if($i->{mass} =~ /(\d+)/) { $wmass[@wmass] = $1; }
	    else { $wmass[@wmass] = 1; }
	  }
	  
	  if($i->{'power'} !~ /^_$/) {
	    if($i->{'type'} =~ /base/i) { $power = $i->{power}; }
	  }
	  if($i->{av} !~ /^_$/) {
	    if($i->{'type'} =~ /base/i) {
	      if($i->{'minav'} !~ /_/) {
		my($tmp) = $i->{av};
		$tmp =~ s/TL/$tl/g;
		if(roll_val($tmp) < roll_val($i->{minav})) {
		  $av = $i->{minav};
		} else {
		  $av = $i->{av};
		}
	      }
	      else {
		$av = $i->{av};
	      }
	    }
	    else {
	      if($i->{av} !~ /^[\+\-]/) { $av .= "+"; }
	      $av .= $i->{av};
	    }
	  }
	  if($i->{ccav} !~ /_/) {
	    $ccav .= $i->{ccav};
	  }
	  if($i->{skill} !~ /^_$/) {
	    if($i->{'type'} =~ /base/i) { $skill = $i->{skill}; }
	    elsif($i->{type} =~ /weapon/i) { $ur[@ur] = $i->{skill}; }
	    else {
	      if($i->{skill} !~ /^[\+\-]/) { $skill .= "+"; }
	      $skill .= $i->{skill};
	    }
	  }
	  if($i->{mp} !~ /^\s*_\s*$/) {
	    if($i->{'type'} =~ /base/i) { $mp = $i->{mp}; }
	    else {
	      if($i->{mp} !~ /^[\+\-]/) { $mp .= "+"; }
	      $mp .= $i->{mp};
	    }
	    if($i->{'type'} =~ /weapon|equip/i && $i->{mp} =~ /\-/) {
		$mp_penalty .= "$i->{mp}";
	    }
	  }
	  if($i->{ccb} !~ /_/) { $ccsb+=$i->{ccb}; }
	  if($i->{rb} !~ /_/) { $rb+=$i->{rb}; }
	  if($i->{dmg} !~ /_/ && $i->{type} !~ /weapon/i) { $ccdb+=$i->{dmg}; }
	  if($i->{sf} !~ /_|0/) { $other .= "Unit has $i->{sf} Stupendous Feats<br>\n"; }
	  if($i->{limit} !~ /_/ && $i->{type} =~ /base/i) {
	    my($txt) = $i->{limit};
	    $txt =~ s/^(\d+):(\d+)T$/Limit $1 per $2 Troops/;
	    $txt =~ s/^(\d+):(\d+)V$/Limit $1 per $2 Vehicle/;
	    $txt =~ s/^(\d+):(\d+)S$/Limit $1 per $2 Slaves/;
	    $txt =~ s/^(\d+)$/Limit $1 per team/;
	    $other .= "$txt<br>\n";
	  }
	  if($i->{specialty} !~ /^\s*_\s*$/) {
	    $other .= "$i->{specialty}<br>\n";
	  }
	}
      }
    }
    foreach $n (keys %stats) {
      foreach $a (@atts) {
	if($a->{name} eq $n) {
	  if($stats{$n} > 0 ) {
	    if($a->{pts} !~ /^[\+\-]/) { $pts .= "+"; $fig_pts .= "+";}
	    $pts .= $a->{pts}*$stats{$n};
	    $fig_pts .= $a->{pts}*$stats{$n};
	    if($a->{power} !~ /^_$/) { $power += $a->{power}*$stats{$n}; }
	    if($a->{av} !~ /^_$/) { $av .= "+".$a->{av}*$stats{$n}; }
	    if($a->{mp} !~ /^_$/) { $mp .= "+".$a->{mp}*$stats{$n}; }
	    if($a->{skill} !~ /^_$/) { $skill .= "+".$a->{skill}*$stats{$n}; }
	    if($a->{dmg} !~ /^_$/) { $ccdb += $a->{dmg}*$stats{$n}; }
	    if($a->{ccb} !~ /_/) { $ccsb += $a->{ccb}*$stats{$n}; }
	    if($a->{ccav} !~ /_/) { $ccav += $a->{ccav}*$stats{$n}; }
	  }
	  elsif($stats{$n} < 0 ) {
	    if($a->{minpts} !~ /^[\+\-]/) { $pts .= "+"; $fig_pts .= "+";}
	    $pts .= $a->{minpts}*(-1*$stats{$n});
	    $fig_pts .= $a->{minpts}*(-1*$stats{$n});
	    if($a->{power} !~ /^_$/) { $power += $a->{power}*$stats{$n}; }
	    if($a->{av} !~ /^_$/) { $av .= $a->{av}*$stats{$n}; }
	    if($a->{mp} !~ /^_$/) { $mp .= $a->{mp}*$stats{$n}; }
	    if($a->{skill} !~ /^_$/) { $skill .= $a->{skill}*$stats{$n}; }
	    if($a->{dmg} !~ /^_$/) { $ccdb += $a->{dmg}*$stats{$n}; }
	    if($a->{ccb} !~ /_/) { $ccsb += $a->{ccb}*$stats{$n}; }
	    if($a->{ccav} !~ /_/) { $ccav += $a->{ccav}*$stats{$n}; }
	  }
	}
      }
    }
    $other =~ s/\\n/\<br\>\n/g;
    $pts =~ s/TL/$tl/g;
    $av =~ s/TL/$tl/g;
    $power =~ s/TL/$tl/g;
    $skill =~ s/TL/$tl/g;
    $mp =~ s/TL/$tl/g;
    $ur[0] =~ s/TL/$tl/g;
    $ur[1] =~ s/TL/$tl/g;
    if(roll_val($fig_pts) < 2) {
      my($tmp) = eval($fig_pts);
      $pts .= "+".eval(2-$tmp);
    }

    #negate MP inhibitor for power > 1 units
    print "<!--\nmp=$mp\npenalty=$mp_penalty\npower=$power\n";
    if($mp_penalty && $power > 1) {
	my($tmp) = roll_val($mp_penalty);
	my($cap) = ($power-1)*2;
	$tmp *= -1;
	print "cap = $cap\ntmp=$tmp\n";
	if($tmp < $cap) { $mp .= "+$tmp"; }
	else { $mp .= "+$cap"; }
    }
    print "-->\n";

    #calculate throw distance
    my($tskill,$weq,$throwrange);
    if($rb) {
      if($rb !~ /^[\+\-]/) { $tskill = roll_eval("$skill+$rb"); }
      else { $tskill = roll_eval("$skill$rb"); }
    }
    else {
      $tskill = roll_eval($skill);
    }
    if($wmass[0]) {
      $weq1 = int((5*$power)/$wmass[0]);
      $trange1 = $weq1 ."+". $tskill;
      $trange1 = roll_eval($trange1);
    }
    if($wmass[1]) {
      $weq2 = int((5*$power)/$wmass[1]);
      $trange2 = $weq2 ."+". $tskill;
      $trange2 = roll_eval($trange2);
    }
    $gen_trange = roll_eval((int(5*$power))."+".$tskill);
    
    if($uhands > $ahands) { print "<b><font color=red>Warning!</font></b> Your trooper needs $uhands hands to wield what you've allotted. Because the current rules don't explain how to support this, you may have to allot yourself some additional points or just fix what you\'re using.<br>\n"; }
    if($whands > $wahands) { print "<b><font color=red>Warning!</font></b> Unfortunately, your trooper can only wield 1 of the two weapons you've given. In order to use both, you must either cheat or go back and check off the \"dual weapon\" attribute.<br>\n"; }
    print "<TABLE BORDER=1 CELLPADDING=2>\n";
    print "<TR><TD COLSPAN=4 ALIGN=CENTER><b><font size=+1>$in{name}</font></b></TD></TR>\n" if($in{name});
    print "<TR><TD>Class</TD><TD>$in{base}</TD>";
    print "<TD COLSPAN=2 ROWSPAN=5 ALIGN=CENTER>";
    if($in{image}) {
      print "<IMG SRC=\"$in{image}\"";
      print " HEIGHT=$in{height}" if($in{height});
      print " WIDTH=$in{width}" if($in{width});
      print ">";
    }
    else {
      print "No Image specified";
    }
    print "</TD></TR>\n";
    print "<TR><TD>Total CP</TD><TD>".(eval $pts)."</TD></TR>\n";
    print "<TR><TD>Armor</TD><TD>".roll_eval($av);
    if($ccav) {
      if($ccav !~ /^[\+\-]/) { print " (+$ccav CC)"; }
      else {print " ($ccav CC)"; }
    }
    print "</TD></TR>\n";
    print "<TR><TD>Movement</TD><TD>".roll_eval($mp)."\"</TD></TR>\n";
    print "<TR><TD>Skill</TD><TD>".roll_eval($skill);
    if($ccsb > 0) { print " (+$ccsb CC)"; }
    elsif($ccsb < 0) { print " ($ccsb CC)"; }
    if($rb > 0) { print " (+$rb Ranged)"; }
    elsif($rb < 0) { print " ($rb Ranged)"; }
    print "</TD></TR>\n";
    print "<TR><TD>Power</TD><TD>$power</TD><TD>Throw Range</TD><TD>$gen_trange</TD></TR>\n";
    
    if($weap[0] =~ /\S/) { print "<TR><TD ALIGN=CENTER COLSPAN=4><B>Weapons</B></TD></TR>\n"; }
    if($weap[0] =~ /\S/) {
      my($dtype);
      $ur[0] =~ s/\((\d+)A\)/ ($1 Auto Fire)/;
      if($dmg[0] =~ s/\(exp\)//) {$dtype = "(explosive)"; }
      if($dmg[0] =~ s/s//) { $dtype = "(stun)"; }
      if($dmg[0] =~ s/S//) {
	$dmg[0] =~ s/^\-//;
	$dmg[0] = "Entraps target against skill of $dmg[0]";
      }
      elsif($range[0] =~ /CC/) {
	if($ccdb > 0) { $dmg[0] .= "+".$ccdb; }
	if($ccdb < 0) { $dmg[0] .= $ccdb; }
	$dmg[0] = roll_eval($dmg[0]);
	if($power > 1) {
	  $dmg[0] = "($dmg[0])\*$power";
	}
	elsif($power < 1) {
	  $dmg[0] = "0 (Unit has $power power)";
	}
      }
      if($range[0] =~ /T/) {
	$range[0] =~ s/^T\*/\($trange1\)\*/;
	$range[0] =~ s/^T$/$trange1/;
      }
      $ur[0] =~ s/(\d+)\((\d+)\)/$1(1H) $2(2H)/;
      print "<TR><TD>$weap[0]</TD><TD>UR: $ur[0]</TD><TD>Dmg: $dmg[0] $dtype</TD><TD>Range: $range[0]</TD></TR>";
    }
    if($weap[1] =~ /\S/) {
      my($dtype);
      $ur[1] =~ s/\((\d+)A\)/ ($1 Auto Fire)/;
      if($dmg[1] =~ s/\(exp\)//) {$dtype = "(explosive)"; }
      if($dmg[1] =~ s/s//) { $dtype = "(stun)"; }
      if($dmg[1] =~ s/S//) {
	$dmg[1] =~ s/^\-//;
	$dmg[1] = "Entraps target against skill of $dmg[1]";
      }
      elsif($range[1] =~ /CC/) {
	if($ccdb > 0) { $dmg[1] .= "+".$ccdb; }
	if($ccdb < 0) { $dmg[1] .= $ccdb; }
	$dmg[1] = roll_eval($dmg[1]);
	if($power > 1) {
	  $dmg[1] = "($dmg[1])\*$power";
	}
	elsif($power < 1) {
	  $dmg[1] = "0 (Unit has $power power)";
	}
      }
      if($range[1] =~ /T/) {
	$range[1] =~ s/^T\*/\($trange2\)\*/;
	$range[1] =~ s/^T$/$trange2/;
      }
      print "<TR><TD>$weap[1]</TD><TD>UR: $ur[1]</TD><TD>Dmg: $dmg[1] $dtype</TD><TD>Range: $range[1]</TD></TR>";
    }
    print "<TR><TD VALIGN=TOP>Specialty</TD><TD COLSPAN=3>$other</TD></TR>\n" if($other);
    print "</TABLE>\n";
  }
  else {
    my($item);
    print "<FORM METHOD=GET>\n";
    print "<INPUT TYPE=HIDDEN NAME=done VALUE=1>\n";
    print "<INPUT TYPE=HIDDEN NAME=tl VALUE=\"$in{tl}\">\n";
    print "<TABLE BORDER=1 CELLPADDING=2><TR VALIGN=TOP><TD COLSPAN=2>\n";
    print "<center><b>Fluff</b></center>\n";
    print "Enter a name/description of your trooper: <INPUT TYPE=TEXT NAME=name><br>\n";
    print "Enter the URL of an image of your trooper: <INPUT TYPE=TEXT NAME=image><BR>\n";
    print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Image width: <INPUT TYPE=TEXT NAME=width SIZE=4> (\"Recommended\" 150)<BR>\n";
    print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Image height: <INPUT TYPE=TEXT NAME=height SIZE=4> (\"Recommended\" 200)<BR>\n";
    print "</TD></TR><TR><TD COLSPAN=2>\n";
    print "<center><b>The Basics</b></center>\n";
    print "<TABLE BORDER=0 CELLPADDING=0>\n";
    print "<TR><TD>Type of troop:</TD><TD><SELECT NAME=base SIZE=1>\n";
    foreach $item (@bases) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	print "<OPTION VALUE=\"";
	my($tmp2) = $item->{name};
	$tmp2 =~ s/\"/\&\#034;/g;
	print $tmp2;
	print "\">$item->{name}\n";
      }
    }
    print "</SELECT></TD></TR>\n";
    print "<TR><TD>1st Hand:</TD><TD><SELECT NAME=hand1 SIZE=1>\n";
    print "<OPTION VALUE=\"\">Nothing\n";
    foreach $item (@weapons) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'2h'} =~ /H/) {
	  print "<OPTION VALUE=\"";
	  my($tmp2) = $item->{name};
	  $tmp2 =~ s/\"/\&\#034;/g;
	  print $tmp2;
	  print "\">$item->{name}\n";
	}
      }
    }
    foreach $item (@equips) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'2h'} =~ /H/) {
	    print "<OPTION VALUE=\"";
	    my($tmp2) = $item->{name};
	    $tmp2 =~ s/\"/\&\#034;/g;
	    print $tmp2;
	    print "\">$item->{name}\n";
	}
      }
    }
    print "</SELECT></TD></TR>\n";
    print "<TR><TD>2nd Hand</TD><TD><SELECT NAME=hand2 SIZE=1>\n";
    print "<OPTION VALUE=\"\">Nothing\n";
    foreach $item (@weapons) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'2h'} =~ /H/) {
	  print "<OPTION VALUE=\"";
	  my($tmp2) = $item->{name};
	  $tmp2 =~ s/\"/\&\#034;/g;
	  print $tmp2;
	  print "\">$item->{name}\n";
	}
      }
    }
    foreach $item (@equips) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'2h'} =~ /H/) {
	  print "<OPTION VALUE=\"";
	  my($tmp2) = $item->{name};
	  $tmp2 =~ s/\"/\&\#034;/g;
	  print $tmp2;
	  print "\">$item->{name}\n";
	}
      }
    }
    print "</SELECT></TD></TR>\n";
    print "<TR><TD>Helmet:</TD><TD><SELECT NAME=helmet SIZE=1>\n";
    foreach $item (@equips) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'2h'} =~ /T/) {
	  print "<OPTION";
	  if($item->{pts} eq "0") { print " SELECTED"; }
	  print " VALUE=\"$item->{name}\">$item->{name}\n";
	}
      }
    }
    print "</SELECT></TD></TR>\n";
    print "</TABLE>\n";
    print "</TD></TR><TR VALIGN=TOP><TD>\n";
    print "<center><b>Other Equipment:</b></center>\n";
    print "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=5>\n";
    foreach $item (@equips) {
	unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	  if($item->{'2h'} !~ /H|T/) {
	  print "<TR><TD>$item->{name}</TD><TD><INPUT TYPE=CHECKBOX NAME=\"equip\" VALUE=\"$item->{name}\"></TD></TR>\n";
	}
      }
    }
    print "</TABLE>\n";
    print "</TD><TD>\n";
    print "<center><b>Attributes:</b></center>\n";
    print "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=5>\n";
    foreach $item (@atts) {
      unless($item->{tl} =~ /\d/ && $tl < $item->{tl}) {
	if($item->{'limit'} =~ /(\S+)\/(\S+)/) {
	  $min = $1;
	  $max = $2;
	  my($i);
	  print "<TR><TD>$item->{name}</TD><TD>\n";
	  for($i=$min;$i<=$max;$i++) {
	    print "<INPUT TYPE=RADIO NAME=\"att_$item->{name}\" VALUE=\"$i\"";
	    if($i==0) { print " CHECKED"; }
	    print ">".$i."x ";
	  }
	  print "</TD>\n";
	}
	else {
	  print "<TR><TD>$item->{name}</TD><TD><INPUT TYPE=CHECKBOX NAME=\"att\" VALUE=\"$item->{name}\"></TD></TR>\n";
	}
      }
    }
    print "</TABLE>\n";
    print "</TD></TR><TR><TD COLSPAN=2 ALIGN=CENTER>";
    print "<INPUT TYPE=SUBMIT VALUE=\"Get Stats\">\n";
    print "<INPUT TYPE=RESET VALUE=\"Reset Form\">\n";
    print "</TD></TR></TABLE>\n";
    print "</FORM>\n";
  }
}

#sub foot {
sub page_end {
  print "<br><br><br>Tek Levels: ";
  for($i=0;$i<=7;$i++) {
    if($i eq $tl) {
      print "<b> $i </b>";
    }
    else {
      print "<A HREF=\"$ENV{SCRIPT_NAME}\?tl=$i\"> $i </A>";
    }
  }
  print "</td></tr></table>\n";
  print "</BODY>\n</HTML>\n";
}

sub read_text {
  my(@f,$item);
  @fields = ("name",
	     "type",
	     "tl",
	     "pts",
	     "minpts",
	     "limit",
	     "av",
	     "minav",
	     "ccav",
	     "power",
	     "dmg",
	     "maxdmg",
	     "mass",
	     "range",
	     "skill",
	     "ccb",
	     "rb",
	     "mp",
	     "2h",
	     "sf",
	     "specialty",
	    );
  if(open(BW,"bw.txt")) {
    $item=0;
    while(<BW>) {
      next if(/^\#/);
      chomp;
      @f=();
      @f=split /\t+/;
      %{$items[$item]} = ();
      for($i=0;$i<@fields;$i++) {
	$items[$item]{$fields[$i]} = $f[$i];
      }
      $item++;
    }
    close BW;
    foreach $item (@items) {
      my($txt) = $item->{type};
      if($txt =~ /base/i) {
	$bases[@bases] = $item;
      }
      elsif($txt =~ /att/i) {
	$atts[@atts] = $item;
      }
      elsif($item->{type} =~ /weapon/i) {
	$weapons[@weapons] = $item;
      }
      elsif($item->{type} =~ /equip/i) {
	$equips[@equips] = $item;
      }
    }
  }
  else {
    print "Ack! Couldnt read in Brikwars Inventory!<br>\n";
  }
}

sub roll_eval {
  my($eq) = @_;
  my(@ds,%dv,$ret,$tot);
  if($eq !~ /^[\+\-]/) { $eq = "+".$eq; }
  my(@ds) = (4,6,8,10,20);
  foreach $die (@ds) {
    while($eq =~ s/([\+\-]\d+)d$die//) { $dv{$die} += $1; }
  }
  $tot .= int(eval($eq));
  if($tot > 0) { $tot = "+".$tot; }
  $ret = "";
  foreach $die (keys %dv) {
    if($dv{$die} != 0) {
      if(!$ret || $dv{$die} < 0) {
	$ret .= $dv{$die}."d$die";
      } else { 
	$ret .= "+".$dv{$die}."d$die";
      }
    }
  }
  if((eval $tot) != 0) {
    $ret .= $tot;
  }
  if($ret =~ /^\+/) { return substr($ret,1); }
  else { return $ret; }
}

sub roll_val {
  my($eq) = @_;
  my(@ds,%dv,$tot);
  if($eq !~ /^[\+\-]/) { $eq = "+".$eq; }
  my(@ds) = (4,6,8,10,20);
  foreach $die (@ds) {
    while($eq =~ s/([\+\-]\d+)d$die//) { $dv{$die} += $1; }
  }
  $tot = int(eval($eq));
  foreach $die (keys %dv) {
    $tot += $dv{$die}*$die;
  }
  return $tot;
}
