#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
///////////////////////////////
// Declarations //
///////////////////////////////
void banner (string name, string type = "\\", int size = 40);
class character{
public:
character(); // Constructor
bool operator== (character); // use when comparing init of objects
bool operator< (character);
bool operator> (character);
string getname ()const ; // return name of object
string getname ();
int getinit () const; // return init of object
int getinit ();
void set_init (int a); // set init of object to 'a'
void heal_full(); // max out hp and 0 nl dam
void heal(int amt); // modify hp by given amount
void heal_nl (int amt); // heal nl dam by given amount
void dam_nl (int amt); // give nl dam by given amount, checks for disabled or unconscious state.
int getHP(); // return current hp
int getnlDam(); // return nl dam
void SetnMob (character* nmob); // Sets next mob
character* GetnMob (); // Gets the address of next mob.
private:
string name; // name of character
int mHP; // max hit points
int HP; // current hit points
int nlDam; // amount of non lethal damage object currently has
int init; // initiative of character
character* nextMob; // points to next mob to iterate to
};
class encounter{
public:
encounter (character*, int); // Constructor
void listFull ();
private:
int ENEMIES; // number of enemies in this encounter
character enemy[]; // array of all enemies in encounter
character* holding[]; // array of pointers to all mobs currently holding turn
character* player; // pointer to array of player mobs
character* firstMob; // pointer to highest init mob
void setInits (character ary[], int arraySize);
character* sortAryLL (character* ary[], int arraySize);
};
void rebuildCharArray (character arry[], int size){
delete[] arry;
arry = new character[size];
}
///////////////////////////////
// Main Function //
///////////////////////////////
int main(){
int input = 1;
string select;
int PLAYERS;
banner ("COMBAT HELPER", "=");
cout << "Welcome to D&D Combat Helper.\n"
<< "Lets begin by adding all players.\n"
<< "How many players are there?";
cin >> PLAYERS;
character* player = new character[PLAYERS];
//////////////////////////////////
// MAIN MENU //
//////////////////////////////////
while (input != 0)
{
banner ("MAIN MENU");
cout << "\nPlease select from the following options:\n"
<< "1. (Re)build all players\n"
<< "2. Start a new encounter\n"
<< "3. Reset all player's health\n"
<< "0. Quit\n";
cin >> input;
switch (input)
{
case 1: //New players
{
break;
};
case 2: //new fight
{
encounter crnt_enco (player, PLAYERS);
break;
};
case 3: //Heal players
{
cout << "All players restored to full health";
break;
};
case 0: // quit
{
cout << "Thank you for using D&D Combat Helper.\nHave a nice day.";
break;
};
default: // incorrect input
{
cout << "Invalid selection, please try again.";
break;
};
}; // Switch end
}; //While end
}
///////////////////////////////
// Misc Function Definitions //
///////////////////////////////
void banner (string name, string type, int size){
cout << endl;
for (int i=0; i < size; i++) { cout << type; };
cout << "\n" << type << type
<< setw (((size-4)/2) + ((name.size())/2) /*- (name.size()%2)*/ ) << name
<< setw (((size-4)/2) - ((name.size())/2) + (name.size()%2))
<< type << type << "\n";
for (int i=0; i < size; i++) { cout << type; };
cout << endl;
};
///////////////////////////////
// character class //
///////////////////////////////
character::character() {
string select;
cout << "\nCreating new character.\nWhat is their name?";
cin >> name;
cout << "\nWhat is their max HP?";
cin >> mHP;
cout << "Are they currently injured? (y/n)";
cin >> select;
if (select == "y"){
cout << "What is their current HP?";
cin >> HP;
cout << "How much non-lethal damage do they currently have?";
cin >> nlDam;
}
else{
HP = mHP;
nlDam = 0;
};
init = 1;
};
bool character::operator== (character b) {return init == b.init;}
bool character::operator> (character b) {return init > b.init;}
bool character::operator< (character b) {return init < b.init;}
string character::getname () const { return name; }
string character::getname () { return name; }
int character::getinit () const { return init; }
int character::getinit () { return init; }
void character::set_init (int a) { init = a; }
void character::heal_full() {
HP = mHP;
nlDam = 0;
};
void character::heal(int amt) { HP += amt; }
void character::heal_nl (int amt) {
if (nlDam < 0)
{
nlDam -= (amt - nlDam);
cout << name << "now has "<< nlDam << " non lethal damage" << endl;
}
else if (nlDam >= 0)
{ cout << name << " has no non lethal damage. No action required" << endl;};
}
void character::dam_nl (int amt) {
nlDam += amt;
if ( nlDam == HP )
{
cout << name << " is now Staggered, and can only take one standard action.";
}
else if (nlDam > HP)
{
cout << name << " is now unconscious.";
}
}
int character::getHP() { return HP; }
int character::getnlDam() { return nlDam; }
void character::SetnMob(character* nmob) { nextMob = nmob;}
///////////////////////////////
// encounter class //
///////////////////////////////
encounter::encounter (character players_in[], int PLAYERS ){
banner ("NEW ENCOUNTER", "*");
character* high;
player = players_in;
cout<< "How many enemies?";
cin >> ENEMIES;
enemy[ENEMIES];
cout<< "Roll for initiative and input for each person or enemy:"
<< "\n(Don't worry about ties, they will be resolved shortly)";
setInits(player, PLAYERS); // get players init
setInits(enemy, ENEMIES); // get enemies init
character* highestPlayer = sortAryLL(player&, PLAYERS);
character* highestEnemy = sortAryLL(enemy&, ENEMIES);
for (int i = 0; i < PLAYERS; i++) { // sort players by init w/ linked list
if (player[i].getinit() > high->getinit() ) {
}
else if (player[i].getinit() == high->getinit() ) {
}
else if (player[i].getinit() < high->getinit() ) {
}
}
for (int i = 0; i < ENEMIES; i++) { // sort enemies by init w/ linked list
if (enemy[i].getinit() > high->getinit() ) {
}
else if (enemy[i].getinit() == high->getinit() ) {
}
else if (enemy[i].getinit() > high->getinit() ) {
}
}
for ( int i = 0 , j = 0 ; i < PLAYERS && j < ENEMIES ; ) { //sort all mobs w/ linked list
if ( player[i] > enemy[j] ) {
player[i].SetnMob( &enemy[j] );
i++;
}
else if ( player[i] > enemy[j] ) {
enemy[j].SetnMob( &player[i] );
j++;
}
else if ( player[i] == enemy[j] ) {
bool a = false;
while (a == false) {
cout<< player[i].getname() << " and " << enemy[j].getname()
<< "are tied. Please roll again and select higher init."
<< "\n1. " << player[i].getname()
<< "\n2. " << enemy[j].getname();
int select;
cin >> select;
if (select == 1) {
player[i].SetnMob( &enemy[j] );
i++;
a = true;
}
else if (select == 2) {
enemy[j].SetnMob( &player[i] );
j++;
a = true;
}
else {
cout << "Invalid selection, Please try again";
}
}
}
}
}
void encounter::setInits (character ary[], int arraySize) {
for ( int i = 0; i < arraySize; i++) {
int in;
cout << ary[i].getname() << ": ";
cin >> in;
ary[i].set_init(in);
}
}
character* encounter::sortAryLL (character* ary[], int arraySize) {
int iteration = 0;
int high = 0;
int i = 0;
while (iteration < arraySize) {
if (ary[i]->getinit() < ary[high]->getinit() ) {
}
else if (ary[i]->getinit() > ary[high]->getinit() ) {
ary[high]->SetnMob(ary[i]);
}
else if ( ary[i]->getinit() == ary[high]->getinit() ) {
}
}
}