//#include <iostream>		//This is in Avatar.h
#include <fstream>
#include <iomanip>
//#include <string>			//This is in Avatar.h
#include <conio.h>
#include <time.h>

//using namespace std;		//This is in Avatar.h
using std::ifstream;
using std::ofstream;
//using std::string;		//This is in Avatar.h
using std::setprecision;

#include "conlib/ConLib.h"
#include "Avatar.h"
#include "map.h"

enum GamePhases
{
	gpSplash = 0, gpMainMenu, gpCreateAvatar, gpSelectAvatar, gpViewSelectedAv, gpPlay, gpQuit, gpMaxPhases
};
string *mainMenu = NULL;

string	*AvailAvatarNames;
Avatar	*AvatarInUse = NULL;				//This is the active avatar the user is manipulating...

const int x_Cord = 3528;
const int y_Cord = 2328;
const int z_Cord = 1;

//Offsets determine how far 'behind' or 'ahead'
//of the pc we will reach to get data
const int OffSetX = 15;
const int OffSetY = 10;

const int MilesPerSquare = 24;

MapTile A_Map[x_Cord][y_Cord][z_Cord];

void	initGame			();
int		GSUI				();
void	OutOfRangeMsg		();
void	PickClassMsg		(string what);
void	DwarfHalfingMages	();
void	GnomePriestError	();
void	printMenu			(ConLib v, int start, int arraySize);
int		DisplaySplash		(ConLib v);//v == viewScreen
int		MainMenu			(ConLib v);
int		createAvatar		(ConLib v);
int		selectAvatar		(ConLib v, string *roster);
int		viewAvatar			(ConLib v, Avatar	*Av);
int 	displayClassAllow	(ConLib v);
bool	customClass			(ConLib v, Avatar &av);
void	getRace				(ConLib v, Avatar &Av);	
void	getCmbtValue		(ConLib v, Avatar &Av);
void	getSaveValue		(ConLib v, Avatar &Av);	
void	getHDLevel			(ConLib v, Avatar &Av);
void	getArmor			(ConLib v, Avatar &Av);	
void	getWeapons			(ConLib v, Avatar &Av);
void	getHpBonus			(ConLib v, Avatar &Av);
void	getOptionals		(ConLib v, Avatar &Av);
void	getRestrictions		(ConLib v, Avatar &Av);
void	ChangeTC			(ConLib v, int c);
void	loadWorldMap		(MapTile map[][y_Cord][z_Cord], int xLength, int yLength, int zLength);
void	saveWorldMap		(MapTile map[][y_Cord][z_Cord], int xLength, int yLength, int zLength);
void	RandomTerrain		(MapTile map[x_Cord][y_Cord][z_Cord], int xLength, int yLength, int zLength);
void	SetLocalTerrain		(MapTile map[x_Cord][y_Cord][z_Cord], Avatar *pc, int terrain);
void	displayWorldMapByTheMile(ConLib loc, MapTile A_Map[][y_Cord][z_Cord], Avatar *pc);
int		testNWP				();

int main()
{
	ConLib	myScrn;
	int		gpCurrentPhase;
	//Seed for the random number generator
	time_t timer;
	srand ((unsigned int)time(&timer));

	//Random Map Generation section-------------------------------------------------------
	//These values will have a -1 applied to them in the class Character
	//to off set Array used here
	int		x_Count			= 0;
	int		y_Count			= 0;
	int		z_Count			= 0;

	//Initiating some basic variables
	int		randTerrain		= 0;
	int		userIn;
	int		gamePhase		= 0;
	bool	showingSubMenu	= false;
	string	strData;

	initGame();
	
	//Assigning proper value before use...
	gpCurrentPhase = gpSplash;

	do
	{
		system("cls");
		switch(gpCurrentPhase)
		{
		case gpSplash:			gpCurrentPhase = DisplaySplash(myScrn);						break;
		case gpMainMenu:		gpCurrentPhase = MainMenu(myScrn);							break;
		case gpCreateAvatar:	gpCurrentPhase = createAvatar(myScrn);						break;
		case gpSelectAvatar:	gpCurrentPhase = selectAvatar(myScrn, AvailAvatarNames);	break;
		case gpViewSelectedAv:	gpCurrentPhase = viewAvatar(myScrn, AvatarInUse);			break;
		case gpPlay:
			if(AvatarInUse != NULL)
			{
				do
				{
					system("cls");
					//Show the map...
					displayWorldMapByTheMile(myScrn, A_Map, AvatarInUse);
					myScrn.SetTxtClr(cRed); cout << "P"; myScrn.SetTxtClr(cSubWhite); cout << "-Quit\n\n ";
					strData = getch();
					if(strData != "m" && strData != "M")
					{
						//At this stage keeping the char values apparent, because inside of
						//Class Avatar, the values are translated.
						if((strData != "a" && strData != "A") && (strData != "w" && strData != "W")	&&
						   (strData != "d" && strData != "D") && (strData != "p" && strData != "P"))
						{
							userIn = atoi(strData.c_str()); 
							if(userIn == 0 && strData.length() > 1)
							{
								cout << "\nInput error...\n ";
								system("pause");
							}
							else
							{
								if(userIn < 2)
								{
									switch(userIn)
									{
									case 0:
										system("cls");

										//Change PC x-coordinate
										cout << " Enter the X coordinate: "; userIn = GSUI();
										if((userIn * 24) < x_Cord) AvatarInUse->SetWorldX(userIn * MilesPerSquare);

										//Change PC y-coordinate
										cout << "\n Enter the Y coordinate: "; userIn = GSUI();
										if((userIn * 24) < y_Cord) AvatarInUse->SetWorldY(userIn * MilesPerSquare);

										break;
									case 1:
										system("cls");

										cout << "Enter the terrain type to be used:\n";
										for(userIn = tOcean1; userIn < MAX_TERRAIN; userIn++)
										{
											myScrn.SetTxtClr(cRed);
											cout << userIn << " - ";
											ChangeTC(myScrn, userIn);
											A_Map[0][0][0].printName(userIn);
											cout << "\n";
										}
										userIn = GSUI();
										SetLocalTerrain(A_Map, AvatarInUse, userIn);
										break;
									case MAX_TERRAIN:
										saveWorldMap(A_Map, x_Cord, y_Cord, z_Cord);
										break;
									}
								}
								else
								{
									switch(userIn)
									{
									case 2:
										cout << " Saving map data...please wait\n ";
										saveWorldMap(A_Map, x_Cord, y_Cord, z_Cord);
										cout << "Completed save\n ";
										system("pause");
										break;
									case 3:
										cout << " Loading map data...please wait\n ";
										loadWorldMap(A_Map, x_Cord, y_Cord, z_Cord);
										cout << "Completed load\n ";
										break;
									case 4:
										system("cls");
										cout << " Enter the terrain type to be used:\n ";
										for(userIn = tOcean1; userIn < MAX_TERRAIN; userIn++)
										{
											myScrn.SetTxtClr(cRed);
											cout << userIn << " - ";
											ChangeTC(myScrn, userIn);
											A_Map[0][0][0].printName(userIn);
											cout << "\n";
										}
										userIn = GSUI();
										if(userIn >= tNothing1 && userIn < MAX_TERRAIN)
											A_Map[AvatarInUse->GetWorldX()][AvatarInUse->GetWorldY()][0].setTerrain(userIn);
										break;
									}
								}
							}
						}
						else
						{
							//Turn left...
							if		(strData == "A" || strData == "a")
							{
								if(AvatarInUse->GetFacing() > 0)	AvatarInUse->SetFacing(AvatarInUse->GetFacing() - 1);
								else								AvatarInUse->SetFacing(7);
							}
							//Turn right...
							else if	(strData == "D" || strData == "d")
							{
								if(AvatarInUse->GetFacing() < 7)	AvatarInUse->SetFacing(AvatarInUse->GetFacing() + 1);
								else								AvatarInUse->SetFacing(0);
							}
							//Go forward...
							else if	(strData == "W" || strData == "w")
							{
								switch(AvatarInUse->GetFacing())
								{
								case 0://North
									if(AvatarInUse->GetWorldY() > 0)			AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() - 1);
									break;
								case 1://NorthEast
									if(AvatarInUse->GetWorldX() < x_Cord - 1)	AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() + 1);
									if(AvatarInUse->GetWorldY() > 0)			AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() - 1);
									break;
								case 2://East
									if(AvatarInUse->GetWorldX() < x_Cord - 1)	AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() + 1);
									break;
								case 3://SouthEast
									if(AvatarInUse->GetWorldX() < x_Cord - 1)	AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() + 1);
									if(AvatarInUse->GetWorldY() < y_Cord - 1)	AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() + 1);
									break;
								case 4://South
									if(AvatarInUse->GetWorldY() < y_Cord - 1)	AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() + 1);
									break;
								case 5://SouthWest
									if(AvatarInUse->GetWorldX() > 0)			AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() - 1);
									if(AvatarInUse->GetWorldY() < y_Cord - 1)	AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() + 1);
									break;
								case 6://West
									if(AvatarInUse->GetWorldX() > 0)			AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() - 1);
									break;
								case 7://NorthWest
									if(AvatarInUse->GetWorldX() > 0)			AvatarInUse->SetWorldX(AvatarInUse->GetWorldX() - 1);
									if(AvatarInUse->GetWorldY() > 0)			AvatarInUse->SetWorldY(AvatarInUse->GetWorldY() - 1);
									break;
								}
							}
						}
					}
				} while (strData != "p" && strData != "P");
			}
			else
			{
				cout << "\n You must first select a Character before entering the game world.\n ";
				system("pause");
			}
			gpCurrentPhase = gpMainMenu;
			break;

		//gpQuit Will cascade out of the game...
		case gpQuit: break;
		default: break;
		}
	}while(gpCurrentPhase != gpQuit);

	if(mainMenu		!= NULL)	delete [] mainMenu;
	if(AvatarInUse	!= NULL)	delete AvatarInUse;

	return 0;
}
void initGame()
{
	Avatar tmpAvatar;
	string tmpString;
	string tmpHold;
	tmpAvatar.Reset();
	
	mainMenu					= new string[gpMaxPhases];
	mainMenu[gpMainMenu]		= "Main Menu";
	mainMenu[gpCreateAvatar]	= "Create New Character";
	mainMenu[gpSelectAvatar]	= "Select Character";
	mainMenu[gpViewSelectedAv]	= "View Selected Character";
	mainMenu[gpPlay]			= "Enter Game";
	mainMenu[gpQuit]			= "Quit Textland";
	
	AvailAvatarNames = new string[maxNumAvatars];

	//Load map data
	loadWorldMap(A_Map, x_Cord, y_Cord, z_Cord);

	fstream InOutData("Avatars.dat", ios::in | ios::out);

	if(!InOutData.fail())
	{
		for(int i = 0; i < maxNumAvatars; i++)
		{
			//Creating an empty Avatar listing to be filled later...
			AvailAvatarNames[i] = "empty slot";

			InOutData.seekg((i) * sizeof(Avatar));
			InOutData.read(reinterpret_cast<char *>(&tmpAvatar), sizeof(Avatar));

			tmpString = tmpAvatar.GetFName();

			if(tmpString != "First" && tmpString.length() > 0)
			{
				tmpHold		= tmpString;
				tmpString	= tmpAvatar.GetLName();
				if(tmpString != "Last" && tmpString.length() > 0)
				{
					tmpHold += " ";
					tmpHold += tmpString;
				}

				AvailAvatarNames[i] = tmpHold;
			}

			tmpString	= "";
			tmpHold		= "";
		}
	}
	else
	{
		cout << "\n Failed to open Avatars.dat\n\n";
		system("pause");
	}
	InOutData.close();
}
//Get Safe User Input...
int GSUI()
{
	int		value;
	string	input;

	cout << "\n\n ";
	cin >> input;
	value = atoi(input.c_str());

	if(input.length() > 1 && value == 0)
	{
		cout << "You entered a non-numeric value\n"
			 << "Returning a zero value\n ";
		system("pause");
		return 0;
	}
	else return value;
}
void OutOfRangeMsg()
{
	cout << "\n The value you entered was out of range\n ";
	system("pause");
}
void PickClassMsg(string what)
{
	cout << "\n You must assign " << what << " first\n ";
	system("pause");
}
void DwarfHalfingMages()
{
	cout << "\n Dwarves and Halflings are not allowed to be Mages.\n ";
	system("pause");
}
void GnomePriestError()
{
	cout << "\n Gnomes are not allowed to cast Priest spells.\n ";
	system("pause");
}
void printMenu(ConLib v, int start, int arraySize)
{
	for(int i = start; i < arraySize; i++)
	{
		v.SetTxtClr(cGreen);	cout << "\n " << i << ") ";
		v.SetTxtClr(cSubWhite);	cout << mainMenu[i];
	}
}
int DisplaySplash(ConLib v)
{
	v.SetTxtClr(cGreen);	cout << "\n      Welcome to\n\n";
	v.SetTxtClr(cRed);		cout << " Adventures in Textland\n\n";

	v.SetTxtClr(cSubWhite); cout << " "; system("pause"); 
	return gpMainMenu;
}
int MainMenu(ConLib v)
{
	int userInput = 0;

	do
	{
		system("cls");
		v.SetTxtClr(cRed); cout << "\n Adventures in Textland\n";
		if(mainMenu != NULL)
		{
			printMenu(v, gpMainMenu, gpMaxPhases);
			userInput = GSUI();
			
			if		(userInput < gpMainMenu || userInput >= gpMaxPhases) OutOfRangeMsg();
			else if (userInput == gpMainMenu)
			{
				//This keeps the string variable from being recreated
				//by keeping User within this function - MWhite 15 Nov, 2015
				cout << "\n You're in the Main Menu.\n ";
				system("pause");
				
				//Forcing out of range value so we stay in the do-while loop...
				userInput = gpMaxPhases;
			}
		}
	} while (userInput < gpMainMenu || userInput >= gpMaxPhases);

	return userInput;
}
int createAvatar(ConLib v)
{
	enum avOptions
	{
		avFName, avMName, avLName,
		avSex, avRace, avAlign, avHeight, avWeight,
		avDual, avClass, avKits, avViewAllowed, 
		avRollsAtts, avPickWeapons, avPickNWPs, avSave, avQuit, MAX_avOpts
	};
    
	char	tmpChrStr[32];
	int		tmpStats[5][7];
	int		userInput			= -1;
	int		tmpInt				= 0; //working tool in various capacities
	int		i					= 0; //loop counter
	int		numStatRolls		= 0;
	bool	classPicked			= false;
	bool	kitPicked			= false;
	bool	found				= false;
	bool	weaponVsClass[cMAX_CLASSES];
	string	tmpStr				= "";
	Avatar	tmpChar; tmpChar.Reset();

	fstream InOutData("Avatars.dat", ios::in | ios::out);

	//TEMPORARY CODE TO GENERATE 'CLEAN' DATA FILE
	//found = true;
	if(found == true)
	{
		for(i = 0; i < maxNumAvatars; i++)
		{
			//We move the file index into position
			InOutData.seekg(i * sizeof(Avatar));
			//We write the amount of data back to the file
			InOutData.write(reinterpret_cast<char *>(&tmpChar), sizeof(Avatar));
		}
		InOutData.close();
		return gpMainMenu;
	}

	if(InOutData.is_open())
	{
		//Set some default values necessary to conduct other actions...
		classPicked = false;
		numStatRolls = 3;

		do
		{
			system("cls");
			v.SetTxtClr(cGreen);	cout << "\n Character Creation\n\n";
			//Name stuff...
			v.SetTxtClr(cSubWhite);	cout << " Name: ";			
			v.SetTxtClr(cGreen);	cout << avFName	<< ") "; v.SetTxtClr(cSubWhite); cout << tmpChar.GetFName()	<< " ";
			v.SetTxtClr(cGreen);	cout << avMName << ") "; v.SetTxtClr(cSubWhite); cout << tmpChar.GetMName()	<< " ";
			v.SetTxtClr(cGreen);	cout << avLName << ") "; v.SetTxtClr(cSubWhite); cout << tmpChar.GetLName()	<< "\n ";
			//Sex/Race...
			v.SetTxtClr(cGreen);	cout << avSex	<< ") "; v.SetTxtClr(cSubWhite); cout << "Sex: ";
			if(tmpChar.GetSex() == 0) cout << "Male"; else cout << "Female"; cout << " ";
			v.SetTxtClr(cGreen);	cout << avRace		<< ") "; v.SetTxtClr(cSubWhite); cout << "Race: ";	cout << tmpChar.GetRaceStr(tmpChar.GetRace())	<< " ";
			v.SetTxtClr(cGreen);	cout << avAlign	<< ") "; v.SetTxtClr(cSubWhite); cout << "Alignment: "; cout << tmpChar.GetAlign() << "\n ";
			//Height/Weight...
			v.SetTxtClr(cGreen);	cout << avHeight << ") "; v.SetTxtClr(cSubWhite); cout << "Height: ";	cout << tmpChar.GetHeight() << " \" ";
			v.SetTxtClr(cGreen);	cout << avWeight << ") "; v.SetTxtClr(cSubWhite); cout << "Weight: ";  cout << tmpChar.GetWeight() << " lbs.\n\n ";
			//Class related
			v.SetTxtClr(cGreen);	cout << avDual   << ") "; v.SetTxtClr(cSubWhite); cout << "Class Aquisition: ";
			if(tmpChar.GetStatus(asMultiClass) == false) cout << "Dual-class"; else cout << "Multi-class"; cout << " ";
			if(tmpChar.GetRace() == MAX_pcRACES) v.SetTxtClr(cGrey); else v.SetTxtClr(cGreen);
			cout << avClass  << ") "; v.SetTxtClr(cSubWhite); cout << "Class: ";

			if(tmpChar.GetStatus(asMultiClass) == false) cout << tmpChar.GetClassStr(0);
			else
			{
				//Assigning how many class slots to present based upon race
				switch(tmpChar.GetRace())
				{
				case rDwarf: case rGnome: case rHalfling: tmpInt = 2; break;
				default: tmpInt = 3; break;
				}

				for(i = 0; i < tmpInt; i++)
				{
					cout << tmpChar.GetClassStr(i);
					if(i < tmpInt - 1) cout << " / ";
				}
			}

			if(classPicked == false || tmpChar.GetSStr() < 1) v.SetTxtClr(cGrey);
			else v.SetTxtClr(cGreen);
			cout << "\n " << avKits << ") ";
			v.SetTxtClr(cSubWhite);	cout << "Kit: ";
			if(tmpChar.GetStatus(asMultiClass) == false) cout << tmpChar.GetKitStr(0);
			else
			{
				//Assigning how many class slots to present based upon race
				switch(tmpChar.GetRace())
				{
				case rDwarf: case rGnome: case rHalfling: tmpInt = 2; break;
				default: tmpInt = 3; break;
				}

				for(i = 0; i < tmpInt; i++)
				{
					cout << tmpChar.GetKitStr(i);
					if(i < tmpInt - 1) cout << " / ";
				}
			}

			v.SetTxtClr(cGreen);	cout << " " << avViewAllowed << ") ";
			v.SetTxtClr(cSubWhite);	cout << "View Class Restrictions";
			
			cout << "\n\n ";

			//Attribute stuff...
			if		(tmpChar.GetRace() == MAX_pcRACES)										v.SetTxtClr(cGrey);
			else if (classPicked != true && tmpChar.GetStatus(asMultiClass) == false)		v.SetTxtClr(cGrey);
			else if (tmpChar.GetStatus(asMultiClass) == true && tmpChar.GetNumClass() < 2)	v.SetTxtClr(cGrey);
			else																			v.SetTxtClr(cGreen);
			cout << avRollsAtts	<< ") "; v.SetTxtClr(cSubWhite); cout << "Attributes\n";
			//Asking if value is below 10 so we can create a leading '0' to give double digits...
			cout << " Str: "; if(tmpChar.GetSStr() < 10) cout << "0"; cout << tmpChar.GetSStr();
			if(tmpChar.GetStrE() > 0)
			{
				cout << " / ";
				if(tmpChar.GetStrE() < 10)	cout << "0" << tmpChar.GetStrE();
				else						cout << tmpChar.GetStrE();
			}	
			cout << "\n";		//If a stat is below ten, we want a leading 0 placement...
			cout << " Dex: "; if(tmpChar.GetSDex() < 10) cout << "0"; cout << tmpChar.GetSDex() << "\n";
			cout << " Con: "; if(tmpChar.GetSCon() < 10) cout << "0"; cout << tmpChar.GetSCon() << "\n";
			cout << " Int: "; if(tmpChar.GetSInt() < 10) cout << "0"; cout << tmpChar.GetSInt() << "\n";
			cout << " Wis: "; if(tmpChar.GetSWis() < 10) cout << "0"; cout << tmpChar.GetSWis() << "\n";
			cout << " Cha: "; if(tmpChar.GetSCha() < 10) cout << "0"; cout << tmpChar.GetSCha() << "\n";
			cout << " Com: "; if(tmpChar.GetSCom() < 10) cout << "0"; cout << tmpChar.GetSCom() << "\n\n";

			cout << " Number of Rolls: ";

			//Change color of asterix before printing...
			switch(numStatRolls)
			{
			case 3:		v.SetTxtClr(cGreen);		break;
			case 2:		v.SetTxtClr(cYellow);		break;
			case 1:		v.SetTxtClr(cRed);			break;
			default: break;
			}
			for(i = 0; i < numStatRolls; i++) cout << "*";

			cout << "\n\n ";

			//Weapons
			if(classPicked == false) v.SetTxtClr(cGrey); else v.SetTxtClr(cGreen); cout << avPickWeapons << ") ";
			v.SetTxtClr(cSubWhite); cout << "Weapon Proficiencies:\n ";
			if(tmpChar.GetNumWPsUsed() > 0)
			{
				tmpInt = 0;//keep track of how many slots we've counted...
				for(i = 0; i < MAX_WEAPONPRO; i++)
				{
					if(tmpChar.GetWPSlotCost(i) > 0)
					{
						tmpInt += tmpChar.GetWPSlotCost(i);
						cout << tmpChar.GetWProName(i);

						if(tmpChar.GetWPSlotCost(i) > 1)	cout << " (Spc)";

						if(tmpInt < tmpChar.GetNumWPsUsed())
						{
							v.SetTxtClr(cYellow);
							cout << " / ";
							v.SetTxtClr(cSubWhite);
						}
					}
				}
			}
			else cout << "Pick Weapon Proficiencies";

			cout << "\n\n ";

			//NWPs
			if(classPicked == false || tmpChar.GetSInt() < 1)
				v.SetTxtClr(cGrey);
			else v.SetTxtClr(cGreen); cout << avPickNWPs << ") ";
			v.SetTxtClr(cSubWhite); cout << "Non-Weapon Proficiencies:\n";
			if(tmpChar.GetNumNWPSAllocated() > 0)
			{
				for(i = 0; i < MAX_NWPs; i++)
				{
					if(tmpChar.GetNWPnumSlotsAll(i) > 0)
					{
						cout << setw(25);
						tmpStr = tmpChar.GetNWPStr(i);
						tmpStr += " ";
						sprintf(tmpChrStr, "%d", tmpChar.GetNWPnumSlotsAll(i));
						tmpStr += tmpChrStr;
						cout << tmpStr;
						cout << "\n";
					}
				}
			}
			else cout << " Pick Non-Weapon Proficiencies\n";
			cout << "\n";
			//Menu commands...
			v.SetTxtClr(cGreen); cout << " " << avSave << ") "; v.SetTxtClr(cSubWhite); cout << "Save Character\n";
			v.SetTxtClr(cGreen); cout << " " << avQuit << ") "; v.SetTxtClr(cSubWhite); cout << "Quit";
			do
			{
				userInput = GSUI();
				if(userInput < avFName || userInput >= MAX_avOpts) OutOfRangeMsg();
			} while (userInput < avFName || userInput >= MAX_avOpts);
			//This clear-screen recreated for the following switch-statement.
			system("cls");
			v.SetTxtClr(cGreen); cout << "\n Character Creation\n\n";
			v.SetTxtClr(cSubWhite);
			//React to user input...
			switch(userInput)
			{
			case avFName:
			case avMName:
			case avLName:
				cout << " Enter a new ";
				switch(userInput)
				{
				case avFName:	cout << "first";	break;
				case avMName:	cout << "middle";	break;
				case avLName:	cout << "last";		break;
				};
				cout << " name (maximum of 15 characters): ";
				do
				{
					cin >> tmpStr;
					if(tmpStr.length() < 1 || tmpStr.length() > (maxNameLength - 1)) 
					{
						OutOfRangeMsg();
						cout << "\n Enter name again: ";
					}
					else
					{
						if		(userInput == avFName)	tmpChar.SetFName(tmpStr);
						else if (userInput == avMName)	tmpChar.SetMName(tmpStr);
						else							tmpChar.SetLName(tmpStr);
					}
				} while (tmpStr.length() < 1 || tmpStr.length() > maxNameLength - 1);
				break;
			case avSex:
				do
				{
					v.SetTxtClr(cGreen); cout << " 0) "; v.SetTxtClr(cSubWhite); cout << "Male";
					v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << "Female";
					cout << "\n ";
					tmpStr = getch();
					userInput = atoi(tmpStr.c_str());
					//userInput = GetSafeUserInput();
					if(userInput < 0 || userInput > 1)	OutOfRangeMsg();
					else								tmpChar.SetSex(userInput);
				} while (userInput < 0 || userInput > 1);
				break;
			case avRace:
				userInput = -1;
				tmpChar.ResetStartingStats();
				//Clear classes
				tmpChar.SetClass(cMAX_CLASSES);
				classPicked = false;
				//Clear Height/Weight
				tmpChar.SetHeight(0);
				tmpChar.SetWeight(0);
				do
				{
					cout << " Chose a race from the list:\n";
					for(int i = 0; i < MAX_pcRACES; i++)
					{
						v.SetTxtClr(cGreen);	cout << " " << i << ") ";
						v.SetTxtClr(cSubWhite);	cout << tmpChar.GetRaceStr(i) << "\n";
					}
					cout << "\n Don't forget to assign Height and Weight.";
					userInput = GSUI();
					if(userInput < 0 || userInput >= MAX_pcRACES)	OutOfRangeMsg();
					else										tmpChar.SetRace(userInput);
				}while(userInput < 0 || userInput >= MAX_pcRACES);
				break;
			case avAlign:
				userInput	= -1;
				tmpInt		= -1;
				i			= -1;
				do
				{
					cout << " There are two aspects to Alignment - Law and Goodness\n"
						 << " Under Law, there is Lawful, Nuetral and Chaotic\n"
						 << " Under Goodness, there is Good, Nuetral and Evil\n"
						 << " During the adventure the choices for encounters\n"
						 << " will have an impact on your Alignment.\n\n"
						 << " Select the categories you wish to assign to these aspects\n";

					do
					{
						cout << "\n Lawfulness:\n";
						v.SetTxtClr(cGreen); cout << " 0) "; v.SetTxtClr(cSubWhite); cout << "Lawful\n";
						v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << "Nuetral\n";
						v.SetTxtClr(cGreen); cout << " 2) "; v.SetTxtClr(cSubWhite); cout << "Chaotic";
						tmpInt = GSUI();
					}while(tmpInt < 0 || tmpInt > 2);
					do
					{
						cout << "\n Goodness:\n";
						v.SetTxtClr(cGreen); cout << " 0) "; v.SetTxtClr(cSubWhite); cout << "Good\n";
						v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << "Nuetral\n";
						v.SetTxtClr(cGreen); cout << " 2) "; v.SetTxtClr(cSubWhite); cout << "Evil";
						i = GSUI();
					}while(i < 0 || i > 2);
				}while((tmpInt < 0 || tmpInt > 2) || (i < 0 || i > 2));
				switch(tmpInt)
				{
				case 0:		tmpInt = 83;	break;
				case 1:		tmpInt = 50;	break;
				default:	tmpInt = 17;	break;
				}
				switch(i)
				{
				case 0:		i = 83;			break;
				case 1:		i = 50;			break;
				default:	i = 17;			break;
				}
				tmpChar.SetAlign(tmpInt, i);
				break;
			case avHeight:
			case avWeight:
				tmpInt = -1;
				do
				{
					cout << " Which way would you prefer to assign ";
					if(userInput == avHeight)	cout << "Height";
					else						cout << "Weight";
					cout << "?\n";

					v.SetTxtClr(cGreen); cout << " 0) "; v.SetTxtClr(cSubWhite); cout << "Enter your own value\n";
					v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << "Randomly assigned";

					tmpInt = GSUI();

					if(tmpInt < 0 || tmpInt > 1) 	OutOfRangeMsg();
					else
					{
						if(tmpInt == 0)
						{
							cout << "\n Enter total ";
							if(userInput == avHeight)	cout << "height in inches";
							else						cout << "weight in pounds";
							cout << " (no fractions): ";
							tmpInt = GSUI();

							if(userInput == avHeight)	tmpChar.SetHeight(tmpInt);
							else						tmpChar.SetWeight(tmpInt);
						}
						else
						{
							if(tmpChar.GetRace() != MAX_pcRACES)
							{
								if(userInput == avHeight)	tmpChar.SetRandomHeight();
								else						tmpChar.SetRandomWeight();
							}
							else
							{
								cout << " Random setting requires you to pick a race first.\n ";
								system("pause");
							}
						}
					}
					
					tmpInt = 0;//reset so that it escapes the function...

				}while(tmpInt < 0 || tmpInt > 1);
				break;
			case avDual:
				userInput = -1;
				tmpChar.ResetStartingStats();
				//Clear classes
				tmpChar.SetClass(cMAX_CLASSES);
				classPicked = false;
				do
				{
					cout << " This version of game allows you to acquire classes either as\n"
						 << " Multi-Class, or Dual-Class Capable (standard single class)\n"
						 << " regardless of your character's race. The Core Rules for\n"
						 << " playing Multi- or Dual- Class have been modified. Enter the\n"
						 << " number for which path you want your character to follow\n\n";

					v.SetTxtClr(cGreen); cout << " 0) "; v.SetTxtClr(cSubWhite); cout << " Dual-Class";
					v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << " Multi-Class";
					
					tmpStr = getch();
					userInput = atoi(tmpStr.c_str());

					if(userInput < 0 || userInput > 1) OutOfRangeMsg();
					else
					{
						if(userInput == 0)	tmpChar.SetStatus(asMultiClass, false);
						else				tmpChar.SetStatus(asMultiClass, true);

						tmpChar.SetClass(cMAX_CLASSES);
						classPicked = false;
					}
				}while(userInput < 0 || userInput > 1);
				break;
			case avClass:
				userInput = -1;
				if(tmpChar.GetRace() < MAX_pcRACES)
				{
					tmpChar.ResetStartingStats();
					numStatRolls = 3;
					tmpChar.ResetWPs();
					v.SetTxtClr(cSubWhite);

					do
					{
						system("cls");
						cout << "\n Pick a class to add:\n\n";

						//Displaying Classes to pick from / menu--------------------------------------------------------//
						//Using c0LvlHuman + 1 in case additional classes are added later...							//
						for(i = c0LvlHuman + 1; i < cMAX_CLASSES; i++)													//
						{																								//
							if		((tmpChar.GetRace() == rDwarf || tmpChar.GetRace() == rHalfling) && i == cWizard)	//
							{																							//
								v.SetTxtClr(cGrey);		cout << " " << i << ") ";										//
								v.SetTxtClr(cGrey);		cout << tmpChar.GetClassNam(i);									//
							}																							//
							else if	(tmpChar.GetRace()  == rGnome && i == cPriest)										//
							{																							//
								v.SetTxtClr(cGrey);		cout << " " << i << ") ";										//
								v.SetTxtClr(cGrey);		cout << tmpChar.GetClassNam(i);									//
							}																							//
							else if (tmpChar.GetStatus(asMultiClass) == true   && i == cPriest)										//
							{																							//
								if(tmpChar.GetRace() == rElf || tmpChar.GetRace() == rHalfling)							//
								{																						//
									v.SetTxtClr(cGrey);		cout << " " << i << ") ";									//
									v.SetTxtClr(cGrey);		cout << tmpChar.GetClassNam(i);								//
								}																						//
								else																					//
								{																						//
									v.SetTxtClr(cGreen);	cout << " " << i << ") ";									//
									v.SetTxtClr(cSubWhite); cout << tmpChar.GetClassNam(i);								//
								}																						//
							}																							//
							else if	(i == cCustom)																		//
							{																							//
								if(tmpChar.GetStatus(asMultiClass) == true)															//
								{																						//
									v.SetTxtClr(cGrey);																	//
									cout << " " << i << ") ";															//
									cout << tmpChar.GetClassNam(i);														//
								}																						//
								else																					//
								{																						//
									v.SetTxtClr(cGreen); cout << " " << i << ") ";										//
									v.SetTxtClr(cSubWhite); cout << tmpChar.GetClassNam(i);								//
								}																						//
							}																							//
							else																						//
							{																							//
								v.SetTxtClr(cGreen);	cout << " " << i << ") ";										//
								v.SetTxtClr(cSubWhite); cout << tmpChar.GetClassNam(i);									//
							}																							//
							cout << "\n";																				//
						}																								//
						v.SetTxtClr(cGreen); cout << " " << i << ")"; v.SetTxtClr(cSubWhite); cout << " Reset\n";		//
						i++;//just incrementing for next version...														//
						v.SetTxtClr(cGreen); cout << " " << i << ")"; v.SetTxtClr(cSubWhite); cout << " Class matrix.\n";//
						//----------------------------------------------------------------------------------------------//
                        
						//Getting the user's choice...
						userInput = GSUI();
						
						//Test to make sure that the user picked an allowed value
						if		(userInput < cWarrior || userInput > cMAX_CLASSES + 1) OutOfRangeMsg();
						else if	(userInput == cMAX_CLASSES + 1) displayClassAllow(v);
						//Picked an allowed value, continue program flow
						else
						{
							//If the user chose Multi-class
							if		(tmpChar.GetStatus(asMultiClass) == true)
							{
								switch(userInput)
								{
								case cCustom:
									cout << " Multi-class characters are restricted from creating\n"
										 << " custom Classes. By taking multi-class, you're going\n"
										 << " to have too many restrictions already.\n\n ";
									//Reset value so that we'll loop back in
									userInput = -1;
									system("pause");
									break;
								case cWizard:
									if(tmpChar.GetRace() == rGnome || tmpChar.GetRace() == rElf)
									{
										DwarfHalfingMages();
										userInput = -1;
									}
									else tmpChar.SetClass(userInput);
									break;
								case cPriest:
									if(tmpChar.GetRace() == rGnome || tmpChar.GetRace() == rElf)
									{
										GnomePriestError();
										userInput = -1;
									}
									else tmpChar.SetClass(userInput);
									break;
								default:
									tmpChar.SetClass(userInput);
									break;
								}
							}
							//Not multi-class == (Dual-class)
							else
							{
								switch(userInput)
								{
								case cWizard:
									if(tmpChar.GetRace() == rDwarf || tmpChar.GetRace() == rHalfling)
									{
										DwarfHalfingMages();
										userInput = -1;
									}
									else tmpChar.SetClass(userInput);
									break;
								case cPriest:
									if	(tmpChar.GetRace() == rGnome)
									{
										GnomePriestError();
										userInput = -1;
									}
									else tmpChar.SetClass(userInput);
									break;
								case cCustom:
									//Reset the custom class to defaults
									tmpChar.ResetCustom();

									//If the function returns true, the class has been built
									//and can have classPicked set to TRUE
									if(customClass(v, tmpChar) == true)
									{
										classPicked = true;
										tmpChar.SetClass(cCustom);
									}
									//Else, negate everything
									else
									{
										classPicked = false;
										tmpChar.SetClass(cMAX_CLASSES);
										tmpChar.ResetCustom();
									}
									break;
								default:
									tmpChar.SetClass(userInput);
									break;
								}
							}

							//Figure out if the user has met requirements to assign 'ClassPicked'
							//Evaluate custom, as it has dificult checks...
							if(userInput != cCustom)
							{
								//Not a custom class picked...
								if(tmpChar.GetStatus(asMultiClass) == false)
								{
									//...simply check to see if the 0-index is not
									if(tmpChar.GetClass(0) != cMAX_CLASSES)	classPicked = true;
									else classPicked = false;
								}
								//If Multi-class capable...
								else
								{
									//...make sure they have at least two picked... 
									if(tmpChar.GetNumClass() >= 2)	classPicked = true;
									else classPicked = false;
								}
							}
						}
					}while(userInput < cWarrior || userInput > cMAX_CLASSES);
				}
				else
				{
					cout << " You need to pick a Race before you can proceed\n ";
					system("pause");
				}
				break;
			case avKits:
				if(classPicked == true)
				{
					//Testing one of the stats to see if any have been assigned already...
					if(tmpChar.GetSStr() > 0)
					{
						cout << "\n Assigning kits needs work"\
							 << "\n Press any key to return.";
						getch();
					}
					else PickClassMsg("stats");
				}
				else PickClassMsg("a Class");
				break;
			case avViewAllowed:
				displayClassAllow(v);
				break;
			case avRollsAtts:
				if(numStatRolls > 0)
				{
					if		(tmpChar.GetRace() == MAX_pcRACES)										PickClassMsg("Race");
					else if	(classPicked != true && tmpChar.GetStatus(asMultiClass) == false)		PickClassMsg("a Class");
					else if	(tmpChar.GetStatus(asMultiClass) == true && tmpChar.GetNumClass() < 2)	PickClassMsg("two Classes");
					else
					{
						numStatRolls--;
						userInput = -1;
						tmpChar.ResetStartingStats();
						
						//Rolling 7 stats...
						for(int y = 0; y < 7; y++)
						{
							//Roll the four dice for a single stat...
							for(int x = 0; x < 4; x++)
							{
								tmpStats[x][y] = rand() % 6;				//Rolling four dice for stats...
								if(tmpStats[x][y] < 1) tmpStats[x][y] = 6;	//Verify that the die roll
								tmpStats[4][y] = 0;							//Prepare final position to accept a total
							}
							
							//Order the rolls high to low
							for(int j = 0; j < 4; j++)
								for(int i = 0; i < 4; i++)
									if(tmpStats[i][y] < tmpStats[j][y])
									{
										userInput		= tmpStats[i][y];
										tmpStats[i][y]	= tmpStats[j][y];
										tmpStats[j][y]	= userInput;
									}
									//Get a total of the top three dice and place in final position
									for(int k = 0; k < 3; k++)
										tmpStats[4][y] += tmpStats[k][y];
						}
						
						do
						{
							cout << " Rolling Stats\n";
							v.SetTxtClr(cSubWhite);
							cout << " Seven numbers have been generated and listed below.\n"
								 << " Pick the numbers to assign in order of the stats:\n"
								 << " Str, Dex, Con, Int, Wis, Cha and Com,\n"
								 << " choose the number you want to fill that Stat.\n\n"
								 << " Note: You get to roll three times. If you attempt to\n"
								 << " roll a 4th time, character generation will be reset.\n\n"
								 << " If you decide to reroll, you will lose the current rolls.\n\n";
							
							cout << " Attributes:\n";
							cout << " Str: "; if(tmpChar.GetSStr() < 10) cout << "0"; cout << tmpChar.GetSStr();
							
							if(tmpChar.GetStrE() > 0)
							{
								cout << " / ";
								if(tmpChar.GetStrE() < 10)	cout << "0" << tmpChar.GetStrE();
								else						cout << tmpChar.GetStrE();
							}
							cout << "\n";
							cout << " Dex: "; if(tmpChar.GetSDex() < 10) cout << "0"; cout << tmpChar.GetSDex() << "\n";
							cout << " Con: "; if(tmpChar.GetSCon() < 10) cout << "0"; cout << tmpChar.GetSCon() << "\n";
							cout << " Int: "; if(tmpChar.GetSInt() < 10) cout << "0"; cout << tmpChar.GetSInt() << "\n";
							cout << " Wis: "; if(tmpChar.GetSWis() < 10) cout << "0"; cout << tmpChar.GetSWis() << "\n";
							cout << " Cha: "; if(tmpChar.GetSCha() < 10) cout << "0"; cout << tmpChar.GetSCha() << "\n";
							cout << " Com: "; if(tmpChar.GetSCom() < 10) cout << "0"; cout << tmpChar.GetSCom() << "\n\n";

							cout << " Rolls:\n";							
							for(tmpInt = 0; tmpInt < 7; tmpInt++)
							{
								v.SetTxtClr(cGreen);	cout << " " << tmpInt << ")";
								v.SetTxtClr(cSubWhite);
								for(userInput = 0; userInput < 4; userInput++)
									cout << " " << tmpStats[userInput][tmpInt];
								v.SetTxtClr(cGreen); cout << " " << tmpStats[userInput][tmpInt] << "\n";
							}
							
							v.SetTxtClr(cGreen); cout << " " << tmpInt << ")"; v.SetTxtClr(cSubWhite); cout << " Return";
							userInput = GSUI();
							
							if(userInput < 0 || userInput > 7) OutOfRangeMsg();
							else
							{
								if(userInput == 7)
								{
									tmpChar.ResetStartingStats();
									if(numStatRolls <= 0)
									{
										tmpChar.Reset(); numStatRolls = 3; classPicked = false;
										cout << "\n You've exceeded the number of rolls allowed for"
											 << "\n the avatar being generated. You must start over.\n\n ";
										system("pause");
									}
								}
								else
								{
									if(tmpStats[4][userInput] > 0)
									{
										i = tmpStats[4][userInput];
										if		(tmpChar.GetSStr() == 0)
										{
											tmpChar.SetSStr(tmpStats[4][userInput]);
											tmpStats[4][userInput] = 0;
                                            
											if(tmpChar.GetSStr() == 18)
											{
												//Setting Exceptional Str
												if((tmpChar.GetClass(0) == cCustom && tmpChar.GetOptionalAbil(FighterExStr) == true) || 
													tmpChar.GetClass(0) == cWarrior)
												{
													i = rand() % 100;
													if(i < 1) i = 100;
													tmpChar.SetStrE(i);
												}
											}
										}
										else if	(tmpChar.GetSDex() == 0) { tmpChar.SetSDex(i); tmpStats[4][userInput] = 0; }
										else if	(tmpChar.GetSCon() == 0) { tmpChar.SetSCon(i); tmpStats[4][userInput] = 0; }
										else if	(tmpChar.GetSInt() == 0) { tmpChar.SetSInt(i); tmpStats[4][userInput] = 0; }
										else if	(tmpChar.GetSWis() == 0) { tmpChar.SetSWis(i); tmpStats[4][userInput] = 0; }
										else if	(tmpChar.GetSCha() == 0) { tmpChar.SetSCha(i); tmpStats[4][userInput] = 0; }
										else if	(tmpChar.GetSCom() == 0) { tmpChar.SetSCom(i); tmpStats[4][userInput] = 0; }
										else							 { cout << "\n All stats are filled\n"; system("pause"); }
									}
									else
									{
										cout << "\n That number has been utilized\n";
										system("pause");
									}
									userInput = -1;//reset value
								}
							}
							
							//Clear and reset title so we don't have to do a special fax paus with the code
							system("cls");
							v.SetTxtClr(cGreen); cout << "\n Character Creation\n\n";
						}while((userInput < 0 || userInput > 7) &&
							   (tmpChar.GetSStr() == 0 || tmpChar.GetSDex() == 0 || tmpChar.GetSCon() == 0 || 
							    tmpChar.GetSInt() == 0 || tmpChar.GetSWis() == 0 || tmpChar.GetSCha() == 0 ||
								tmpChar.GetSCom() == 0) && userInput != 7);
						tmpChar.CheckStatsByRace();
					}
				}
				else
				{
					//By this point, they have probably assigned stats on their last allowed
					//roll and decided they didn't like it. So they decided to reroll...
					tmpChar.Reset(); numStatRolls = 3; classPicked = false;
					cout << "\n You've exceeded the number of rolls allowed for"
						 << "\n the avatar being generated. You must start over.\n\n ";
					system("pause");
				}
				break;
			case avPickWeapons:
				if(classPicked == true)
				{
					//Reset has to be before Assign because Reset
					//zero's out how many slots the avatar can have
					tmpChar.ResetWPs();
					tmpChar.AssignNumWeaPros();
					do
					{
						system("cls");
						v.SetTxtClr(cGreen); cout << "\n Character Creation\n\n";
						v.SetTxtClr(cSubWhite);

						cout << " Assign Weapon Proficiency Slots\n\n"
							 << " Pick proficiencies allowed for your class from the list below.\n\n"
							 << " Note: Single-class Warriors can pick a skill twice to specialize.\n\n";

						//Display weapon skills...
						for(tmpInt = 0; tmpInt < MAX_WEAPONPRO; tmpInt += 2)
						{
							//Not Multi-class, so we can look at
							//the 0-index to get which class is picked.
							if(tmpChar.GetStatus(asMultiClass) == false)
							{
								//Is a custom class...have to check combat value
								if(tmpChar.GetClass(0) == cCustom)
								{
									if(WeaponsAllowed[tmpInt][tmpChar.GetCustomCmbtValue()] == true)	v.SetTxtClr(cGreen);
									else																v.SetTxtClr(cGrey);
								}
								//Standard classes can be easily indexed in array
								else
								{
									if(WeaponsAllowed[tmpInt][tmpChar.GetClass(0)] == true)				v.SetTxtClr(cGreen);
									else																v.SetTxtClr(cGrey);
								}
							}
							//Is Multi-class, so we have to look at every
							//class to ensure there's no restrictions
							else
							{
								//Loop through the classes...
								for(i = 0; i < tmpChar.GetNumClass(); i++)
								{
									//Make sure that we're not going to over-index...
									if(tmpChar.GetClass(i) < cMAX_CLASSES)
									{
										//Is the class a Priest?
										if(tmpChar.GetClass(i) == cPriest)
										{
											//If it is, being in this if-statement will
											//trump the else-statement because Clerics
											//have a governing 'body' over their selection
											if(WeaponsAllowed[tmpInt][cPriest] == false)
											{
												v.SetTxtClr(cGrey);
												break;
											}
											else v.SetTxtClr(cGreen);
										}
										//No a Cleric...classes allowed to mix weapon proficiencies...
										else
										{
											if(WeaponsAllowed[tmpInt][tmpChar.GetClass(i)] == false)
											{
												v.SetTxtClr(cGrey);
												break;
											}
											else v.SetTxtClr(cGreen);
										}
									}
								}
							}
							//...(left column)							
							//Print out the wp index number...
							cout << setw(8) << tmpInt << ") ";
							//Setting text color in case the following tests fail...
							v.SetTxtClr(cSubWhite);
							//Change color according to 1 point assigned, or two...
							if(tmpChar.GetWPSlotCost(tmpInt) > 0)
							{
								if(tmpChar.GetWPSlotCost(tmpInt) == 1)	v.SetTxtClr(cYellow);
								else									v.SetTxtClr(cGrey);
							}

							//Extract and print skill name...
							tmpStr = tmpChar.GetWProName(tmpInt);
							cout << tmpStr;
							//...(right column)
							if(tmpInt + 1 < MAX_WEAPONPRO)
							{
								if(tmpChar.GetStatus(asMultiClass) == false)
								{
									//Is a custom class...have to check combat value
									if(tmpChar.GetClass(0) == cCustom)
									{
										if(WeaponsAllowed[tmpInt + 1][tmpChar.GetCustomCmbtValue()] == true)
											v.SetTxtClr(cGreen);
										else
											v.SetTxtClr(cGrey);
									}
									//Standard classes can be easily indexed in array
									else
									{
										if(WeaponsAllowed[tmpInt + 1][tmpChar.GetClass(0)] == true)
											v.SetTxtClr(cGreen);
										else
											v.SetTxtClr(cGrey);
									}
								}
								//Is Multi-class, so we have to look at every
								//class to ensure there's no restrictions
								else
								{
									//Loop through the classes...
									for(i = 0; i < tmpChar.GetNumClass(); i++)
									{
										//Make sure that we're not going to over-index...
										if(tmpChar.GetClass(i) < cMAX_CLASSES)
										{
											//Is the class a Priest?
											if(tmpChar.GetClass(i) == cPriest)
											{
												//If it is, being in this if-statement will
												//trump the else-statement because Clerics
												//have a governing 'body' over their selection
												if(WeaponsAllowed[tmpInt + 1][cPriest] == false)
												{
													v.SetTxtClr(cGrey);
													break;
												}
												else v.SetTxtClr(cGreen);
											}
											//No a Cleric...classes allowed to mix weapon proficiencies...
											else
											{
												if(WeaponsAllowed[tmpInt + 1][tmpChar.GetClass(i)] == false)
												{
													v.SetTxtClr(cGrey);
													break;
												}
												else v.SetTxtClr(cGreen);
											}
										}
									}
								}

								cout << setw(30 - int(tmpStr.length())) << tmpInt + 1 << ") ";

								//Setting text color in case the following tests fail...
								v.SetTxtClr(cSubWhite);
								
								//Change color according to 1 point assigned, or two...
								if(tmpChar.GetWPSlotCost(tmpInt + 1) > 0)
								{
									if(tmpChar.GetWPSlotCost(tmpInt + 1) == 1)	v.SetTxtClr(cYellow);
									else										v.SetTxtClr(cGrey);
								}

								tmpStr = tmpChar.GetWProName(tmpInt + 1);
								cout << tmpStr;
							}
							cout << "\n";
						}

						v.SetTxtClr(cGreen); cout << "\n -2) "; v.SetTxtClr(cSubWhite); cout << "Reset Skills";
						v.SetTxtClr(cGreen); cout << "\n -1) "; v.SetTxtClr(cSubWhite); cout << "Finish\n\n";

						//Display number of skills remaining...
						cout << " Skill allocation: " << tmpChar.GetNumWPsUsed() << " / " << tmpChar.GetNumMaxWPslots() << "\n";

						//Get user's WP choice...
						userInput = GSUI();

						//Make sure user picked an allowed value...
						if		(userInput >= 0 && userInput < MAX_WEAPONPRO)
						{
							//Validate proper WP selection according to class
							if(tmpChar.GetStatus(asMultiClass) == false)
							{
								if		(tmpChar.GetClass(0) == cWarrior || tmpChar.GetClass(0) == c0LvlHuman)
								{
									found = true;
								}
								else if	(tmpChar.GetClass(0) == cPriest)
								{
									//Set menu green/grey according to allowance
									switch(userInput)
									{
									case wpClub: case wpFlailFoot: case wpFlailHorse: case wpLucernHammer:
									case wpMaceFoot: case wpMaceHorse: case wpMorningStar: case wpQuarterstaff:
									case wpSling: case wpStaffSling: case wpWarhammer:
										found = true;
										break;
									default: break;
									}
								}
								else if	(tmpChar.GetClass(0) == cRogue)
								{
									switch(userInput)
									{
									case wpBowShort: case wpClub: case wpCrossbowHand: case wpDagger: 
									case wpDirk: case wpDart: case wpKnife: case wpMancatcher: 
									case wpQuarterstaff: case wpSling: case wpStaffSling: case wpSwordBroad: 
									case wpSwordLong: case wpSwordShort: case wpWhip: 
										found = true;
										break;
									default: break;
									}
								}
								else if	(tmpChar.GetClass(0) == cWizard)
								{
									switch(userInput)
									{
									case wpDagger: case wpDirk: case wpDart:
									case wpKnife: case wpQuarterstaff: case wpSling:
										found = true;
										break;
									default: break;
									}
								}
								else if	(tmpChar.GetClass(0) == cCustom)
								{
									switch(tmpChar.GetCustomCmbtValue())
									{
									case cWarrior:
									case c0LvlHuman:
										found = true;
										break;
									case cPriest:
										switch(userInput)
										{
										case wpClub: case wpFlailFoot: case wpFlailHorse: case wpLucernHammer:
										case wpMaceFoot: case wpMaceHorse: case wpMorningStar: case wpQuarterstaff:
										case wpSling: case wpStaffSling: case wpWarhammer:
											found = true;
											break;
										default: break;
										}
										break;
									case cRogue:
										switch(userInput)
										{
										case wpBowShort: case wpClub: case wpCrossbowHand: case wpDagger: 
										case wpDirk: case wpDart: case wpKnife: case wpMancatcher: 
										case wpQuarterstaff: case wpSling: case wpStaffSling: case wpSwordBroad: 
										case wpSwordLong: case wpSwordShort: case wpWhip: 
											found = true;
											break;
										default: break;
										}
										break;
									case cWizard:
										switch(userInput)
										{
										case wpDagger: case wpDirk: case wpDart:
										case wpKnife: case wpQuarterstaff: case wpSling:
											found = true;
											break;
										default: break;
										}
										break;
									}
								}
							}
							//Multi-class (setting true/false for each class)
							else
							{
								for(i = 0; i < tmpChar.GetNumClass(); i++)
								{
									//Setting false before tests...
									weaponVsClass[i] = false;

									switch(tmpChar.GetClass(i))
									{
									case cPriest:
										switch(userInput)
										{
										case wpClub: case wpFlailFoot: case wpFlailHorse: case wpLucernHammer:
										case wpMaceFoot: case wpMaceHorse: case wpMorningStar: case wpQuarterstaff:
										case wpSling: case wpStaffSling: case wpWarhammer:
											weaponVsClass[i]	= true;
											break;
										default:
											weaponVsClass[i]	= false;
											break;
										}
										break;
									case cCustom:
										switch(tmpChar.GetCustomCmbtValue())
										{
										case cPriest:
											switch(userInput)
											{
											case wpClub: case wpFlailFoot: case wpFlailHorse: case wpLucernHammer:
											case wpMaceFoot: case wpMaceHorse: case wpMorningStar: case wpQuarterstaff:
											case wpSling: case wpStaffSling: case wpWarhammer:
												weaponVsClass[i]	= true;
												break;
											default:
												weaponVsClass[i]	= false;
											}
											break;
										}
										break;
									default:
										weaponVsClass[i] = true;
										break;
									}
								}

								found = true;
								
								for(i = 0; i < tmpChar.GetNumClass(); i++)
									if(weaponVsClass[i] == false)
									{
										found = false;
										break;
									}
							}

							//This if-test checks to make sure that the user
							//can select that particular weapon for the class
							if(found == true)
							{
								//Only warriors can take the same skill more than once...
								if((tmpChar.GetClass(0) == cWarrior && tmpChar.GetStatus(asMultiClass) == false) ||
								   (tmpChar.GetClass(0) == cCustom  && tmpChar.GetCustomCmbtValue() == cWarrior))
								{
									//Skill already Specialized
									if(tmpChar.GetWPSlotCost(userInput) > 1)
									{
										cout << "\n That skill is already specialized.\n\n ";
										system("pause");
										found = true;
									}
									else found = false;
								}
								else
								{
									if(tmpChar.GetWPSlotCost(userInput) > 0)
									{
										cout << " Only single-class Warriors can specialize.\n\n ";
										system("pause");
										found = true;
									}
									else found = false;
								}

								//false allows player to assign proficiency...
								if(found == false)
									tmpChar.AssignWeaponSlot(userInput, tmpChar.GetWPSlotCost(userInput) + 1);
							}
							else
							{
								cout << "\n\n That weapon proficiency is not allowed.\n\n ";
								system("pause");
							}
						}
						else if (userInput == -2)
						{
							tmpChar.ResetWPs();
							tmpChar.AssignNumWeaPros();
						}
						else if (userInput == -1) { }//empty block...
						else OutOfRangeMsg();
					}while(userInput != -1);
				}
				else PickClassMsg("a Class");
				break;
			case avPickNWPs:
				if(classPicked == true)
				{
					if(tmpChar.GetSInt() > 0)
					{
						//Reset has to be before Assign because Reset
						//zero's out how many slots the avatar can have
						tmpChar.ResetNWPs();
						tmpChar.AssignNumNWPs();
						do
						{
							system("cls");
							v.SetTxtClr(cGreen); cout << "\n Character Creation\n\n";
							v.SetTxtClr(cSubWhite);
							cout << " Assign Non-Weapon Proficiency Slots\n\n"
								 << " Pick proficiencies from the list below.\n\n"
								 << " Note: Pick a skill multiple times to specialize.\n\n";
							//Display NWPs...
							for(tmpInt = 0; tmpInt < MAX_NWPs; tmpInt += 3)
							{
								v.SetTxtClr(cGreen);
								//Want to get the number off the left side of the screen...
								if		(tmpInt < 10)	cout << "   ";
								else if	(tmpInt < 100)	cout << "  ";
								else					cout << " ";
								cout << tmpInt << ") ";
								v.SetTxtClr(cSubWhite);
								//Left column...
								tmpStr = tmpChar.GetNWPStr(tmpInt);
								if(tmpChar.GetNWPnumSlotsAll(tmpInt) > 0)
								{
									sprintf(tmpChrStr, "%d", tmpChar.GetNWPnumSlotsAll(tmpInt));
									tmpStr += " ";
									tmpStr += tmpChrStr;
									//Set text color for easy reading...
									v.SetTxtClr(cYellow);
								}
								cout << tmpStr;
								//Middle column....
								if(tmpInt + 1	< MAX_NWPs)
								{
									v.SetTxtClr(cGreen);
									cout << setw(24 - int(tmpStr.length())) << tmpInt + 1 << ") ";

									v.SetTxtClr(cSubWhite);
									tmpStr = tmpChar.GetNWPStr(tmpInt + 1);

									if(tmpChar.GetNWPnumSlotsAll(tmpInt + 1) > 0)
									{
										sprintf(tmpChrStr, "%d", tmpChar.GetNWPnumSlotsAll(tmpInt + 1));
										tmpStr += " ";
										tmpStr += tmpChrStr;
										//Set text color for easy reading...
										v.SetTxtClr(cYellow);
									}

									cout << tmpStr;
								}
								//Right column....
								if(tmpInt + 2	< MAX_NWPs)
								{
									v.SetTxtClr(cGreen);
									cout << setw(26 - int(tmpStr.length())) << tmpInt + 2 << ") ";
									v.SetTxtClr(cSubWhite);
									tmpStr = tmpChar.GetNWPStr(tmpInt + 2);
									if(tmpChar.GetNWPnumSlotsAll(tmpInt + 2) > 0)
									{
										sprintf(tmpChrStr, "%d", tmpChar.GetNWPnumSlotsAll(tmpInt + 2));
										tmpStr += " ";
										tmpStr += tmpChrStr;
										//Set text color for easy reading...
										v.SetTxtClr(cYellow);
									}
									cout << tmpStr;
								}
								cout << "\n";
							}
							v.SetTxtClr(cGreen); cout << "\n -2) "; v.SetTxtClr(cSubWhite); cout << "Reset Skills";
							v.SetTxtClr(cGreen); cout << "\n -1) "; v.SetTxtClr(cSubWhite); cout << "Finish\n\n";
							//Display number of skills remaining...
							cout << " Skill allocation: " << tmpChar.GetNumNWPSAllocated() << " / " << tmpChar.GetNumMaxNWPslots() << "\n";
							//Get user's WP choice...
							userInput = GSUI();
							
							//Make sure user picked an allowed value...
							if		(userInput >= 0 && userInput < MAX_NWPs)
							{
								tmpChar.AssignNWPSlot(userInput, tmpChar.GetNWPnumSlotsAll(userInput) + 1);
							}
							else if (userInput == -2)
							{
								//Reset has to be before Assign because Reset
								//zero's out how many slots the avatar can have
								tmpChar.ResetNWPs();
								tmpChar.AssignNumNWPs();
							}						
						}while(userInput != -1);
					}
					else
					{
						cout << "\n You must rolls stats before assigning NWPs.\n\n ";
						system("pause");
					}
				}
				else PickClassMsg("a Class");
				break;
			case avSave:
				cout << " It is required that all Weapon and Non-weapon proficiency\n"
					 << " slots have been used before saving your character. Proceed? (y / n)\n\n ";
				cin >> tmpStr;
				//Used as a test to see if there was an error while checking the avatar
				found = false;
				if(tmpStr == "y" || tmpStr == "Y")
				{
					tmpStr = tmpChar.GetFName();
					if(tmpStr != "First")
					{
						tmpStr = tmpChar.GetLName();
						if(tmpStr != "Last")
						{
							if(tmpChar.GetRace() < MAX_pcRACES)
							{
								if(tmpChar.GetClass(0) != cMAX_CLASSES)
								{
									if(tmpChar.GetSStr() > 0)
									{
										if(tmpChar.GetNumMaxWPslots() == tmpChar.GetNumWPsUsed())
										{
											if(tmpChar.GetNumMaxNWPslots() == tmpChar.GetNumNWPSAllocated())
											{
												cout << "\n Character complete, proceeding to save...\n\n ";
											}
											else
											{
												tmpStr = "\n Non-weapon Proficiencies";
												found = true;
											}
										}
										else
										{
											tmpStr = "\n Weapon Proficiencies";
											found = true;
										}
									}
									else
									{
										tmpStr = "\n Attributes";
										found = true;
									}
								}
								else
								{
									tmpStr = "\n Class(s)";
									found = true;
								}
							}
							else
							{
								tmpStr = "\n Race";
								found = true;
							}
						}
						else
						{
							tmpStr = "\n Last Name";
							found = true;
						}
					}
					else
					{
						tmpStr = "\n First Name";
						found = true;
					}
					if(found == true)
					{
						tmpStr += " needs to be set...\n\n ";
						cout << tmpStr;
						system("pause");
					}
					else
					{
						tmpInt = -1;
						//First, find for an empty slot...
						for(i = 0; i < maxNumAvatars; i++)
						{
							if(AvailAvatarNames[i] == "empty slot")
							{
								tmpInt = i;
								break;
							}
						}
						if(tmpInt >= 0 && tmpInt < maxNumAvatars)
						{
							tmpStr = tmpChar.GetFName();
							tmpStr += " ";
							tmpStr += tmpChar.GetLName();

							//Set the dataIndex of the avatar...
							tmpChar.SetDataIndex(tmpInt);

							//Assign the character's name to the Roster
							AvailAvatarNames[tmpInt] = tmpStr;

							//We move the file index into position
							InOutData.seekg(tmpInt * sizeof(Avatar));
							//We write the amount of data back to the file
							InOutData.write(reinterpret_cast<char *>(&tmpChar), sizeof(Avatar));

							cout << "\n Character saved...\n\n ";
							system("pause");
						}
						else
						{
							cout << "\n All character slots are full."
								 << "\n You'll need to empty a slot (delete a character)\n\n ";
							system("pause");

							//Resetting so we don't return to main() by accident...
							userInput = -1;
						}
					}
				}
				break;
			case avQuit:
				break;
			}
		}while(userInput != avQuit);
	}
	else
	{
		v.SetTxtClr(cRed);
		system("cls");
		cout << "\n Failed to open Avatars.dat\n\n";
		system("pause");
	}

	InOutData.close();
	//This forces the game phase back into mainMenu
	return gpMainMenu;
}
int displayClassAllow(ConLib v)
{
	string tmpString;
	Avatar tmpChar;

	cout << "\n";
	cout << setw(63) << "0-Lvl   Warrior Priest  Rogue   Mage    Custom\n";
	for(int y = 0; y < MAX_pcRACES; y++)
	{
		v.SetTxtClr(cSubWhite);
		cout << " " << tmpChar.GetRaceStr(y);
		switch(y)
		{
		case rDwarf:		cout << setw(4) << " ";		break;
		case rElf:			cout << setw(5) << " ";		break;
		case rGnome:		cout << setw(3) << " ";		break;
		case rHalfElf:		cout << setw(2) << " ";		break;
		case rHalfling:		cout << setw(2) << " ";		break;
		case rHuman:		cout << setw(3) << " ";		break;
		}

		for(int x = 0; x < cMAX_CLASSES; x++)
		{
			if(ClassesAllowed[x][y] == true)
			{
				v.SetTxtClr(cGreen);
				tmpString = "Yes";
			}
			else
			{
				v.SetTxtClr(cRed);
				tmpString = "No";
			}

			cout << "\t" << tmpString;
		}
		cout << "\n";
	}
	
	v.SetTxtClr(cSubWhite); cout << "\n "; system("pause");

	return gpMainMenu;
}
bool customClass(ConLib v, Avatar &Av)
{
	int user = 0;
	
	cout << setprecision(2) << fixed;

	if(Av.GetRace() != rHuman) Av.SetCmbtValue(cmbtRace, 1.0);

	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		v.SetTxtClr(cGreen); cout << "  0) "; v.SetTxtClr(cSubWhite); cout << "Change Races Allowed     : " << setw(5) << Av.GetCmbtValue(cmbtRace);
		cout << " (";
		if(Av.GetCmbtValue(cmbtRace) == 0) cout << "Human";
		else cout << "Other";
		cout << ")\n";
		v.SetTxtClr(cGreen); cout << "  1) "; v.SetTxtClr(cSubWhite); cout << "Change Combat Rating     : " << setw(5) << Av.GetCmbtValue(cmbtCombatValue);

		cout << " (";
		switch(int(Av.GetCmbtValue(cmbtCombatValue)))
		{
		case -2:	cout << "0-lvl Fighter";	break;
		case -1:	cout << "Wizard";			break;
		case 0:		cout << "Rogue";			break;
		case 1:		cout << "Priest";			break;
		case 2:		cout << "Warrior";			break;
		case 3:		cout << "Monster";			break;
		default: cout << "Erorr";
		}
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  2) "; v.SetTxtClr(cSubWhite); cout << "Change Saving Throws     : " << setw(5) << Av.GetCmbtValue(cmbtSaveValue);
		cout << " (";
		cout << Av.GetClassNam(Av.GetSaveAsClass());
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  3) "; v.SetTxtClr(cSubWhite); cout << "Change Hit Die value     : " << setw(5) << Av.GetCmbtValue(cmbtHDLevel);
		cout << " (";
		if		(Av.GetCmbtValue(cmbtHDLevel) == 0.00) cout << "1d3";
		else if	(Av.GetCmbtValue(cmbtHDLevel) == 0.50) cout << "1d4";
		else if (Av.GetCmbtValue(cmbtHDLevel) == 0.75) cout << "1d6";
		else if (Av.GetCmbtValue(cmbtHDLevel) == 1.00) cout << "1d8";
		else if (Av.GetCmbtValue(cmbtHDLevel) == 2.00) cout << "1d10";
		else if (Av.GetCmbtValue(cmbtHDLevel) == 4.00) cout << "1d12";
		else cout << "HD Error";
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  4) "; v.SetTxtClr(cSubWhite); cout << "Change Armor allowed     : " << setw(5) << Av.GetCmbtValue(cmbtArmorAllowed);
		cout << " (";
		if		(Av.GetCmbtValue(cmbtArmorAllowed) == -1.0) cout << "None";
		else if (Av.GetCmbtValue(cmbtArmorAllowed) == -0.5) cout << "Limited";
		else if (Av.GetCmbtValue(cmbtArmorAllowed) == 0.0)  cout << "All";
		else cout << "Armor Error";
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  5) "; v.SetTxtClr(cSubWhite); cout << "Change Weapons allowed   : " << setw(5) << Av.GetCmbtValue(cmbtWeaponsAllowed);
		cout << " (";
		if		(Av.GetCmbtValue(cmbtWeaponsAllowed) == -1.5) cout << "Limited";
		else if (Av.GetCmbtValue(cmbtWeaponsAllowed) == -1.0) cout << "One-class";
		else if (Av.GetCmbtValue(cmbtWeaponsAllowed) == 0.0)  cout << "All";
		else cout << "Weapons Error";
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  6) "; v.SetTxtClr(cSubWhite); cout << "Change hp above 9th level: " << setw(5) << Av.GetCmbtValue(cmbtHPAfter9th);
		cout << " (";
		if		(Av.GetCmbtValue(cmbtHPAfter9th) == 0.0) cout << "+0";
		else if (Av.GetCmbtValue(cmbtHPAfter9th) == 0.5) cout << "+1";
		else if (Av.GetCmbtValue(cmbtHPAfter9th) == 1.0) cout << "+2";
		else if (Av.GetCmbtValue(cmbtHPAfter9th) == 2.0) cout << "+3";
		else cout << "Hp Bonus Error";
		cout << ")\n";

		v.SetTxtClr(cGreen); cout << "  7) "; v.SetTxtClr(cSubWhite); cout << "Change Optional Skills\n"; 
		v.SetTxtClr(cGreen); cout << "  8) "; v.SetTxtClr(cSubWhite); cout << "Change Restrictions\n";
		v.SetTxtClr(cGreen); cout << "  9) "; v.SetTxtClr(cSubWhite); cout << "Return without using custom\n";
		v.SetTxtClr(cGreen); cout << " 10) "; v.SetTxtClr(cSubWhite); cout << "Return using this class\n\n";
	
		cout << " Total of Multiplier: " << setw(15) << Av.GetTotalMult() << "\n\n";
		
		cout << "  2nd level: " << setw(24) << Av.GetTotalMult() * 200		<< "\n"
			 << "  3rd level: " << setw(24) << Av.GetTotalMult() * 400		<< "\n"
			 << "  4th level: " << setw(24) << Av.GetTotalMult() * 800		<< "\n"
			 << "  5th level: " << setw(24) << Av.GetTotalMult() * 1600		<< "\n"
			 << "  6th level: " << setw(24) << Av.GetTotalMult() * 3200		<< "\n"
			 << "  7th level: " << setw(24) << Av.GetTotalMult() * 6400		<< "\n"
			 << "  8th level: " << setw(24) << Av.GetTotalMult() * 12800	<< "\n"
			 << "  9th level: " << setw(24) << Av.GetTotalMult() * 25600	<< "\n"
			 << " 10th+ add : " << setw(24) << Av.GetTotalMult() * 25600	<< "\n\n";
		
		cout << " Enter menu number:";
		user = GSUI();
		
		switch(user)
		{
		case 0:	getRace			(v, Av);	break;
		case 1:	getCmbtValue	(v, Av);	break;
		case 2:	getSaveValue	(v, Av);	break;
		case 3:	getHDLevel		(v, Av);	break;
		case 4:	getArmor		(v, Av);	break;
		case 5:	getWeapons		(v, Av);	break;
		case 6:	getHpBonus		(v, Av);	break;
		case 7:	getOptionals	(v, Av);	break;
		case 8:	getRestrictions	(v, Av);	break;
		default:							break;
		}
	}while(user != 9 && user != 10);

	if(user == 9) return false;

	//This is choice '10'...
	//Tests to make sure that the person has a minimum requirement fulfilled
	//Needs additional tests to make sure that certain values are filled (cmbt, etc)
	if(Av.GetTotalMult() > 0) return true;
	else
	{
		cout << "\n Custom Class xp must have a modifier greater than 0.0 to be playable\n ";
		system("pause");
		return false;
	}
}
void getRace(ConLib v, Avatar &Av)
{
	char user = ' ';
	system("cls");
	
	v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
	v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

	cout << "\n Pick which race the class will be restricted to...\n";
	v.SetTxtClr(cGreen); cout << " h)"; v.SetTxtClr(cSubWhite); cout << " Humans only            + 0\n";
	v.SetTxtClr(cGreen); cout << " o)"; v.SetTxtClr(cSubWhite); cout << " Other                  + 1\n\n";

	cout << " Note: Racial restrictions of which Classes allowed\n"
		 << " still apply if you're planning to cast spells\n\n";

	user = getch();

	if (user == 'o' || user == 'O') Av.SetCmbtValue(cmbtRace, 1.0);
	else
	{
		if(Av.GetRace() != rHuman)
		{
			cout << "\n Non-humans have to have 'other' selected.\n ";
			system("pause");
		}
		else
		{
			Av.SetCmbtValue(cmbtRace, 0.0);
			Av.SetRestriction(NonHuman9, false);
			Av.SetRestriction(NonHuman12, false);
		}
	}
}
void getCmbtValue(ConLib v, Avatar &Av)
{
	char user = ' ';
	do
	{
		system("cls");
		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		cout << " Pick which you wish the class to attack as\n\n";
		v.SetTxtClr(cGreen); cout << " (h)"; v.SetTxtClr(cSubWhite); cout << " 0-Level Human - 2\n";
		v.SetTxtClr(cGreen); cout << " (w)"; v.SetTxtClr(cSubWhite); cout << " Wizard        - 1\n";
		v.SetTxtClr(cGreen); cout << " (r)"; v.SetTxtClr(cSubWhite); cout << " Rogue         + 0\n";
		v.SetTxtClr(cGreen); cout << " (p)"; v.SetTxtClr(cSubWhite); cout << " Priest        + 1\n";
		v.SetTxtClr(cGreen); cout << " (a)"; v.SetTxtClr(cSubWhite); cout << " Warrior       + 2\n";
		v.SetTxtClr(cGreen); cout << " (m)"; v.SetTxtClr(cSubWhite); cout << " Monster       + 3\n\n";
		cout << " Note: 0-level human category never gains in combat skills\n\n";

		user = getch();

		switch(user)
		{
		case 'h': case 'H': Av.SetCmbtValue(cmbtCombatValue, -2);	break;
		case 'w': case 'W':
			if(Av.GetRace() == rDwarf || Av.GetRace() == rHalfling) DwarfHalfingMages();
			else Av.SetCmbtValue(cmbtCombatValue, -1);
			break;
		case 'r': case 'R': Av.SetCmbtValue(cmbtCombatValue, 0);	break;
		case 'p': case 'P':
			if(Av.GetRace() == rGnome) GnomePriestError();
			else Av.SetCmbtValue(cmbtCombatValue, 1);
			break;
		case 'a': case 'A': Av.SetCmbtValue(cmbtCombatValue, 2);	break;
		case 'm': case 'M':	Av.SetCmbtValue(cmbtCombatValue, 3);	break;
		default:
			cout << "That was not an option - try again...\n";
			system("pause");
			break;
		}
	}
	while (user != 'h' && user != 'H' && user != 'w' && user != 'W' &&
	       user != 'r' && user != 'R' && user != 'p' && user != 'P' &&
		   user != 'a' && user != 'A' && user != 'm' && user != 'M');
}
void getSaveValue(ConLib v, Avatar &Av)
{
	int  iTmp = 0;
	char user = ' ';
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		cout << " Pick which class you want to have Saving Throws for...\n\n";
		v.SetTxtClr(cGreen); cout << " (h) "; v.SetTxtClr(cSubWhite); cout << " 0-level Human   -2\n";
		v.SetTxtClr(cGreen); cout << " (a) "; v.SetTxtClr(cSubWhite); cout << " Any other chart +0\n\n";

		cout << " (0-level humans never improve in saving throws)\n"
			 << " Any other takes on the Save Table of the combat value you chose\n"
			 << " (If you chose 0-lvl Human, then your saves will use the 0-level chart)\n\n";

		user = getch();

		switch(user)
		{
		case 'h': case 'H':
			Av.SetCmbtValue(cmbtSaveValue, -2.0);
			Av.SetSaveAsClass(c0LvlHuman);
			break;
		case 'a': case 'A':
			Av.SetCmbtValue(cmbtSaveValue, 0.0);
			do
			{
				cout << "\n Pick which category your Character will save as\n";
				for(int s = cWarrior; s < cCustom; s++)
				{
					v.SetTxtClr(cGreen);	cout << " " << s << ") ";
					v.SetTxtClr(cSubWhite);	cout << Av.GetClassNam(s) << "\n";
				}
				cout << " ";
				iTmp = GSUI();
				if(iTmp >= cWarrior && iTmp < cCustom) Av.SetSaveAsClass(iTmp);
			}while (iTmp < cWarrior || iTmp >= cCustom);
			break;
		default: cout << "That was not an option - try again...\n"; system("pause"); break;
		}
	} while (user != 'h' && user != 'H' && user != 'a' && user != 'A');
}
void getHDLevel(ConLib v, Avatar &Av)
{
	char user = ' ';
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";
		
		cout << " Pick which Hit Die you roll each level up to 9th...\n\n";
		v.SetTxtClr(cGreen); cout << " (3) "; v.SetTxtClr(cSubWhite); cout << "1d3    +0\n";
		v.SetTxtClr(cGreen); cout << " (4) "; v.SetTxtClr(cSubWhite); cout << "1d4    +0.5\n";
		v.SetTxtClr(cGreen); cout << " (6) "; v.SetTxtClr(cSubWhite); cout << "1d6    +0.75\n";
		v.SetTxtClr(cGreen); cout << " (8) "; v.SetTxtClr(cSubWhite); cout << "1d8    +1\n";
		v.SetTxtClr(cGreen); cout << " (1) "; v.SetTxtClr(cSubWhite); cout << "1d10   +2\n";
		v.SetTxtClr(cGreen); cout << " (2) "; v.SetTxtClr(cSubWhite); cout << "1d12   +4\n\n";

		cout << " Note: Standard Wizards and Rogues get to roll an extra die at 10th level.\n"
			 << " Using this system you're allowed a maximum of rolling for 9th level.\n\n";

		user = getch();

		switch(user)
		{
		case '3':	Av.SetCmbtValue(cmbtHDLevel, 0);	break;
		case '4':	Av.SetCmbtValue(cmbtHDLevel, 0.5);	break;
		case '6':	Av.SetCmbtValue(cmbtHDLevel, 0.75);	break;
		case '8':	Av.SetCmbtValue(cmbtHDLevel, 1.0);	break;
		case '1':	Av.SetCmbtValue(cmbtHDLevel, 2.0);	break;
		case '2':	Av.SetCmbtValue(cmbtHDLevel, 4.0);	break;
		default:
			cout << "That was not an option - try again...\n ";
			system("pause");
			break;
		}
	} while (user != '3' && user != '4' && user != '6' && user != '8' && user != '1' && user != '2');
}
void getArmor(ConLib v, Avatar &Av)
{
	char user = ' ';
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		cout << " Pick the amount of armor allowed to the class...\n\n";
		v.SetTxtClr(cGreen); cout << " (n) "; v.SetTxtClr(cSubWhite); cout << " No Armor        -1\n";
		v.SetTxtClr(cGreen); cout << " (l) "; v.SetTxtClr(cSubWhite); cout << " Limited AC      -0.5\n";
		v.SetTxtClr(cGreen); cout << " (a) "; v.SetTxtClr(cSubWhite); cout << " All             +0\n\n";

		cout << " (Limited AC means the character can not wear anything greater than AC 5)\n\n";

		user = getch();

		switch(user)
		{
		case 'n': case 'N':	Av.SetCmbtValue(cmbtArmorAllowed, -1.0); break;
		case 'l': case 'L':	Av.SetCmbtValue(cmbtArmorAllowed, -0.5); break;
		case 'a': case 'A':	Av.SetCmbtValue(cmbtArmorAllowed,  0.0); break;
		default:
            cout << "That is not an option...try again\n ";
			system("pause");
			break;
		}
	} while (user != 'n' && user != 'N' && user != 'l' && 
			 user != 'L' && user != 'a' && user != 'A');
}
void getWeapons(ConLib v, Avatar &Av)
{
	char user = ' ';
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		cout << " Pick the weapons the class can use...\n\n";
		v.SetTxtClr(cGreen); cout << " (l) "; v.SetTxtClr(cSubWhite); cout << " Limited*     -1.5\n";
		v.SetTxtClr(cGreen); cout << " (o) "; v.SetTxtClr(cSubWhite); cout << " One Class**  -1  \n";
		v.SetTxtClr(cGreen); cout << " (a) "; v.SetTxtClr(cSubWhite); cout << " All          +0  \n\n";

		cout << " *Limited is maximum of four weapons - that do no more than 1d8 in damage\n"
			 << " **One Class is limited to one catagory (slashing, piercing, bludgeoning).\n\n";

		user = getch();

		switch(user)
		{
		case 'l': case 'L': Av.SetCmbtValue(cmbtWeaponsAllowed, -1.5); break;
		case 'o': case 'O':	Av.SetCmbtValue(cmbtWeaponsAllowed, -1.0); break;
		case 'a': case 'A':	Av.SetCmbtValue(cmbtWeaponsAllowed,  0.0); break;
		default:
			cout << " That is not an option...try again\n\n ";
			system("pause");
			break;
		}
	} while (user != 'l' && user != 'L' && user != 'o' &&
			 user != 'O' && user != 'a' && user != 'A');
}
void getHpBonus(ConLib v, Avatar &Av)
{
	char user = ' ';
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n";
		v.SetTxtClr(cSubWhite); cout << " Custom Class Creation\n\n";

		cout << " Pick how many hit points the class will receive after 9th level\n\n";
		v.SetTxtClr(cGreen); cout << " 1) "; v.SetTxtClr(cSubWhite); cout << "+0 hp  +0.0\n";
		v.SetTxtClr(cGreen); cout << " 2) "; v.SetTxtClr(cSubWhite); cout << "+1 hp  +0.5\n";
		v.SetTxtClr(cGreen); cout << " 3) "; v.SetTxtClr(cSubWhite); cout << "+2 hp  +1.0\n";
		v.SetTxtClr(cGreen); cout << " 4) "; v.SetTxtClr(cSubWhite); cout << "+3 hp  +2.0\n\n";

		user = getch();

		switch(user)
		{
		case '1':	Av.SetCmbtValue(cmbtHPAfter9th, 0.0);	break;
		case '2':	Av.SetCmbtValue(cmbtHPAfter9th, 0.5);	break;
		case '3':	Av.SetCmbtValue(cmbtHPAfter9th, 1.0);	break;
		case '4':	Av.SetCmbtValue(cmbtHPAfter9th, 2.0);	break;
		default:
			cout << " That is not an option...try again\n\n ";
			break;
		}
	} while (user != '1' && user != '2' && user != '3' && user != '4');
}
void getOptionals(ConLib v, Avatar &Av)
{
	int user = 0;

	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n\n";
		v.SetTxtClr(cSubWhite); cout << " Optional Special Abilities\n\n";

		v.SetTxtClr(cGreen); cout << "  " << FighterCon			<< ") "; v.SetTxtClr(cSubWhite); cout << " Fighter Constitution            : " << Av.GetOptTF(FighterCon)			<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << FighterExStr		<< ") "; v.SetTxtClr(cSubWhite); cout << " Fighter Exceptional Strength    : " << Av.GetOptTF(FighterExStr)		<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << AnimalEmp			<< ") "; v.SetTxtClr(cSubWhite); cout << " Animal Empathy                  : " << Av.GetOptTF(AnimalEmp)			<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << BonusHitCreature	<< ") "; v.SetTxtClr(cSubWhite); cout << " Bonus to hit particular creature: " << Av.GetOptTF(BonusHitCreature)	<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << ReadLang			<< ") "; v.SetTxtClr(cSubWhite); cout << " Read Languages (Rogue)          : " << Av.GetOptTF(ReadLang)			<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << AuraOfPro			<< ") "; v.SetTxtClr(cSubWhite); cout << " Aura of Protection (Paladin)    : " << Av.GetOptTF(AuraOfPro)			<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << Backstab			<< ") "; v.SetTxtClr(cSubWhite); cout << " Backstab (Rogue)                : " << Av.GetOptTF(Backstab)			<< "\n";

		if(Av.GetRace() == rGnome) v.SetTxtClr(cGrey);
		else v.SetTxtClr(cGreen); 
		cout << "  " << CastAnyPriest << ") "; v.SetTxtClr(cSubWhite); cout << " Cast any Priest Spell           : " << Av.GetOptTF(CastAnyPriest)		<< "\n";

		v.SetTxtClr(cGreen); cout << "  " << ClimbWalls			<< ") "; v.SetTxtClr(cSubWhite); cout << " Climb Walls (Rogue)             : " << Av.GetOptTF(ClimbWalls)			<< "\n";
		v.SetTxtClr(cGreen); cout << "  " << FindRemove			<< ") "; v.SetTxtClr(cSubWhite); cout << " Find/Remove Traps (Rogue)       : " << Av.GetOptTF(FindRemove)			<< "\n";
		v.SetTxtClr(cGreen); cout << " "  << HealAsPal			<< ") "; v.SetTxtClr(cSubWhite); cout << " Heal as Paladin                 : " << Av.GetOptTF(HealAsPal)			<< "\n";
		v.SetTxtClr(cGreen); cout << " "  << HearNoise			<< ") "; v.SetTxtClr(cSubWhite); cout << " Hear noise (Rogue)              : " << Av.GetOptTF(HearNoise)			<< "\n";
		v.SetTxtClr(cGreen); cout << " "  << HideShadows		<< ") "; v.SetTxtClr(cSubWhite); cout << " Hide in Shadows (Rogue)         : " << Av.GetOptTF(HideShadows)		<< "\n";

		if(Av.GetRace() == rDwarf || Av.GetRace() == rHalfling) v.SetTxtClr(cGrey);
		else v.SetTxtClr(cGreen); 
		cout << " "  << AnyMageSpell << ") ";

		if(Av.GetRace() == rDwarf || Av.GetRace() == rHalfling) v.SetTxtClr(cGrey);
		else v.SetTxtClr(cSubWhite);
		cout << " Cast any Wizard spell           : " << Av.GetOptTF(AnyMageSpell)		<< "\n";

		v.SetTxtClr(cGreen); cout << " " << MoveSilent			<< ") "; v.SetTxtClr(cSubWhite); cout << " Move silently (Rogue)           : " << Av.GetOptTF(MoveSilent)			<< "\n";
		v.SetTxtClr(cGreen); cout << " " << OpenLocks			<< ") "; v.SetTxtClr(cSubWhite); cout << " Open Locks (Rogue)              : " << Av.GetOptTF(OpenLocks)			<< "\n";
		v.SetTxtClr(cGreen); cout << " " << PickPockets			<< ") "; v.SetTxtClr(cSubWhite); cout << " Pick pockets (Rogue)            : " << Av.GetOptTF(PickPockets)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << FollowAsWarrior		<< ") "; v.SetTxtClr(cSubWhite); cout << " Gain Followers as Warrior       : " << Av.GetOptTF(FollowAsWarrior)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << FollowAsCleric		<< ") "; v.SetTxtClr(cSubWhite); cout << " Gain Followers as Cleric        : " << Av.GetOptTF(FollowAsCleric)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << FollowAsThief		<< ") "; v.SetTxtClr(cSubWhite); cout << " Gain Followers as Rogue         : " << Av.GetOptTF(FollowAsThief)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << FollowAsMage		<< ") "; v.SetTxtClr(cSubWhite); cout << " Gain Followers as Mage          : " << Av.GetOptTF(FollowAsMage)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << -1 << ") "; v.SetTxtClr(cSubWhite); cout << " to return to previous screen\n\n";

		cout << " Enter the number to the left to add/remove the ability.";
		user = GSUI();

		if(user >= FighterCon && user < TOTAL_OptVals)
		{
			if(user >= FollowAsWarrior && user <= FollowAsMage)
			{
				for(int i = FollowAsWarrior; i <= FollowAsMage; i++)
					if(user != i) Av.SetOptionalAbil(i, false);
			}

			if((Av.GetRace() == rDwarf || Av.GetRace() == rHalfling) && user == AnyMageSpell)
				DwarfHalfingMages();
			else if (Av.GetRace() == rGnome && user == CastAnyPriest)
				GnomePriestError(); 
			else Av.ReverseOptional(user);
		}
	} while (user != -1);
}
void getRestrictions(ConLib v, Avatar &Av)
{
	int user = 0;
	do
	{
		system("cls");

		v.SetTxtClr(cGreen);    cout << "\n Character Creation\n\n";
		v.SetTxtClr(cSubWhite); cout << " Class Restrictions\n\n";

		v.SetTxtClr(cGreen); cout << " " << CantKeepMuch << ") "; v.SetTxtClr(cSubWhite); cout << "Can't keep more treasure than can carry: " << Av.GetResTF(CantKeepMuch)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << MustDonate   << ") "; v.SetTxtClr(cSubWhite); cout << "Must donate 10% of treasure            : " << Av.GetResTF(MustDonate)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << NonHuman9    << ") "; v.SetTxtClr(cSubWhite); cout << "Has non-human level of 9th             : " << Av.GetResTF(NonHuman9)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << NonHuman12   << ") "; v.SetTxtClr(cSubWhite); cout << "Has non-human level of 12th            : " << Av.GetResTF(NonHuman12)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << HasEthos     << ") "; v.SetTxtClr(cSubWhite); cout << "Has particular ethos to follow         : " << Av.GetResTF(HasEthos)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << Cant10Magic  << ") "; v.SetTxtClr(cSubWhite); cout << "Can't keep more than 10 magic items    : " << Av.GetResTF(Cant10Magic)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << Cant6Magic   << ") "; v.SetTxtClr(cSubWhite); cout << "Can't keep more than 6 magic items     : " << Av.GetResTF(Cant6Magic)	<< "\n";
		v.SetTxtClr(cGreen); cout << " " << CantClass    << ") "; v.SetTxtClr(cSubWhite); cout << "Can't associate with one class         : " << Av.GetResTF(CantClass)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << CantAlign    << ") "; v.SetTxtClr(cSubWhite); cout << "Can't associate with one alignment     : " << Av.GetResTF(CantAlign)		<< "\n";
		v.SetTxtClr(cGreen); cout << " " << -1  << ") "; v.SetTxtClr(cSubWhite); cout << "Quit this screen\n\n";
		
		cout << " Enter the number to the left to add/remove a restriction.\n\n";
		user = GSUI();

		if(user >= CantKeepMuch && user <= CantAlign)
		{
			if((user == NonHuman9 || user == NonHuman12) && Av.GetCmbtValue(cmbtRace) == 0)
			{
				system("cls");
				cout << " You can not take a level restriction without assigning a demi-human value.\n\n";
				system("pause");
			}
			else
			{
				Av.ReverseRestrict(user);

				switch(user)
				{
				case Cant10Magic:
					if(Av.GetRestriction(Cant10Magic) == true)
					{
						if(Av.GetRestriction(Cant6Magic) == true)
							Av.ReverseRestrict(Cant6Magic);
					}
					break;
				case Cant6Magic:
					if(Av.GetRestriction(Cant6Magic) == true)
					{
						if(Av.GetRestriction(Cant10Magic) == true)
							Av.ReverseRestrict(Cant10Magic);
					}
				default:
					break;
				}
			}
		}
	} while (user != -1);
}
int selectAvatar(ConLib v, string *roster)
{
	Avatar tmpAv;
	int Selection	= -2;
	int	tmpInt		= -1;
	
	fstream InOutData("Avatars.dat", ios::in | ios::out);

	system("cls"); v.SetTxtClr(cGreen); cout << "\n Character Selection\n\n";

	do
	{
		for(int i = 0; i < maxNumAvatars; i += 2)
		{
			v.SetTxtClr(cGreen);	cout << setw(3) << i << ") ";
			v.SetTxtClr(cSubWhite);	cout << roster[i];

			v.SetTxtClr(cGreen);	cout << setw(34 - int(roster[i].length())) << i + 1 << ") ";
			v.SetTxtClr(cSubWhite);	cout << roster[i + 1] << "\n";
		}
		v.SetTxtClr(cGreen);    cout << " -1) ";
		v.SetTxtClr(cSubWhite); cout << "Return without selecting...";

		cout << "\n\n Enter the index number of the Character that you want to use: ";
		Selection = GSUI();

		if(Selection >= 0 && Selection < maxNumAvatars)
		{
			//If an Avatar was already selected, write it back
			//to the file to ensure that it's data is saved.
			if(AvatarInUse != NULL)
			{
				tmpAv = AvatarInUse;
				tmpInt = tmpAv.GetDataIndex();
				InOutData.seekg(tmpInt * sizeof(Avatar));
				InOutData.write(reinterpret_cast<char *>(&tmpAv), sizeof(Avatar));
				delete AvatarInUse;
			}

			AvatarInUse = new Avatar();
			InOutData.seekg(Selection * sizeof(Avatar));
			InOutData.read(reinterpret_cast<char *>(&tmpAv), sizeof(Avatar));
			AvatarInUse->Copy(tmpAv);
		}
		//-1 is an exit...
	}while(Selection < -1 || Selection >= maxNumAvatars);

	InOutData.close();
	return gpMainMenu;
}

int viewAvatar(ConLib v, Avatar *Av)
{
	char	tmpChrStr[32];
	int		tmpInt	= 0;
	int		i		= 0;
	string	tmpStr	= "";
	system("cls");
	v.SetTxtClr(cGreen); cout << "\n View Active Character\n\n";
	v.SetTxtClr(cSubWhite);

	if(Av != NULL)
	{
		//Name stuff...
		v.SetTxtClr(cGreen); cout << " Name: "; v.SetTxtClr(cSubWhite);	cout << Av->GetFName() << " " << Av->GetMName() << " " << Av->GetLName() << "\n";
		v.SetTxtClr(cGreen); cout << " Sex: ";	v.SetTxtClr(cSubWhite); if(Av->GetSex() == 0) cout << "Male"; else cout << "Female";
		v.SetTxtClr(cGreen); cout << " Race: ";	v.SetTxtClr(cSubWhite); cout << Av->GetRaceStr(Av->GetRace());
		v.SetTxtClr(cGreen); cout << " Alignment: "; v.SetTxtClr(cSubWhite); cout << Av->GetAlign() << "\n";
		v.SetTxtClr(cGreen); cout << " Height: "; v.SetTxtClr(cSubWhite); cout << Av->GetHeight() << " \"";
		v.SetTxtClr(cGreen); cout << " Weight: "; v.SetTxtClr(cSubWhite); cout << Av->GetWeight() << " lbs.\n\n";
		v.SetTxtClr(cGreen); cout << " Class Aquisition: "; v.SetTxtClr(cSubWhite);
		if(Av->GetStatus(asMultiClass) == false) cout << "Dual-class"; else cout << "Multi-class";
		v.SetTxtClr(cGreen); cout << " Class: "; v.SetTxtClr(cSubWhite);
		if(Av->GetStatus(asMultiClass) == false) cout << Av->GetClassStr(0);
		else
		{
			//Assigning how many class slots to present based upon race
			switch(Av->GetRace())
			{
			case rDwarf: case rGnome: case rHalfling: tmpInt = 2; break;
			default: tmpInt = 3; break;
			}
			for(i = 0; i < tmpInt; i++)
			{
				cout << Av->GetClassStr(i);
				if(i < tmpInt - 1) cout << " / ";
			}
		}
		v.SetTxtClr(cGreen); cout << " Kit: "; v.SetTxtClr(cSubWhite);
		if(Av->GetStatus(asMultiClass) == false) cout << Av->GetKitStr(0);
		else
		{
			//Assigning how many class slots to present based upon race
			switch(Av->GetRace())
			{
			case rDwarf: case rGnome: case rHalfling: tmpInt = 2; break;
			default: tmpInt = 3; break;
			}
			for(i = 0; i < tmpInt; i++)
			{
				cout << Av->GetKitStr(i);
				if(i < tmpInt - 1) cout << " / ";
			}
		}
		cout << "\n\n ";
		v.SetTxtClr(cGreen); cout << "Attributes\n";
		cout << " Str: "; 
		v.SetTxtClr(cSubWhite); if(Av->GetSStr() < 10) cout << "0"; cout << Av->GetSStr();
		if(Av->GetStrE() > 0)
		{
			cout << " / ";
			if(Av->GetStrE() < 10)	cout << "0";
			cout << Av->GetStrE();
		}
		cout << "\n";		//If a stat is below ten, we want a leading 0 placement...
		v.SetTxtClr(cGreen); cout << " Dex: "; v.SetTxtClr(cSubWhite); if(Av->GetSDex() < 10) cout << "0"; cout << Av->GetSDex() << "\n";
		v.SetTxtClr(cGreen); cout << " Con: "; v.SetTxtClr(cSubWhite); if(Av->GetSCon() < 10) cout << "0"; cout << Av->GetSCon() << "\n";
		v.SetTxtClr(cGreen); cout << " Int: "; v.SetTxtClr(cSubWhite); if(Av->GetSInt() < 10) cout << "0"; cout << Av->GetSInt() << "\n";
		v.SetTxtClr(cGreen); cout << " Wis: "; v.SetTxtClr(cSubWhite); if(Av->GetSWis() < 10) cout << "0"; cout << Av->GetSWis() << "\n";
		v.SetTxtClr(cGreen); cout << " Cha: "; v.SetTxtClr(cSubWhite); if(Av->GetSCha() < 10) cout << "0"; cout << Av->GetSCha() << "\n";
		v.SetTxtClr(cGreen); cout << " Com: "; v.SetTxtClr(cSubWhite); if(Av->GetSCom() < 10) cout << "0"; cout << Av->GetSCom() << "\n\n";
		//Weapons
		v.SetTxtClr(cGreen); cout << " Weapon Proficiencies:\n ";
		v.SetTxtClr(cSubWhite);		
		if(Av->GetNumWPsUsed() > 0)
		{
			tmpInt = 0;//Used to testfor need slash marks...
			for(i = 0; i < MAX_WEAPONPRO; i++)
			{
				//Only show the ones that have something assigned...
				if(Av->GetWPSlotCost(i) > 0)
				{
					tmpInt += Av->GetWPSlotCost(i);

					cout << Av->GetWProName(i);
					if(Av->GetWPSlotCost(i) > 1) cout << " (Spc)";

					if(tmpInt < Av->GetNumWPsUsed())
					{
						v.SetTxtClr(cYellow);
						cout << " / ";
						v.SetTxtClr(cSubWhite);
					}
				}
			}
		}
		cout << "\n\n ";
		//NWPs
		v.SetTxtClr(cGreen); cout << "Non-Weapon Proficiencies:\n "; v.SetTxtClr(cSubWhite);

		for(i = 0; i < MAX_NWPs; i++)
			if(Av->GetNWPnumSlotsAll(i) > 0)
			{
				tmpStr = Av->GetNWPStr(i);
				tmpStr += " ";
				sprintf(tmpChrStr, "%d", Av->GetNWPnumSlotsAll(i));
				tmpStr += tmpChrStr;
				cout << tmpStr;
				cout << "\n ";
			}
	}
	else cout << " No Character has been selected. Did you create one?";
	cout << "\n\n ";
	system("pause");
	return gpMainMenu;
}
//ChangeTextColor()
void ChangeTC(ConLib v, int c)
{
	switch(c)
	{
	case tOcean1:		v.SetTxtClr(cLBlue);			break;
	case tOcean2:		v.SetTxtClr(cSubLBlue);			break;
	case tOcean3:		v.SetTxtClr(cNvyBlue);			break;
	case tRiver1:		v.SetTxtClr(cLBlue);			break;
	case tRiver2:		v.SetTxtClr(cSubLBlue);			break;
	case tRiver3:		v.SetTxtClr(cBlue);				break;
	case tRiver4:		v.SetTxtClr(cNvyBlue);			break;
	case tRiver5:		v.SetTxtClr(cSubRed);			break;
	case tDesert:		v.SetTxtClr(cYellow);			break;
	case tRough:		v.SetTxtClr(cGrey);				break;
	case tScrub:		v.SetTxtClr(cSubGreen);			break;
	case tPlains:		v.SetTxtClr(cGreen);			break;
	case tFarmLand:		v.SetTxtClr(cGold);				break;
	case tForest1:		v.SetTxtClr(cGreen);			break;
	case tForest2:		v.SetTxtClr(cSubGreen);			break;
	case tMarsh:		v.SetTxtClr(cSubGreen);			break;
	case tHills:		v.SetTxtClr(cGrey);				break;
	case tMountain1:	v.SetTxtClr(cGrey);				break;
	case tMountain2:	v.SetTxtClr(cSubWhite);			break;
	case tMountain3:	v.SetTxtClr(cWhite);			break;
	case tMountain4:	v.SetTxtClr(cSubRed);			break;
	case tHamlet:		v.SetTxtClr(cGrey);				break;
	case tVillage:		v.SetTxtClr(cSubWhite);			break;
	case tTown:			v.SetTxtClr(cWhite);			break;
	case tCity:			v.SetTxtClr(cYellow);			break;
	case tCapital:		v.SetTxtClr(cRed);				break;
	}
}
void loadWorldMap(MapTile map[][y_Cord][z_Cord], int xLength, int yLength, int zLength)
{
	int			temp;
	ifstream	in;
	string		strTemp;
	
	in.open("continent.txt");

	if(!in.is_open())
	{
		cout << "There was a problem loading the continent map\n";
		system("pause");
	}
	else
	{
		cout << "\n Loading map data...please wait\n\n ";

		for(int tempZ = 0; tempZ < zLength; tempZ++)
			for(int tempY = 0; tempY < yLength; tempY++)
			{
				for(int tempX = 0; tempX < xLength; tempX++)
				{
					in >> strTemp;
					if(strTemp.length() > 0)
					{
						temp = atoi(strTemp.c_str());
						map[tempX][tempY][tempZ].setTerrain(temp);
					}
				}//tempX loop
				if(tempY%100 == 0) cout << ".";
			}
		cout << "Map completed.";
	}
	in.close();
}
void saveWorldMap(MapTile map[][y_Cord][z_Cord], int xLength, int yLength, int zLength)
{
	ofstream out;
	
	out.open("continent.txt");

	if(!out.is_open())
	{
		cout << "There was a problem opening continent map\n";
		system("pause");
	}
	else
	{
		for (int tempZ = 0; tempZ < zLength; tempZ++)
		{
			for (int tempY = 0; tempY < yLength; tempY++)
			{
				for (int tempX = 0; tempX < xLength; tempX++)
				{
					out << map[tempX][tempY][tempZ].getTerrain();

					if(tempX < xLength - 1) out << " ";
				}//tempX loop
                if(tempY < yLength - 1) out << "\n";
			}
			if(tempZ < zLength - 1) out << "\n";
		}
	}
	out.close();
}
void SetLocalTerrain(MapTile map[x_Cord][y_Cord][z_Cord], Avatar *pc, int terrain)
{
	//Setting blocks of '24' spaces for rapid assignment
	for(int z = AvatarInUse->GetWorldZ(); z < AvatarInUse->GetWorldZ() + 1; z++)
		for(int y = AvatarInUse->GetWorldY(); y < AvatarInUse->GetWorldY() + MilesPerSquare; y++)
			for(int x = AvatarInUse->GetWorldX(); x < AvatarInUse->GetWorldX() + MilesPerSquare; x++)
				map[x][y][z].setTerrain(terrain);
}
void displayWorldMapByTheMile(ConLib loc, MapTile A_Map[][y_Cord][z_Cord], Avatar *pc)
{
	for (int z_Count = 0; z_Count < z_Cord; z_Count++)
	{
		for (int y_Count = (pc->GetWorldY() - OffSetY); y_Count < (pc->GetWorldY() + OffSetY); y_Count++)
		{
			cout << " ";//Spacer from edge of screen
			for (int x_Count = (pc->GetWorldX() - OffSetX); x_Count < (pc->GetWorldX() + OffSetX); x_Count++)
			{
				if ((x_Count < 0 || x_Count > x_Cord - 1) || (y_Count < 0 || y_Count > y_Cord - 1))
				{
					loc.SetTxtClr(cSubWhite);
					cout << ".";
				}
				else
				{
				//	if(!(x_Count == pc->GetWorldX() && y_Count == pc->GetWorldY())) 
				//	{
						ChangeTC(loc, A_Map[x_Count][y_Count][z_Count].getTerrain());
						A_Map[x_Count][y_Count][0].print();
				//	}
				//	else 
				//	{
				//		loc.SetTxtClr(cRed);
				//		cout << "X";
				//	}//else
				}//else
			}//x_Count loop
			cout << "\n";
		}//y_Count Loop
	}//z_Count Loop
	
	loc.SetTxtClr(cSubWhite);	cout << " X: ";	loc.SetTxtClr(cGreen);		cout << pc->GetWorldX() << " (" << (pc->GetWorldX()/24) << ")";
	loc.SetTxtClr(cSubWhite);	cout << " Y: ";	loc.SetTxtClr(cGreen);		cout << pc->GetWorldY() << " (" << (pc->GetWorldY()/24) << ")";
	loc.SetTxtClr(cSubWhite);	cout << " Z: ";	loc.SetTxtClr(cGreen);		cout << pc->GetWorldZ() << "\n";
	loc.SetTxtClr(cSubWhite);	cout << " Facing: "; loc.SetTxtClr(cGreen);
	switch(pc->GetFacing())
	{
	case 0: cout << "North";		break;
	case 1: cout << "North East";	break;
	case 2: cout << "East";			break;
	case 3: cout << "South East";	break;
	case 4: cout << "South";		break;
	case 5: cout << "South West";	break;
	case 6: cout << "West";			break;
	case 7: cout << "North West";	break;
	}

	loc.SetTxtClr(cSubWhite);	cout << "\n Terrain: ";
	ChangeTC(loc, A_Map[pc->GetWorldX()][pc->GetWorldY()][0].getTerrain());
	A_Map[pc->GetWorldX()][pc->GetWorldY()][0].printName();
	
	loc.SetTxtClr(cRed);		cout << "\n A";	loc.SetTxtClr(cSubWhite);	cout << "-Left ";
	loc.SetTxtClr(cRed);		cout << "D";	loc.SetTxtClr(cSubWhite);	cout << "-Right ";
	loc.SetTxtClr(cRed);		cout << "W";	loc.SetTxtClr(cSubWhite);	cout << "-Move ";
}
void RandomTerrain(MapTile map[x_Cord][y_Cord][z_Cord], int xLength, int yLength, int zLength)
{
	int temp = 0;
	for (int tempZ = 0; tempZ < zLength; tempZ++)
		for (int tempY = 0; tempY < yLength; tempY++)
			for (int tempX = 0; tempX < xLength; tempX++)
			{
				temp = int(rand() % MAX_TERRAIN);
				if (temp > MAX_TERRAIN)	temp = MAX_TERRAIN;
				if (temp < tOcean1)		temp = tOcean1;
				if(temp == tMountain4)//volcano
				{
					//Volcano only active 5% of the time
					if(rand()%100 < 95) temp = tMountain3;
				}
				map[tempX][tempY][tempZ].setTerrain(temp);
			}//tempX loop
}
/*
//Enumerating menu options that the user will be using
enum UserChoice { PRINT = 1, NEW, VIEW, UPDATE, DELETE, RENEW, END, totalChoices };

//Defining some constants
#define AccNumWidth		7
#define CashWidth		8

void	UpdateRecord	(fstream &);
void	DeleteRecord	(fstream &);
void	RenewAccounts	(fstream &);
void	ViewCurrent		(fstream &);

int main()
{
	int		UserChoice = -1;

	Init();

	fstream InOutData("Credit.dat", ios::in | ios::out);

	if(!InOutData)
	{
		cout << "Unable to open Client.dat\n";
		system("pause");
	}
	else
	{
		//EnterChoice prints menu, and returns a value that is used as test value in this while-loop
		while((UserChoice = EnterChoice()) != END)
		{
			//Reset location each time to ensure index is correct
			InOutData.seekg(0);

			switch(UserChoice)
			{
			case PRINT:		CreateTextFile	(InOutData);		break;
			case NEW:		NewRecord		(InOutData);		break;
			case UPDATE:	UpdateRecord	(InOutData);		break;
			case DELETE:	DeleteRecord	(InOutData);		break;
			case RENEW:		RenewAccounts	(InOutData);		break;
			case VIEW:		ViewCurrent		(InOutData);		break;
			case END:		cout << "Quiting...\n";				break;
			default: cout << "Input did not match choices.\n";	break;
			}
		}
		InOutData.clear();
	}
	InOutData.close();
	return 0;
}
void ViewCurrent(fstream &Data)
{
	ClientData	TmpClient1;
	
	system("cls");
	
	cout << left	<< setw(AccNumWidth + 1)	<< "Account\t\t"
		 << left	<< setw(NameSize)			<< "L Name"
		 << left	<< setw(NameSize)			<< "F Name"
		 << right	<< setw(CashWidth)			<< "Balance"
		 << "\n\n";

	for(int i = 0; i < MaxAccounts; i++)
	{
		Data.seekg((i) * sizeof(ClientData));
		Data.read(reinterpret_cast<char *>(&TmpClient1), sizeof(ClientData));
        
		if(TmpClient1.GetAcc() > -1)
		{
			OutputLine(cout, TmpClient1);
			cout << "\n";
		}
	}

	//Add a line to clearn up output
	cout << "\n";
	system("pause");
}
void UpdateRecord(fstream &Update)
{
	int			AccNum	= GetAccNum("Enter account number to update");
	double		Trans	= 0.0;
	ClientData	TmpClient1;

	//We move to the location in the records
	Update.seekg((AccNum - 1) * sizeof(ClientData));

	//We read the data according to the size of the record
	Update.read(reinterpret_cast<char *>(&TmpClient1), sizeof(ClientData));

	if(TmpClient1.GetAcc() > -1)
	{
		system("cls");
		OutputLine(cout, TmpClient1);
		cout << "\nEnter charge (+) or payment (-) (note, negative values will take from account): ";
		cin >> Trans;

		TmpClient1.SetBal(TmpClient1.GetBal() + Trans);

		//We move back to into position...
		Update.seekp((AccNum - 1) * sizeof(ClientData));
		//We overwrite the data...
		Update.write(reinterpret_cast<char *>(&TmpClient1), sizeof(ClientData));

		cout << "\n\nRecord updated...\n\n";

		//Return to start of file
		Update.seekg(0);
	}
	else cout << "Account " << AccNum << " has no information.\n";

	system("pause");
}
void DeleteRecord(fstream &DeleteFrom)
{
	int AccNum = GetAccNum("Enter Account Number to Delete");
	ClientData TmpClient1; 
	ClientData TmpClient2;
	
	TmpClient2.Reset();
	
	//We move to the position of the index
	DeleteFrom.seekg((AccNum - 1) * sizeof(ClientData));

	//We read from that point
    DeleteFrom.read(reinterpret_cast<char *>(&TmpClient1), sizeof(ClientData));
	
	cout << "Account Number: " << AccNum;

	if(TmpClient1.GetAcc() > -1)
	{
		//Move back into position...
		DeleteFrom.seekp((AccNum - 1) * sizeof(ClientData));
		//Overwrite the location with empty data...
		DeleteFrom.write(reinterpret_cast<char *>(&TmpClient2), sizeof(ClientData));

		cout << " deleted.\n";
	}
	else cout << " is empty.\n";
	cout << "\n\n";
	system("pause");
}
void RenewAccounts(fstream &ClearThese)
{
	ClientData TmpClient1;

	for(int i = 0; i < MaxAccounts; i++)
	{
		ClearThese.seekp((i) * sizeof(ClientData));
		ClearThese.write(reinterpret_cast<char *>(&TmpClient1), sizeof(ClientData));
	}
}
*/