#include #include #include #include #include #include "lib/Character.hpp" #include "lib/Spell.hpp" #define INTERVAL 1000 #define FLAG_INTERVAL 250 void sleep(int ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } int strlen(const char *msg) { int i = 0; while (msg[i] != '\x00') { i++; } return i; } int getLowest(int a, int b) { return (a < b) ? a : b; } int getHighest(int a, int b) { return (a > b) ? a : b; } void intervalPrint(const char *msg, int interval = 1000, int len = 0) { if (len <= 0) { len = strlen(msg); } for (int i = 0; i < len; i++) { std::cout << msg[i] << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } std::cout << std::endl; } void intervalPrint(std::string &msg, int interval = 1000, int len = 0) { if (len <= 0) { len = msg.length(); } for (int i = 0; i < len; i++) { std::cout << msg.at(i) << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } std::cout << std::endl; } int getNumber(const char *prompt, int min, int max) { int tmp = 0; std::cout << prompt; while (!(std::cin >> tmp) && (tmp >= min && tmp <= max)) { if (std::cin.eofbit) { exit(1); } std::cin.get(); std::cin.clear(); std::cin.ignore(4096, '\x00'); // std::cin.ignore(4096, '\n'); std::cout << prompt; } return tmp; } Character *chooseEnemy() { std::cout << "List of challenger:" << std::endl; for (int i = 0; i < Character::Enemies.size(); i++) { std::cout << "[" << i << "] " << Character::Enemies[i]->getName() << std::endl; } int choice = 0; do { choice = getNumber("Choose your enemy: ", 0, Character::Enemies.size()); } while (!(choice >= 0 && choice < Character::Enemies.size())); return Character::Enemies[choice]; } Character *generatePlayer() { Character *tmp = new Character( Character::playerNames[std::rand() % Character::playerNames.size()], 1, 1, 100, 50, 1, 1); return tmp; } std::string loadFlag() { std::string tmp; std::ifstream flagFile("flag.txt"); if (flagFile.is_open()) { flagFile >> tmp; } return tmp; } void printCharacterInfo(Character *c) { std::cout << "Name : " << c->getName() << std::endl << "HP : " << c->getCurHP() << "/" << c->getMaxHP() << std::endl << "MP : " << c->getCurMP() << "/" << c->getMaxMP() << std::endl; } void printCharacterFullInfo(Character *c) { std::cout << "Name : " << c->getName() << std::endl << "Level: " << c->getLevel() << std::endl << "Exp : " << c->getExperience() << " | next: " << c->toNextLevel() << std::endl << "HP : " << c->getCurHP() << "/" << c->getMaxHP() << std::endl << "MP : " << c->getCurMP() << "/" << c->getMaxMP() << std::endl; } Character *startBattle(Character *p1, Character *p2) { int maxTurn = 1000; int turn = 0; std::cout << "===== BATTLE START ======" << std::endl; while ((p1->isAlive() && p2->isAlive()) && (++turn <= maxTurn)) { std::cout << "== Turn " << turn << " ==" << std::endl; std::cout << "Player =====" << std::endl; printCharacterInfo(p1); std::cout << "Enemy ======" << std::endl; printCharacterInfo(p2); std::cout << "===== Spell Books =====" << std::endl; for (int i = 1; i <= p1->getLevel() && i < Spell::Book.size(); i++) { std::cout << "[" << i << "] " << Spell::Book[i]->getName() << std::endl; } int p1Choice = getNumber("Choose your spell: ", 0, getLowest(p1->getLevel(), Spell::Book.size() - 1)); int p2Choice = (std::rand() % getLowest(p2->getLevel(), Spell::Book.size() - 1)) + 1; Spell *p1Spell = Spell::Book[p1Choice]; Spell *p2Spell = Spell::Book[p2Choice]; if (p1->canCastSpell(p1Spell)) { p1->castSpell(p1Spell, p2); std::cout << p1->getName() << " cast " << p1Spell->getName() << std::endl; sleep(INTERVAL); std::cout << p2->getName() << " took " << p1Spell->getAmount() << " damage" << std::endl; sleep(INTERVAL); } else { std::cout << p1->getName() << " failed to cast " << p1Spell->getName() << std::endl; sleep(INTERVAL); std::cout << p1->getName() << " does not have enough MP to cast it!" << std::endl; sleep(INTERVAL); } if (p2->canCastSpell(p2Spell)) { p2->castSpell(p2Spell, p1); std::cout << p2->getName() << " cast " << p2Spell->getName() << std::endl; sleep(INTERVAL); std::cout << p1->getName() << " took " << p2Spell->getAmount() << " damage" << std::endl; sleep(INTERVAL); } else { std::cout << p2->getName() << " failed to cast " << p2Spell->getName() << std::endl; sleep(INTERVAL); std::cout << p2->getName() << " does not have enough MP to cast it!" << std::endl; sleep(INTERVAL); } } Character *winner; if (turn >= maxTurn) { std::cout << "The battle took too long, a winner has to be decided." << std::endl; winner = (p1->getCurHP() > p2->getCurHP()) ? p1 : p2; } else { winner = (p1->isAlive()) ? p1 : p2; } return winner; } int main() { std::srand(std::time(0)); std::string flag = loadFlag(); Character *player = generatePlayer(); Character *archMage = new Character("Arch-Mage", 999, 999999, 999999, 999999, 1, 1); std::cout << "Welcome to SpellWarz!" << std::endl; sleep(INTERVAL); std::cout << "You are a young mage named '" << player->getName() << "'" << std::endl; sleep(INTERVAL); std::cout << "Here's your flag: "; intervalPrint(flag, FLAG_INTERVAL, 10); std::cout << "Oh no!" << std::endl; sleep(INTERVAL); std::cout << "The Arch-Mage took your flag!" << std::endl; sleep(INTERVAL); std::cout << "He said you are not worthy of it," << std::endl; sleep(INTERVAL); std::cout << "defeat him to get it back!" << std::endl; sleep(INTERVAL); while (player->isAlive()) { std::cout << "========================================" << std::endl; printCharacterFullInfo(player); std::cout << "========================================" << std::endl << "[1] Sleep" << std::endl << "[2] Meditate" << std::endl << "[3] Spar with other mages" << std::endl << "[4] Search info about Arch-Mage" << std::endl << "[5] Challenge the Arch-Mage" << std::endl << "[0] Give up on life" << std::endl; int choice = getNumber("Choose your action: ", 0, 5); std::cout << "========================================" << std::endl; if (choice == 0) { std::cout << "Farewell young mage, see you in the afterlife..." << std::endl; player->reduceHP(player->getMaxHP()); } if (choice == 1) { std::cout << "You take a rest in your dormitory..." << std::endl; sleep(INTERVAL); std::cout << "You recovered to full HP and MP" << std::endl; sleep(INTERVAL); player->restoreHP(player->getMaxHP()); player->restoreMP(player->getMaxMP()); } if (choice == 2) { int tmp; tmp = (rand() % 10) + 1; std::cout << "You meditate on your mana..." << std::endl; sleep(INTERVAL); std::cout << "And got " << tmp << " experience!" << std::endl; sleep(INTERVAL); player->increaseExperience(tmp); if (player->readytoLevelUp()) { std::cout << "Congratulations, you leveled up!" << std::endl; while (player->readytoLevelUp()) { player->levelUp(); } sleep(200); } } if (choice == 3) { Character *enemy = new Character(*chooseEnemy()); Character *winner = startBattle(player, enemy); if (winner == player) { std::cout << "You win! You got " << enemy->getExperience() << "exp" << std::endl; sleep(INTERVAL); player->increaseExperience(enemy->getExperience()); if (player->readytoLevelUp()) { std::cout << "Congratulations, you leveled up!" << std::endl; while (player->readytoLevelUp()) { player->levelUp(); } sleep(200); } } else { while (!player->isAlive()) { player->restoreHP(1); } std::cout << "You lose the fight, it was a fair fight." << std::endl; sleep(INTERVAL); } } if (choice == 4) { std::cout << "You are searching info about the Arch-Mage..." << std::endl; sleep(INTERVAL); std::cout << "Here's some info about the Arch-Mage:" << std::endl; printCharacterFullInfo(archMage); } if (choice == 5) { if (archMage->isAlive()) { std::cout << "You are challenging the Arch-Mage" << std::endl; sleep(INTERVAL); std::cout << "Arch-Mage: "; sleep(INTERVAL); intervalPrint("so you have come to challenge me. Prepare to die!", 200); Character *winner = startBattle(player, archMage); if (winner == player) { std::cout << "You win! You got " << archMage->getExperience() << "exp" << std::endl; player->increaseExperience(archMage->getExperience()); sleep(INTERVAL); if (player->readytoLevelUp()) { std::cout << "Congratulations, you leveled up!" << std::endl; while (player->readytoLevelUp()) { player->levelUp(); } sleep(200); } std::cout << "You did a good job! Now you are the Arch-Mage!" << std::endl; sleep(INTERVAL); std::cout << "Here's the flag the previous Arch-Mage took from you: " << std::endl; sleep(INTERVAL); intervalPrint(flag, FLAG_INTERVAL); } else { std::cout << "You lose the fight..." << std::endl; sleep(INTERVAL); std::cout << "Unfortunately, the Arch-Mage was serious about this fight..." << std::endl; sleep(INTERVAL); std::cout << "You were killed in battle..." << std::endl; intervalPrint("GAME OVER", 250); } } else { std::cout << "You are the Arch-Mage now." << std::endl; sleep(INTERVAL); std::cout << "Here's your flag:"; sleep(INTERVAL); intervalPrint(flag, FLAG_INTERVAL); } } } }