First of all, let me join others in pointing out what sweet ASCII art you've done. This definitely has the beginnings of a much nicer text game than most.
I'd start by defining some structures to hold data about specific things in the game. For a couple of examples:
struct Ability {
std::string name;
int level_adder;
int cost(int level, int inte) {
return (level + level_adder) * inte;
}
bool can_afford(int level, int inte, int manna) {
return cost(level, inte) <= manna;
}
void show(int level, int inte) {
std::cout << name << "[" << cost() << " manna]\n";
}
};
class PlayerClass {
std::string name;
std::vector<Ability> abilities;
size_t ability_count() { return abilities.size(); }
void show(int level, int inte) {
for (int i=0; i<abilities.size(); i++)
std::cout << "[" << i << "] ";
abilities[i].show(level, inte);
}
Ability const &operator[](size_t index) const {
return abilities.at(index);
}
};
With these, we can define all the data for the Player classes something like this:
PlayerClass Champion{
"Champion",
{ "Cleaving Strike", 0},
{ "Melting Thrust", 0},
{"Critical Bash", 0},
{"Purify", 1}
};
PlayerClass Necromancer{
"Necromancer",
{ "Shadow Strike", 0},
{ "cripple", 0},
{ "Mutilate", 0},
{ "Life Tap", 2}
};
...and so on for the other player classes. For only one example, this makes it much easier to add more player classes in the future--for example, I can sit down and decide I want to add a "thief" class:
PlayerClass Thief {
"Thief",
{ "Pick Pocket", 0},
{ "Grab Purse", 0},
{ "Rob Business", 1},
{ "Rob Bank", 4}
};
...and most of the rest of the game can work with this new player class without any modification at all.
Then we can define a player to hold (for example) a reference to a PlayerClass object:
class Player {
PlayerClass &pclass;
// ...
};
With this, getability obviously returns (possibly a pointer or reference to) an Ability object, and looks something like this:
player.pclass.show();
cin >> input;
if (input > player.pclass.ability_count())
ability = None;
else {
ability = player.pclass[input];
player.manna -= ability.cost();
}
Note how this has eliminated huge amounts of repetition in the code, with essentially identical logic repeated once for every ability of every player class.