#!/usr/local/bin/perl
$| = 1;
srand;

$dir = "/users/rei/Random/Foobar";

$Numchars = 2; #Number of non-PCs in datafile is 3
$Z = 9; # 0 to Number of traits per character in datafile plus one blank line
$rdx_width = 11; #set size of grid x
$rdy_height = 11; #set size of grid y
$rdy_min = 8; # minimum y distance from entrance to destination
$mapx_width = 21;
$mapy_height = 21;


@trait = ("NAME", "STR", "INT", "DEX", "SPD", "HP", "ARM", "WPN", "CURHP");
open (PASS, "$dir/passwordfile") ||
	die "$0: $!: Couldn't open $dir/passwordfile for reading.\n" ;
while ($name = <PASS>)
{
	chop ($name);
	$pword = <PASS>;
	chop ($pword);
	$pwordlist{$name} = $pword;
}
close (PASS);

print ("Your game name: ");
$Gamename = <STDIN>;
chop $Gamename;
$Gamename =~ tr/A-Z/a-z/;
# print("$Gamename lowercaseified.\n");

if ($pwordlist{$Gamename})
{
	# ask for password of existing game

	print ("Password required for $Gamename: ");
	$Password = <STDIN>;
	chop $Password;
	if ($Password ne $pwordlist{$Gamename}) 
	{
		die "Wrong password; try again.\n";
	}
	else
	{
		print("Using Game $Gamename\n");
		
		open (DATA, "$dir/$Gamename");
		for ($i = 0; $i <= $Z; $i++)
		{
			$ME[$i] = <DATA>;
			chop $ME[$i];
			@foo = split(/ /,$ME[$i]);
			$ME[$i] = $foo[1];
			# print ("@ME[$i]\n");
		}
		close (DATA);

	}

}
else
{
	# ask for new game
	print ("New Game by the name of $Gamename ? (Y/N) ");
	$newgame = <STDIN>;
	chop $newgame;
	$newgame =~ tr/A-Z/a-z/ ;
	if ($newgame ne "y") { die "Exiting: No game specified\n"; }
	else
	{
		print ("Password for the new game: ");
		$Password = <STDIN>;
		chop $Password; 
		open (PASSADD, ">>$dir/passwordfile") ||
		die "Couldn't open $dir/passwordfile for appending\n";
		print PASSADD "$Gamename\n";
		print PASSADD "$Password\n";
		close (PASSADD);
		print ("$Gamename with password $Password has been added.\n");
# MAKE NEW CHARACTER HERE
		print ("Character Generation\n");
		print ("Character name: ");
		$ME[0] = <STDIN>;
		chop $ME[0];
		print ("Now, you have a total of 100 points to distribute among the four ");	
		print ("attributes\n of Strength, Intelligence, Agility, and Quickness.\n");
		print ("After assigning these characteristics, you will be asked to confirm\n");
		print ("the numbers.  You can type q at the end to exit the game.\n");
		while (($Exit ne "y") && ($Exit ne "q"))
		{
# Prevent them from going over point total at some point 		
			$Totalpoints = 100;
			print ("You have $Totalpoints pts.  Strength? ");
			$ME[1] = <STDIN>;
			chop $ME[1];
			$Totalpoints = $Totalpoints - $ME[1];
			print ("You have $Totalpoints pts.  Intelligence? ");
			$ME[2] = <STDIN>;
			chop $ME[2];
			$Totalpoints = $Totalpoints - $ME[2];
			print ("You have $Totalpoints pts.  Agility? ");
			$ME[3] = <STDIN>;
			chop $ME[3];
			$Totalpoints = $Totalpoints - $ME[3];
			print ("You have $Totalpoints pts.  Quickness? ");
			$ME[4] = <STDIN>;
			chop $ME[4];
			$Totalpoints = $Totalpoints - $ME[4];
			print ("Are these stats what you want (y/n/q)? ");
			$Exit = <STDIN>;
			chop $Exit;
			$Exit =~ tr/A-Z/a-z/;
		}
		if ($Exit eq "q") { die "OK, bye!\n"; }
		open (CHARADD, ">>$dir/$Gamename") ||
		die "Couldn't open $dir/$Gamename for adding character info. \n";
		$ME[5] = int (($ME[1] + $ME[2] + $ME[3] + $ME[4])/4) ;
		$ME[6] = 5 ; # starting DB
		$ME[7] = 5 ; # starting OB
		$ME[8] = $ME[5]; #current HP
		for ($i = 0; $i <= $Z; $i++)
		{
			print CHARADD "$trait[$i] $ME[$i]\n";
		}
		close (CHARADD);
		print ("Stats for $ME[0] have been saved in file $Gamename.\n");

	}
}

# Whew!  Now we have, whether new or old, a character with stats.

print ("--------------------------------------------------------\n");

open (DATA, "$dir/datafile2");
$c = 0;
for (;;)
{
#	Loading in the nasty bads!

	for ($d = 0; $d <= $Z; $d++)
	{
		$THEM{$c, $d} = <DATA>;
		chop $THEM{$c, $d};
#		print ("$c, $d, $THEM{$c, $d}\n");
		if ($THEM{$c, $d} eq "*") { last; }
		@foo = split(/ /, $THEM{$c, $d});
		$THEM{$c, $d} = $foo[1];

	}
	if ($THEM{$c, $d} eq "*") { last; }
	$c++;
}
close (DATA);


# ----------------------GAME STARTS HERE -----------------------------


# finish combat system.

# Generate map
# Place baddies on map
# let character go explore


#print ("Making map....\n");
#&dungeon_maker;
#print ("Map generated.\n");

#&print_dungeon;

&load_map;
&print_map;

$curr_x = 10;
$curr_y = 3;


# Town, dungeon or outdoor wandering section..... ************

while ($Input ne "q")
{
print("You are standing upon $Map($curr_x, $curr_y).\n");
$curr_n = $curr_y - 1;
$curr_s = $curr_y + 1;
$curr_e = $curr_x + 1;
$curr_w = $curr_x - 1;
$curr_nn = $curr_n - 1;
$curr_ee = $curr_e + 1;
$curr_ss = $curr_s + 1;
$curr_ww = $curr_w - 1;

print("\n");

print("$Map{$curr_ww, $curr_nn} $Map{$curr_w, $curr_nn} $Map{$curr_x,
$curr_nn} $Map{$curr_e, $curr_nn} $Map{$curr_ee, $curr_nn}\n");

print("$Map{$curr_ww, $curr_n} $Map{$curr_w, $curr_n} $Map{$curr_x,
$curr_n} $Map{$curr_e, $curr_n} $Map{$curr_ee, $curr_n}\n");

print("$Map{$curr_ww, $curr_y} $Map{$curr_w, $curr_y} Me $Map{$curr_e,
$curr_y} $Map{$curr_ee, $curr_y}\n");

print("$Map{$curr_ww, $curr_s} $Map{$curr_w, $curr_s} $Map{$curr_x,
$curr_s} $Map{$curr_e, $curr_s} $Map{$curr_ee, $curr_s}\n");

print("$Map{$curr_ww, $curr_s} $Map{$curr_w, $curr_ss} $Map{$curr_x,
$curr_ss} $Map{$curr_e, $curr_ss} $Map{$curr_ee, $curr_ss}\n");

print("\n");
print("> ");
$Input = <STDIN>;
chop $Input;
$Input =~ tr/A-Z/a-z/;
if ($Input eq "n")
	{
	$curr_y = $curr_y - 1;
	}
if ($Input eq "e")
	{
	$curr_x = $curr_x + 1;
	}
if ($Input eq "s")
	{
	$curr_y = $curr_y + 1;
	}
if ($Input eq "w")
	{
	$curr_x = $curr_x - 1;
	}
}

# End of town/dungeon/outdoors wandering section **************


#Random Map Generator Algorithms:
# Indoor
# Outdoor
# Dungeon
# Town
# Close-up Outdoor

#Note that certain sections will be writer-made

print("\nYou run into several nasty people right here.\n");

for ($N = 0; $N <= $Numchars ; $N++)
{
	print ("Type anything to commence battle number $N (q to quit). ");
	$anything = <STDIN>;
	chop $anything;
	if ($anything eq "q") { die "Quit!\n"; }

	$MYlevel = 0;
	$THlevel = 0;
	for ($lev = 1; $lev <=4 ; $lev++)
	{
		$MYlevel = $ME[$lev] + $MYlevel;
		$THlevel = $THEM{$N, $lev} + $THlevel;
	}

	$THlevel = int($THlevel/(4*5));
	$MYlevel = int($MYlevel/(4*5));

print ("Your level: $MYlevel.  $THEM{$N, 0}'s level: $THlevel\n");

while (($THEM{$N, 8} > -($THEM{$N, 5})) && ($ME[8] > -($ME[5])))
{
	print ("Type anything to roll for initiative (q to quit). ");
	$anything = <STDIN>;
	chop $anything;
	if ($anything eq "q") { die "Quit!\n"; }
# Other options: run away, parry, spell(?)
# But initiative still determines who goes first(?)
	$IGofirst = int (rand(100)+1) + int ($ME[4]/4);
	$Theyfirst = int (rand(100)+1) + int ($THEM{$N, 4}/4);
	print ("You roll: $IGofirst.\n \n");
	if ($IGofirst >= $Theyfirst)
	{
		print ("You attack first!\n");
		&attack;
		if ($THEM{$N, 8} <= -($THEM{$N, 5})) { next; }
		print ("\n");
		&theyattack;
	}
	if ($IGofirst < $Theyfirst)
	{
		print ("$THEM{$N, 0} attacks first!\n");
		&theyattack;
		if ($ME[8] <= -($ME[5])) { next; }
		print ("\n");
		&attack;
	}
	print ("\nCurrent stats: $ME[0] has $ME[8] hps.  $THEM{$N, 0} has $THEM{$N, 8} hps.\n");
}
print ("\nNext combat!\n");
print ("Resetting your HP.\n");
$ME[8] = $ME[5];


# END OF MAIN
}


sub attack
{
	print ("$ME[0]'s attack!\n");
	$MYROLL = int (rand(100) + 1);
	$THROLL = int (rand(100) + 1);

	print ("Your roll: $MYROLL.\n");
#	print ("Their roll: $THROLL\n");

	$MYattack = int (((2*$MYROLL) + $ME[3] + $ME[4] + $ME[6])/6);
	$THdefend = int (((2*$THROLL) + $THEM{$N, 3} + $THEM{$N, 4} + $THEM{$N, 6})/6);

	# print ("Your total attack: $MYattack.  Their total defence: $THdefend.\n");

	$HITMISS = $MYattack - $THdefend;

	# print ("Difference: $HITMISS\n");

	if ($HITMISS <= 0) {print ("You miss!\n"); }
	else 
		{
		print ("You hit!\n");

		$MYOB = int ($ME[1] + (2 * $ME[7]));
		$THDB = int ($THEM{$N, 6});
		#print ("Your OB: $MYOB.  Their Defense: $THDB\n");

		$THpain = int (($HITMISS * $MYOB - $THDB)/100);
		if ($THpain < 0) {$THpain = 0;} 
		print ("$THEM{$N, 0} loses $THpain hit points\n");
		$THEM{$N, 8} = $THEM{$N, 8} - $THpain;
#		print ("They are down to $THnewhp.\n");
		if ($THEM{$N, 8} <= -($THEM{$N, 5})) {print ("$THEM{$N, 0} is dead!\n");}
		}


}



sub theyattack
{
	print ("$THEM{$N, 0}'s attack!\n");
	$MYROLL = int (rand(100) + 1);
	$THROLL = int (rand(100) + 1);

	print ("Your defense roll: $MYROLL.\n");
#	print ("Their attack roll: $THROLL\n");

	$THattack = int (((2*$THROLL) + $THEM{$N, 3} + $THEM{$N, 4} + $THEM{$N, 6})/6);
	$MYdefend = int (((2*$MYROLL) + $ME[3] + $ME[4] + $ME[6])/6);


	$HITMISS = $THattack - $MYdefend;

	# print ("Difference: $HITMISS\n");

	if ($HITMISS <= 0) {print ("$THEM{$N, 0} misses you!\n"); }
	else 
		{
		print ("You've been hit!\n");

		$THOB = int ($THEM{$N, 1} + (2 * $THEM{$N, 7}));
		$MYDB = int ($ME[6]);
		#print ("Your Defence: $MYDB.  Their OB: $THOB\n");

		$MYpain = int (($HITMISS * $THOB - $MYDB)/100);
		if ($MYpain < 0) { $MYpain = 0; }
		print ("You lose $MYpain hit points\n");
		$ME[8] = $ME[8] - $MYpain;
#		print ("You are down to $MYnewhp.\n");
		if ($ME[8] <= -($ME[5])) {print ("You're dead!\n");}
		}
# END THEIR ATTACK
}


sub dungeon_maker
{# Dungeon Generator (So it's not the most efficient in the world)

	for ($rdx = 0; $rdx <= ($rdx_width+1); $rdx++)
	{
		for ($rdy = 0; $rdy <= ($rdy_height+1); $rdy++) 
		{
		$RDungeon{$rdx, $rdy} = "S";
		}
	}
	$rdx_entrance = int (rand ($rdx_width));
	$rdy_entrance = 0;

# Entrance is somewhere along the y axis.  (0, 0) is at top left.
	$rdx_destination = int (rand($rdx_width - 1));
	$rdy_destination = int (rand($rdy_height - 1));
	if ($rdy_destination <= $rdy_min) { $rdy_destination = $rdy_min; }

	$curr_rdx = $rdx_entrance;
	$curr_rdy = $rdy_entrance;
# Now we connect the two with a semi-random path.
# LOOP BEGINS HERE
#&print_dungeon;
print ("\n");
# OH NO!  This can create corner-to-corner "squares"
# accidentally, or in sequence.  **FIX THIS**!!!*****

$ack = 0;
until (($curr_rdx == $rdx_destination) && ($curr_rdy == $rdy_destination))
{

	$rdx_closeness = &absolute($rdx_destination - $curr_rdx);
	$rdy_closeness = &absolute($rdy_destination - $curr_rdy);
	$Next_rdx = int (rand(3)) - 1; #number of 1, 0, or -1 (W, same, or East)
# Next part says, if the new random place is further away from the destination
# Roll again.  Makes it just a little more likely to go toward the
# destination, rather than wander all over the screen.
	$newrdx_close = &absolute($rdx_destination - ($curr_rdx + $Next_rdx));
	if ($newrdx_close > $rdx_closeness)
		{
		 $Next_rdx = int (rand(3)) - 1;
		}
#	print ("X roll is $Next_rdx\n");
# Set bounds.
	$curr_rdx = $curr_rdx + $Next_rdx;
	if ($curr_rdx < 0) {$curr_rdx = 0;}
	if ($curr_rdx > $rdx_width) {$curr_rdx = $rdx_width;}
	
#	print ("New curr_rdx: $curr_rdx\n");
# Do the same for y.
	$Next_rdy = int (rand(3)) - 1;
	$newrdy_close = &absolute($rdy_destination - ($curr_rdy + $Next_rdy));
	if ($newrdy_close > $rdy_closeness)
		{
		 $Next_rdy = int (rand(3)) - 1;
		} 
#	print ("Y roll is $Next_rdy.\n");
	$curr_rdy = $curr_rdy + $Next_rdy;
	if ($curr_rdy < 0) {$curr_rdy = 0;}
	if ($curr_rdy > $rdy_height) {$curr_rdy = $rdy_height;}
#	print ("New curr_rdy: $curr_rdy\n");

# Now change the map.
	$RDungeon{$curr_rdx, $curr_rdy} = ".";
#print ("\n");
#&print_dungeon;
#print ("\n");
#	$ack++;
#	if ($ack == 10) { 
#		$ack = 0;
#		$answer = <STDIN>; }
#	chop $answer;
#	if ($answer eq "q") { die "ARGH!\n"; }
# Generate random dead ends here.

}
	$RDungeon{$rdx_entrance, $rdy_entrance} = "*";
	$RDungeon{$rdx_destination, $rdy_destination} = "?";
}

sub print_dungeon
{
for ($rdy = 0; $rdy <= ($rdy_height+1); $rdy++)
	{
	for ($rdx = 0; $rdx <= ($rdx_width+1); $rdx++)
		{
		print ("$RDungeon{$rdx, $rdy} ");
		}
	print ("\n");
	}
print ("********* That's it!! *********");
}

sub absolute
{
	($whatever_number) = @_;
	if ($whatever_number < 0) 
	{ 
		$whatever_number = -($whatever_number);
	}

return ($whatever_number);
}

sub load_map
{
	print("Map name: ");
	$Mapname = <STDIN>;
	chop $Mapname;
	open (MAP, "$dir/$Mapname")
		|| die "$0: $!: Couldn't open $dir/$Mapname!\n";
	
	for ($mapy = 0; $mapy <= ($mapy_height + 1); $mapy++)
	{
		$row = <MAP>;
		chop $row;
		@pieces = split (/ /, $row);
		for ($mapx = 0; $mapx <= ($mapx_width + 1); $mapx++)
		{
			$Map{$mapx, $mapy} = $pieces[$mapx];
#			print ("$mapx, $mapy = $pieces[$mapx]\n");
		}
	}
	close (MAP);
}


sub print_map
{
for ($mapy = 0; $mapy <= ($mapy_height+1); $mapy++)
	{
	for ($mapx = 0; $mapx <= ($mapx_width+1); $mapx++)
		{
		print ("$Map{$mapx, $mapy} ");
		}
	print ("\n");
	}
print ("*********  *********");
}
