You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

378 lines
12 KiB

#include <iostream>
#include <thread>
#include <chrono>
#include <random>
#include <fstream>
#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);
}
}
}
}