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