├── sounds ├── bomb.wav ├── heal.wav ├── arrow.wav ├── potion.wav ├── attack0.wav ├── attack1.wav ├── attack2.wav ├── whetstone.wav ├── attack_crit.wav └── attack_miss.wav ├── astyle_format.sh ├── screenshots ├── menu.png └── battle.png ├── include ├── ItemTypes.h ├── PlayerTypes │ ├── Saitama.h │ ├── Debugger.h │ ├── PlayerTypes.h │ ├── Rogue.h │ ├── Healer.h │ └── Warrior.h ├── EnemyTypes │ ├── Dragon.h │ ├── Crab.h │ ├── Lich.h │ ├── Demon.h │ ├── Squid.h │ ├── Zabra.h │ ├── Goblin.h │ ├── Murloc.h │ ├── Gremlin.h │ ├── Mimic.h │ ├── Slimeball.h │ ├── Zombie.h │ ├── Gargoyle.h │ ├── GiantCrab.h │ ├── Putnafer.h │ ├── SmallRat.h │ ├── Vampire.h │ ├── Cerberus.h │ ├── Cockatrice.h │ ├── Skeleton.h │ ├── Werewolf.h │ ├── GiantSquid.h │ ├── TimidGhost.h │ ├── RatKing.h │ ├── SmallDragon.h │ └── EnemyTypes.h ├── StoreGreetings.h ├── Entity.h ├── Store.h ├── Console.h ├── Gambling.h ├── Enemy.h ├── Game.h ├── Common.h ├── Player.h └── Sound.h ├── .travis.yml ├── src ├── PlayerTypes │ ├── Debugger.cpp │ ├── Saitama.cpp │ ├── Rogue.cpp │ ├── Healer.cpp │ └── Warrior.cpp ├── StoreGreetings.cpp ├── Turn.cpp ├── EnemyTypes │ ├── Mimic.cpp │ ├── Lich.cpp │ ├── Demon.cpp │ ├── Crab.cpp │ ├── Vampire.cpp │ ├── Squid.cpp │ ├── Murloc.cpp │ ├── Zombie.cpp │ ├── Cockatrice.cpp │ ├── Werewolf.cpp │ ├── Goblin.cpp │ ├── Zabra.cpp │ ├── GiantSquid.cpp │ ├── Gargoyle.cpp │ ├── Dragon.cpp │ ├── GiantCrab.cpp │ ├── Putnafer.cpp │ ├── Slimeball.cpp │ ├── SmallDragon.cpp │ ├── Cerberus.cpp │ ├── SmallRat.cpp │ ├── Skeleton.cpp │ ├── TimidGhost.cpp │ ├── RatKing.cpp │ └── Gremlin.cpp ├── sourcelist.cmake ├── Common.cpp ├── Entity.cpp ├── Console.cpp ├── Enemy.cpp ├── Sound.cpp ├── Store.cpp ├── Gambling.cpp ├── Game.cpp └── Player.cpp ├── CMakeLists.txt ├── LICENSE ├── .github └── workflows │ └── cmake.yml ├── README.md ├── .gitattributes ├── CODE_OF_CONDUCT.md └── .gitignore /sounds/bomb.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/bomb.wav -------------------------------------------------------------------------------- /sounds/heal.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/heal.wav -------------------------------------------------------------------------------- /sounds/arrow.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/arrow.wav -------------------------------------------------------------------------------- /sounds/potion.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/potion.wav -------------------------------------------------------------------------------- /astyle_format.sh: -------------------------------------------------------------------------------- 1 | astyle --style=google -N -xg -xe -W1 -xb -j --indent=spaces=4 -n $* 2 | -------------------------------------------------------------------------------- /screenshots/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/screenshots/menu.png -------------------------------------------------------------------------------- /sounds/attack0.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/attack0.wav -------------------------------------------------------------------------------- /sounds/attack1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/attack1.wav -------------------------------------------------------------------------------- /sounds/attack2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/attack2.wav -------------------------------------------------------------------------------- /sounds/whetstone.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/whetstone.wav -------------------------------------------------------------------------------- /screenshots/battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/screenshots/battle.png -------------------------------------------------------------------------------- /sounds/attack_crit.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/attack_crit.wav -------------------------------------------------------------------------------- /sounds/attack_miss.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tagniam/Turn/HEAD/sounds/attack_miss.wav -------------------------------------------------------------------------------- /include/ItemTypes.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ITEMTYPES_H_INCLUDED 3 | #define ITEMTYPES_H_INCLUDED 4 | 5 | enum ITEMTYPE 6 | { 7 | ARROWS = 1, 8 | BOMB, 9 | POTION, 10 | WHETSTONE 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: gcc 3 | before_install: 4 | - sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libsdl2-dev libsdl2-mixer-dev 5 | before_script: 6 | - cmake . 7 | script: 8 | - make 9 | -------------------------------------------------------------------------------- /src/PlayerTypes/Debugger.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/PlayerTypes/Debugger.h" 2 | 3 | int Debugger::ReturnDamage() { 4 | return 100; 5 | } 6 | 7 | int Debugger::ReturnRiskAttackDamage() { 8 | return 100; 9 | } 10 | 11 | int Debugger::ReturnHealAmount() { 12 | return 100; 13 | } 14 | -------------------------------------------------------------------------------- /src/PlayerTypes/Saitama.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/PlayerTypes/Saitama.h" 2 | 3 | int Saitama::ReturnDamage() { 4 | return 9999999; 5 | } 6 | 7 | int Saitama::ReturnRiskAttackDamage() { 8 | return 9999999; 9 | } 10 | 11 | int Saitama::ReturnHealAmount() { 12 | return 9999999; 13 | } 14 | -------------------------------------------------------------------------------- /src/StoreGreetings.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/Common.h" 2 | #include "../include/StoreGreetings.h" 3 | 4 | #include 5 | 6 | std::string random_greeting() { 7 | size_t index = Common::RandomInt(0, static_cast(STORE_GREETINGS.size())-1); 8 | return STORE_GREETINGS[index]; 9 | } 10 | -------------------------------------------------------------------------------- /include/PlayerTypes/Saitama.h: -------------------------------------------------------------------------------- 1 | #ifndef SAITAMA_H 2 | #define SAITAMA_H 3 | 4 | #include "../Player.h" 5 | 6 | 7 | class Saitama : public Player { 8 | private: 9 | int ReturnDamage(); 10 | int ReturnRiskAttackDamage(); 11 | int ReturnHealAmount(); 12 | }; 13 | 14 | #endif // SAITAMA_H 15 | -------------------------------------------------------------------------------- /include/PlayerTypes/Debugger.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGGER_H 2 | #define DEBUGGER_H 3 | 4 | #include "../Player.h" 5 | 6 | 7 | class Debugger : public Player { 8 | private: 9 | int ReturnDamage(); 10 | int ReturnRiskAttackDamage(); 11 | int ReturnHealAmount(); 12 | }; 13 | 14 | #endif // DEBUGGER_H 15 | -------------------------------------------------------------------------------- /include/PlayerTypes/PlayerTypes.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYERTYPES_H_INCLUDED 2 | #define PLAYERTYPES_H_INCLUDED 3 | 4 | // Includes player type headers. 5 | 6 | #include "Warrior.h" 7 | #include "Rogue.h" 8 | #include "Healer.h" 9 | #include "Debugger.h" 10 | #include "Saitama.h" 11 | 12 | #endif // PLAYERTYPES_H_INCLUDED 13 | -------------------------------------------------------------------------------- /include/PlayerTypes/Rogue.h: -------------------------------------------------------------------------------- 1 | #ifndef ROGUE_H 2 | #define ROGUE_H 3 | 4 | #include "../Player.h" 5 | 6 | 7 | class Rogue : public Player { 8 | public: 9 | Rogue(void); 10 | private: 11 | int ReturnDamage(); 12 | int ReturnRiskAttackDamage(); 13 | int ReturnHealAmount(); 14 | }; 15 | 16 | #endif // ROGUE_H 17 | -------------------------------------------------------------------------------- /include/PlayerTypes/Healer.h: -------------------------------------------------------------------------------- 1 | #ifndef HEALER_H 2 | #define HEALER_H 3 | 4 | #include "../Player.h" 5 | 6 | 7 | class Healer : public Player { 8 | public: 9 | Healer(void); 10 | private: 11 | int ReturnDamage(); 12 | int ReturnRiskAttackDamage(); 13 | int ReturnHealAmount(); 14 | }; 15 | 16 | #endif // HEALER_H 17 | -------------------------------------------------------------------------------- /include/PlayerTypes/Warrior.h: -------------------------------------------------------------------------------- 1 | #ifndef WARRIOR_H 2 | #define WARRIOR_H 3 | 4 | #include "../Player.h" 5 | 6 | 7 | class Warrior : public Player { 8 | public: 9 | Warrior(void); 10 | private: 11 | int ReturnDamage(); 12 | int ReturnRiskAttackDamage(); 13 | int ReturnHealAmount(); 14 | }; 15 | 16 | #endif // WARRIOR_H 17 | -------------------------------------------------------------------------------- /include/EnemyTypes/Dragon.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAGON_H 2 | #define DRAGON_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Dragon : public Enemy { 8 | public: 9 | Dragon(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro(); 13 | 14 | private: 15 | int ReturnDamage(); 16 | int ReturnRiskAttackDamage(); 17 | int ReturnHealAmount(); 18 | }; 19 | 20 | #endif // DRAGON_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Crab.h: -------------------------------------------------------------------------------- 1 | #ifndef CRAB_H 2 | #define CRAB_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Crab : public Enemy { 8 | public: 9 | Crab(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // CRAB_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Lich.h: -------------------------------------------------------------------------------- 1 | #ifndef LICH_H 2 | #define LICH_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Lich : public Enemy { 8 | public: 9 | Lich(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // LICH_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Demon.h: -------------------------------------------------------------------------------- 1 | #ifndef Demon_H 2 | #define Demon_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Demon : public Enemy { 8 | public: 9 | Demon(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // DEMON_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Squid.h: -------------------------------------------------------------------------------- 1 | #ifndef SQUID_H 2 | #define SQUID_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Squid : public Enemy { 8 | public: 9 | Squid(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // SQUID_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Zabra.h: -------------------------------------------------------------------------------- 1 | #ifndef ZBRA_H 2 | #define ZBRA_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Zabra : public Enemy { 8 | public: 9 | Zabra(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // ZBRA_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Goblin.h: -------------------------------------------------------------------------------- 1 | #ifndef GOBLIN_H 2 | #define GOBLIN_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Goblin : public Enemy { 8 | public: 9 | Goblin(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // GOBLIN_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Murloc.h: -------------------------------------------------------------------------------- 1 | #ifndef MURLOC_H 2 | #define MURLOC_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Murloc : public Enemy { 8 | public: 9 | Murloc(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // MURLOC_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Gremlin.h: -------------------------------------------------------------------------------- 1 | #ifndef GREMLIN_H 2 | #define GREMLIN_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Gremlin : public Enemy { 8 | public: 9 | Gremlin(); 10 | EnemyType GetType() override; 11 | std::string GetIntro() override; 12 | 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // GREMLIN_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Mimic.h: -------------------------------------------------------------------------------- 1 | #ifndef MIMIC_H 2 | #define MIMIC_H 3 | 4 | #include "../Enemy.h" 5 | 6 | class Mimic : public Enemy { 7 | public: 8 | 9 | Mimic(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | 16 | int ReturnDamage() override; 17 | int ReturnRiskAttackDamage() override; 18 | int ReturnHealAmount() override; 19 | }; 20 | 21 | #endif // MIMIC_H 22 | -------------------------------------------------------------------------------- /include/EnemyTypes/Slimeball.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMEBALL_H 2 | #define SLIMEBALL_H 3 | 4 | #include "../Enemy.h" 5 | 6 | class Slimeball : public Enemy { 7 | public: 8 | Slimeball(); 9 | std::string GetIntro() override; 10 | EnemyType GetType() override; 11 | private: 12 | int ReturnDamage() override; 13 | int ReturnRiskAttackDamage() override; 14 | int ReturnHealAmount() override; 15 | }; 16 | 17 | #endif // SLIMEBALL_H 18 | -------------------------------------------------------------------------------- /include/EnemyTypes/Zombie.h: -------------------------------------------------------------------------------- 1 | #ifndef ZOMBIE_H 2 | #define ZOMBIE_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Zombie : public Enemy { 8 | public: 9 | Zombie(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // ZOMBIE_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Gargoyle.h: -------------------------------------------------------------------------------- 1 | #ifndef GARGOYLE_H 2 | #define GARGOYLE_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Gargoyle : public Enemy { 8 | public: 9 | Gargoyle(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // GARGOYLE_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/GiantCrab.h: -------------------------------------------------------------------------------- 1 | #ifndef GIANTCRAB_H 2 | #define GIANTCRAB_H 3 | 4 | #include "Crab.h" 5 | 6 | 7 | class GiantCrab : public Crab { 8 | public: 9 | GiantCrab(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // GIANTCRAB_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Putnafer.h: -------------------------------------------------------------------------------- 1 | #ifndef PUTNAFER_H 2 | #define PUTNAFER_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Putnafer : public Enemy { 8 | public: 9 | Putnafer(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // PUTNAFER_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/SmallRat.h: -------------------------------------------------------------------------------- 1 | #ifndef SMALLRAT_H 2 | #define SMALLRAT_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class SmallRat : public Enemy { 8 | public: 9 | SmallRat(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // SMALLRAT_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/Vampire.h: -------------------------------------------------------------------------------- 1 | #ifndef VAMPIRE_H 2 | #define VAMPIRE_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Vampire : public Enemy { 8 | public: 9 | Vampire(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // VAMPIRE_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Cerberus.h: -------------------------------------------------------------------------------- 1 | #ifndef CERBERUS_H 2 | #define CERBERUS_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Cerberus : public Enemy { 8 | public: 9 | Cerberus(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // CERBERUS_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Cockatrice.h: -------------------------------------------------------------------------------- 1 | #ifndef COCKATRICE_H 2 | #define COCKATRICE_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Cockatrice : public Enemy { 8 | public: 9 | Cockatrice(); 10 | EnemyType GetType() override; 11 | std::string GetIntro() override; 12 | 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // COCKATRICE_H -------------------------------------------------------------------------------- /include/EnemyTypes/Skeleton.h: -------------------------------------------------------------------------------- 1 | #ifndef SKELETON_H 2 | #define SKELETON_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Skeleton : public Enemy { 8 | public: 9 | Skeleton(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // SKELETON_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/Werewolf.h: -------------------------------------------------------------------------------- 1 | #ifndef WEREWOLF_H 2 | #define WEREWOLF_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class Werewolf : public Enemy { 8 | public: 9 | Werewolf(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // WEREWOLF_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/GiantSquid.h: -------------------------------------------------------------------------------- 1 | #ifndef GIANTSQUID_H 2 | #define GIANTSQUID_H 3 | 4 | #include "Squid.h" 5 | 6 | 7 | class GiantSquid : public Squid { 8 | public: 9 | GiantSquid(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | private: 14 | int ReturnDamage() override; 15 | int ReturnRiskAttackDamage() override; 16 | int ReturnHealAmount() override; 17 | }; 18 | 19 | #endif // GIANTSQUID_H 20 | -------------------------------------------------------------------------------- /include/EnemyTypes/TimidGhost.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMIDGHOST_H 2 | #define TIMIDGHOST_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class TimidGhost : public Enemy { 8 | public: 9 | TimidGhost(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // TIMIDGHOST_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/RatKing.h: -------------------------------------------------------------------------------- 1 | #ifndef RATKING_H 2 | #define RATKING_H 3 | 4 | #include "../Enemy.h" 5 | 6 | class RatKing : public Enemy { 7 | public: 8 | RatKing(); 9 | 10 | EnemyType GetType() override; 11 | std::string GetIntro() override; 12 | private: 13 | int ReturnDamage() override; 14 | int ReturnRiskAttackDamage() override; 15 | int ReturnHealAmount() override; 16 | 17 | int amountOfRats_; 18 | }; 19 | 20 | #endif // RATKING_H 21 | -------------------------------------------------------------------------------- /include/EnemyTypes/SmallDragon.h: -------------------------------------------------------------------------------- 1 | #ifndef SMALLDRAGON_H 2 | #define SMALLDRAGON_H 3 | 4 | #include "../Enemy.h" 5 | 6 | 7 | class SmallDragon : public Enemy { 8 | public: 9 | SmallDragon(); 10 | 11 | EnemyType GetType() override; 12 | std::string GetIntro() override; 13 | 14 | private: 15 | int ReturnDamage() override; 16 | int ReturnRiskAttackDamage() override; 17 | int ReturnHealAmount() override; 18 | }; 19 | 20 | #endif // SMALLDRAGON_H 21 | -------------------------------------------------------------------------------- /include/StoreGreetings.h: -------------------------------------------------------------------------------- 1 | #ifndef STOREGREETINGS_H 2 | #define STOREGREETINGS_H 3 | 4 | #include 5 | #include 6 | 7 | const std::vector STORE_GREETINGS { 8 | "Come on in and buy something!", 9 | "Buy somethin', would ya?", 10 | "No refunds!", 11 | "Window shopping is free, but it doesn't pay my bills!", 12 | "You break it, you buy it!", 13 | "We've got what you need!", 14 | "We're happy to separate you from your money!" 15 | }; 16 | 17 | std::string random_greeting(); 18 | 19 | #endif // STOREGREETINGS_H 20 | -------------------------------------------------------------------------------- /include/Entity.h: -------------------------------------------------------------------------------- 1 | #ifndef ENTITY_H 2 | #define ENTITY_H 3 | 4 | #include 5 | 6 | class Entity { 7 | public: 8 | Entity(); 9 | std::string GetName(); 10 | virtual int Action() = 0; 11 | void TakeDamage(int); 12 | bool IsDead(); 13 | 14 | protected: 15 | virtual int GenericAttack() = 0; 16 | virtual int RiskAttack() = 0; 17 | void Heal(); 18 | 19 | virtual int ReturnDamage() = 0; 20 | virtual int ReturnRiskAttackDamage() = 0; 21 | virtual int ReturnHealAmount() = 0; 22 | 23 | void DisplayHealthBar(); 24 | 25 | std::string name; 26 | int health; 27 | }; 28 | 29 | #endif // ENTITY_H 30 | 31 | -------------------------------------------------------------------------------- /src/Turn.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/Game.h" 2 | 3 | // 4 | // TO-DO: 5 | // - add more enemies 6 | // - implement arena 7 | // - implement custom moves (e.g. specific moves to each class, custom Attack(); stuff) 8 | // - add advanced AI (when taking a risk attack and miss, heal) 9 | // - store and sell (buy with coins, sell arrows/bombs/etc for money or experience) 10 | // - use items in between matches (whetstone, potion) 11 | // - save data in file 12 | 13 | /// Continue commenting code at Player.GenericAttack(). 14 | 15 | int main() { 16 | Game _Game; 17 | // Goes to main menu. Nice. 18 | _Game.MainMenu(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /src/PlayerTypes/Rogue.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/PlayerTypes/Rogue.h" 3 | 4 | Rogue::Rogue(void) { 5 | SoundInfo info; 6 | info.attackRange = std::make_pair(1, 11); 7 | SetSoundInfo(info); 8 | } 9 | 10 | int Rogue::ReturnDamage() { 11 | return Common::RandomInt(7, 12); 12 | } 13 | 14 | int Rogue::ReturnRiskAttackDamage() { 15 | int selector = Common::RandomInt(0, 1); 16 | switch(selector) { 17 | case 0: 18 | return 1; 19 | break; 20 | case 1: 21 | return 10; 22 | break; 23 | default: 24 | return 0; 25 | break; 26 | } 27 | } 28 | 29 | int Rogue::ReturnHealAmount() { 30 | return Common::RandomInt(6, 12); 31 | } 32 | -------------------------------------------------------------------------------- /src/PlayerTypes/Healer.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/PlayerTypes/Healer.h" 3 | 4 | Healer::Healer(void) { 5 | SoundInfo info; 6 | info.attackRange = std::make_pair(1, 9); 7 | SetSoundInfo(info); 8 | } 9 | 10 | int Healer::ReturnDamage() { 11 | return Common::RandomInt(5, 10); 12 | } 13 | 14 | int Healer::ReturnRiskAttackDamage() { 15 | int selector = Common::RandomInt(0, 1); 16 | switch(selector) { 17 | case 0: 18 | return 5; 19 | break; 20 | case 1: 21 | return 10; 22 | break; 23 | default: 24 | return 0; 25 | break; 26 | } 27 | } 28 | 29 | int Healer::ReturnHealAmount() { 30 | return Common::RandomInt(7, 15); 31 | } 32 | -------------------------------------------------------------------------------- /src/PlayerTypes/Warrior.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/PlayerTypes/Warrior.h" 3 | 4 | Warrior::Warrior(void) { 5 | SoundInfo info; 6 | info.attackRange = std::make_pair(1, 16); 7 | SetSoundInfo(info); 8 | } 9 | 10 | int Warrior::ReturnDamage() { 11 | return Common::RandomInt(0, 20); 12 | } 13 | 14 | int Warrior::ReturnRiskAttackDamage() { 15 | int selector = Common::RandomInt(0, 5); 16 | switch(selector) { 17 | case 0: 18 | case 1: 19 | case 2: 20 | case 3: 21 | return 0; 22 | break; 23 | case 4: 24 | case 5: 25 | return 20; 26 | break; 27 | default: 28 | return 0; 29 | break; 30 | } 31 | } 32 | 33 | int Warrior::ReturnHealAmount() { 34 | return Common::RandomInt(1, 10); 35 | } 36 | -------------------------------------------------------------------------------- /include/EnemyTypes/EnemyTypes.h: -------------------------------------------------------------------------------- 1 | #ifndef ENEMYTYPES_H_INCLUDED 2 | #define ENEMYTYPES_H_INCLUDED 3 | 4 | // Includes all enemy type headers. 5 | 6 | #include "Crab.h" 7 | #include "GiantCrab.h" 8 | #include "Squid.h" 9 | #include "GiantSquid.h" 10 | #include "Mimic.h" 11 | #include "Lich.h" 12 | #include "Murloc.h" 13 | #include "Vampire.h" 14 | #include "Werewolf.h" 15 | #include "Goblin.h" 16 | #include "Gargoyle.h" 17 | #include "Putnafer.h" 18 | #include "Zombie.h" 19 | #include "Cerberus.h" 20 | #include "Skeleton.h" 21 | #include "SmallDragon.h" 22 | #include "SmallRat.h" 23 | #include "Slimeball.h" 24 | #include "RatKing.h" 25 | #include "Zabra.h" 26 | #include "Gremlin.h" 27 | #include "TimidGhost.h" 28 | #include "Demon.h" 29 | #include "Cockatrice.h" 30 | #include "Dragon.h" 31 | 32 | #endif // ENEMYTYPES_H_INCLUDED 33 | -------------------------------------------------------------------------------- /src/EnemyTypes/Mimic.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Mimic.h" 3 | 4 | Mimic::Mimic() { 5 | name = "Mimic"; 6 | ExperienceAmount = 10; 7 | CoinsDrop = Common::RandomInt(150, 200); 8 | } 9 | 10 | EnemyType Mimic::GetType() { 11 | return etMimic; 12 | } 13 | 14 | int Mimic::ReturnDamage() { 15 | return Common::RandomInt(3, 9); 16 | } 17 | 18 | int Mimic::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 1); 20 | switch (selector) { 21 | case 0: 22 | return 13; 23 | break; 24 | case 1: 25 | return 2; 26 | break; 27 | default: 28 | return 0; 29 | break; 30 | } 31 | } 32 | 33 | int Mimic::ReturnHealAmount() { 34 | return Common::RandomInt(2, 10); 35 | } 36 | 37 | std::string Mimic::GetIntro() { 38 | return "Is this your lucky day??"; 39 | } 40 | -------------------------------------------------------------------------------- /src/EnemyTypes/Lich.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Lich.h" 3 | 4 | Lich::Lich() { 5 | name = "Lich"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(50, 149); 8 | } 9 | 10 | EnemyType Lich::GetType() { 11 | return etLich; 12 | } 13 | 14 | int Lich::ReturnDamage() { 15 | return Common::RandomInt(5, 24); 16 | } 17 | 18 | int Lich::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 30; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Lich::ReturnHealAmount() { 38 | return Common::RandomInt(5, 29); 39 | } 40 | 41 | std::string Lich::GetIntro() { 42 | return "A cold chill enters the room..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Demon.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Demon.h" 3 | 4 | Demon::Demon() { 5 | name = "Demon"; 6 | ExperienceAmount = 25; 7 | CoinsDrop = Common::RandomInt(0, 34); 8 | } 9 | 10 | EnemyType Demon::GetType() { 11 | return etDemon; 12 | } 13 | 14 | int Demon::ReturnDamage() { 15 | return Common::RandomInt(5, 16); 16 | } 17 | 18 | int Demon::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | case 4: 26 | return 1; 27 | break; 28 | case 5: 29 | return 25; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Demon::ReturnHealAmount() { 38 | return Common::RandomInt(1, 15); 39 | } 40 | 41 | std::string Demon::GetIntro() { 42 | return "A hellish roar is heard. . . "; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Crab.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Crab.h" 3 | 4 | Crab::Crab() { 5 | name = "Crab"; 6 | ExperienceAmount = 20; 7 | CoinsDrop = Common::RandomInt(0, 49); 8 | } 9 | 10 | EnemyType Crab::GetType() { 11 | return etCrab; 12 | } 13 | 14 | int Crab::ReturnDamage() { 15 | return Common::RandomInt(1, 10); 16 | } 17 | 18 | int Crab::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch(selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 15; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Crab::ReturnHealAmount() { 38 | return Common::RandomInt(1, 11); 39 | } 40 | 41 | std::string Crab::GetIntro() { 42 | return "A small shape scuttles from the shadows..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Vampire.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Vampire.h" 3 | 4 | Vampire::Vampire() { 5 | name = "Vampire"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(50, 149); 8 | } 9 | 10 | EnemyType Vampire::GetType() { 11 | return etVampire; 12 | } 13 | 14 | int Vampire::ReturnDamage() { 15 | return Common::RandomInt(5, 24); 16 | } 17 | 18 | int Vampire::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 25; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Vampire::ReturnHealAmount() { 38 | return Common::RandomInt(8, 22); 39 | } 40 | 41 | std::string Vampire::GetIntro() { 42 | return "A dark presence..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Squid.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Squid.h" 3 | 4 | Squid::Squid() { 5 | name = "Squid"; 6 | ExperienceAmount = 20; 7 | CoinsDrop = Common::RandomInt(0, 49); 8 | } 9 | 10 | EnemyType Squid::GetType() { 11 | return etSquid; 12 | } 13 | 14 | int Squid::ReturnDamage() { 15 | return Common::RandomInt(1, 10); 16 | } 17 | 18 | int Squid::ReturnRiskAttackDamage() { 19 | int selector= Common::RandomInt(0, 5); 20 | switch(selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 15; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Squid::ReturnHealAmount() { 38 | return Common::RandomInt(1, 11); 39 | } 40 | 41 | std::string Squid::GetIntro() { 42 | return "Because two arms attacking you just wasn't enough."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Murloc.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Murloc.h" 3 | 4 | Murloc::Murloc() { 5 | name = "Murloc"; 6 | ExperienceAmount = 35; 7 | CoinsDrop = Common::RandomInt(0, 39); 8 | } 9 | 10 | EnemyType Murloc::GetType() { 11 | return etMurloc; 12 | } 13 | 14 | int Murloc::ReturnDamage() { 15 | return Common::RandomInt(5, 9); 16 | } 17 | 18 | int Murloc::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 12; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Murloc::ReturnHealAmount() { 38 | return Common::RandomInt(5, 39); 39 | } 40 | 41 | std::string Murloc::GetIntro() { 42 | return "The sound of wet footsteps approaches..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Zombie.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Zombie.h" 3 | 4 | Zombie::Zombie() { 5 | name = "Zombie"; 6 | ExperienceAmount = 90; 7 | CoinsDrop = Common::RandomInt(40, 64); 8 | } 9 | 10 | EnemyType Zombie::GetType() { 11 | return etZombie; 12 | } 13 | 14 | int Zombie::ReturnDamage() { 15 | return Common::RandomInt(20, 29); 16 | } 17 | 18 | int Zombie::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 6); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | case 6: 30 | return 30; 31 | break; 32 | default: 33 | return 0; 34 | break; 35 | } 36 | } 37 | 38 | int Zombie::ReturnHealAmount() { 39 | return Common::RandomInt(2, 41); 40 | } 41 | 42 | std::string Zombie::GetIntro() { 43 | return "\"Brains,\" it moans..."; 44 | } 45 | -------------------------------------------------------------------------------- /include/Store.h: -------------------------------------------------------------------------------- 1 | #ifndef STORE_H 2 | #define STORE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "Player.h" 8 | 9 | struct ItemInfo { 10 | std::string item_name; 11 | int amount; 12 | int piece_price; 13 | }; 14 | 15 | struct ItemHash { 16 | std::size_t operator()(ITEMTYPE it) const { 17 | return static_cast(it); 18 | } 19 | }; 20 | 21 | class Store { 22 | using catalogue_t = std::unordered_map; 23 | 24 | public: 25 | Store() noexcept; 26 | void StoreFront(Player*); 27 | 28 | private: 29 | catalogue_t buy_stock; 30 | catalogue_t sell_stock; 31 | 32 | void BuyFront(Player*); 33 | void SellFront(Player*); 34 | 35 | void SellItem(Player*, ITEMTYPE, ItemInfo); 36 | void BuyItem(Player*, ITEMTYPE, ItemInfo); 37 | 38 | void DisplayStock(const catalogue_t&) const; 39 | void DisplayStoreMainMenu(Player*) const; 40 | 41 | }; 42 | 43 | #endif // STORE_H 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Cockatrice.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Cockatrice.h" 3 | 4 | Cockatrice::Cockatrice() { 5 | name = "Cockatrice"; 6 | ExperienceAmount = 25; 7 | CoinsDrop = Common::RandomInt(10, 49); 8 | } 9 | 10 | EnemyType Cockatrice::GetType() { 11 | return etCockatrice; 12 | } 13 | 14 | int Cockatrice::ReturnDamage() { 15 | return Common::RandomInt(1, 15); 16 | } 17 | 18 | int Cockatrice::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 5; 26 | break; 27 | case 4: 28 | case 5: 29 | return 12; 30 | break; 31 | default: 32 | return 1; 33 | break; 34 | } 35 | } 36 | 37 | int Cockatrice::ReturnHealAmount() { 38 | return Common::RandomInt(5, 20); 39 | } 40 | 41 | std::string Cockatrice::GetIntro() { 42 | return "hiss..."; 43 | } -------------------------------------------------------------------------------- /src/EnemyTypes/Werewolf.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Werewolf.h" 3 | 4 | Werewolf::Werewolf() { 5 | name = "Werewolf"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(50, 149); 8 | } 9 | 10 | EnemyType Werewolf::GetType() { 11 | return etWerewolf; 12 | } 13 | 14 | int Werewolf::ReturnDamage() { 15 | return Common::RandomInt(5, 24); 16 | } 17 | 18 | int Werewolf::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 20; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Werewolf::ReturnHealAmount() { 38 | return Common::RandomInt(4, 18); 39 | } 40 | 41 | std::string Werewolf::GetIntro() { 42 | return "Smells like wet dog."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Goblin.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Goblin.h" 3 | 4 | Goblin::Goblin() { 5 | name = "Goblin"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(50, 149); 8 | } 9 | 10 | EnemyType Goblin::GetType() { 11 | return etGoblin; 12 | } 13 | 14 | int Goblin::ReturnDamage() { 15 | return Common::RandomInt(5, 24); 16 | } 17 | 18 | int Goblin::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 20; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Goblin::ReturnHealAmount() { 38 | return Common::RandomInt(3, 12); 39 | } 40 | 41 | std::string Goblin::GetIntro() { 42 | return "You hear cackles of laughter in the distance..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Zabra.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Zabra.h" 3 | 4 | Zabra::Zabra() { 5 | name="Zabra"; 6 | ExperienceAmount = 150; 7 | CoinsDrop = Common::RandomInt(55, 154); 8 | } 9 | 10 | 11 | EnemyType Zabra::GetType() { 12 | return etZabra; 13 | } 14 | 15 | int Zabra::ReturnDamage() { 16 | return Common::RandomInt(6, 25); 17 | } 18 | 19 | int Zabra::ReturnRiskAttackDamage() { 20 | int selector = Common::RandomInt(0, 5); 21 | switch (selector) { 22 | case 0: 23 | case 1: 24 | case 2: 25 | case 3: 26 | return 2; 27 | break; 28 | case 4: 29 | case 5: 30 | return 30; 31 | break; 32 | default: 33 | return 0; 34 | break; 35 | } 36 | } 37 | 38 | int Zabra::ReturnHealAmount() { 39 | return Common::RandomInt(6, 35); 40 | } 41 | 42 | std::string Zabra::GetIntro() { 43 | return std::string("Three times coraman, nobody can beat ...."); 44 | } 45 | -------------------------------------------------------------------------------- /src/EnemyTypes/GiantSquid.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/GiantSquid.h" 3 | 4 | GiantSquid::GiantSquid() { 5 | name = "Giant Squid"; 6 | ExperienceAmount = 50; 7 | CoinsDrop = Common::RandomInt(0, 99); 8 | } 9 | 10 | EnemyType GiantSquid::GetType() { 11 | return etGiantSquid; 12 | } 13 | 14 | int GiantSquid::ReturnDamage() { 15 | return Common::RandomInt(7, 14); 16 | } 17 | 18 | int GiantSquid::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch(selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 0; 26 | break; 27 | case 4: 28 | case 5: 29 | return 20; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int GiantSquid::ReturnHealAmount() { 38 | return Common::RandomInt(5, 11); 39 | } 40 | 41 | std::string GiantSquid::GetIntro() { 42 | return "With a thunderous splash..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Gargoyle.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Gargoyle.h" 3 | 4 | Gargoyle::Gargoyle() { 5 | name = "Gargoyle"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(50, 149); 8 | } 9 | 10 | EnemyType Gargoyle::GetType() { 11 | return etGargoyle; 12 | } 13 | 14 | int Gargoyle::ReturnDamage() { 15 | return Common::RandomInt(5, 24); 16 | } 17 | 18 | int Gargoyle::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 25; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Gargoyle::ReturnHealAmount() { 38 | return Common::RandomInt(6, 20); 39 | } 40 | 41 | std::string Gargoyle::GetIntro() { 42 | return "A silhouette of wings and horns swoops towards you..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/Dragon.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Dragon.h" 3 | 4 | Dragon::Dragon() { 5 | name = "Dragon"; 6 | ExperienceAmount = 270; 7 | CoinsDrop = Common::RandomInt(100, 158); 8 | } 9 | 10 | EnemyType Dragon::GetType() { 11 | return etDragon; 12 | } 13 | 14 | int Dragon::ReturnDamage() { 15 | return Common::RandomInt(30, 58); 16 | } 17 | 18 | int Dragon::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 10; 26 | break; 27 | case 4: 28 | case 5: 29 | return 60; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int Dragon::ReturnHealAmount() { 38 | return Common::RandomInt(30, 48); 39 | } 40 | 41 | std::string Dragon::GetIntro() { 42 | return "Your biggest nightmare comes true a bigger version of small dragon comes..."; 43 | } 44 | -------------------------------------------------------------------------------- /src/EnemyTypes/GiantCrab.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/GiantCrab.h" 3 | 4 | GiantCrab::GiantCrab() { 5 | name = "Giant Crab"; 6 | ExperienceAmount = 100; 7 | CoinsDrop = Common::RandomInt(0, 99); 8 | } 9 | 10 | EnemyType GiantCrab::GetType() { 11 | return etGiantCrab; 12 | } 13 | 14 | 15 | int GiantCrab::ReturnDamage() { 16 | return Common::RandomInt(7, 14); 17 | } 18 | 19 | int GiantCrab::ReturnRiskAttackDamage() { 20 | int selector = Common::RandomInt(0, 5); 21 | switch(selector) { 22 | case 0: 23 | case 1: 24 | case 2: 25 | case 3: 26 | return 0; 27 | break; 28 | case 4: 29 | case 5: 30 | return 20; 31 | break; 32 | default: 33 | return 0; 34 | break; 35 | } 36 | } 37 | 38 | int GiantCrab::ReturnHealAmount() { 39 | return Common::RandomInt(5, 11); 40 | } 41 | 42 | std::string GiantCrab::GetIntro() { 43 | return "A great claw begins to close around you..."; 44 | } 45 | -------------------------------------------------------------------------------- /include/Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef CONSOLE_H_INCLUDED 3 | #define CONSOLE_H_INCLUDED 4 | 5 | #ifdef _WIN32 6 | #include 7 | #endif // _WIN32 8 | 9 | class Console { 10 | public: 11 | enum EColour { 12 | Grey = 0, 13 | DarkGrey, 14 | Red, 15 | Green, 16 | 17 | Background_Red, 18 | Background_Grey, 19 | Background_DarkGrey, 20 | 21 | // Aliases for easy changing of defaults 22 | Default = Grey, 23 | DefaultBackgroun = Background_Grey, 24 | }; 25 | 26 | void ClearScreen(); 27 | 28 | char GetChar() const; 29 | 30 | void SetColour(EColour colour); 31 | 32 | static Console& GetInstance(); 33 | private: 34 | // Private constructor for the singleton 35 | Console(); 36 | 37 | // Copy constructor private and unimplemented for this singleton 38 | Console(Console&) = delete; 39 | 40 | #ifdef _WIN32 41 | HANDLE m_hConsoleHandle; 42 | #endif // _WIN32 43 | }; 44 | 45 | #endif // CONSOLE_H_INCLUDED 46 | -------------------------------------------------------------------------------- /src/EnemyTypes/Putnafer.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Putnafer.h" 3 | 4 | Putnafer::Putnafer() { 5 | name = "Putnafer"; 6 | ExperienceAmount = 150; 7 | CoinsDrop = Common::RandomInt(90, 109); 8 | } 9 | 10 | EnemyType Putnafer::GetType() { 11 | return etPutnafer; 12 | } 13 | 14 | int Putnafer::ReturnDamage() { 15 | return Common::RandomInt(10, 31); 16 | } 17 | 18 | int Putnafer::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | return 5; 25 | break; 26 | case 3: 27 | return 1; 28 | break; 29 | case 4: 30 | case 5: 31 | return 25; 32 | break; 33 | default: 34 | return 0; 35 | break; 36 | } 37 | } 38 | 39 | int Putnafer::ReturnHealAmount() { 40 | return Common::RandomInt(2, 13); 41 | } 42 | 43 | std::string Putnafer::GetIntro() { 44 | return "Terrifying doesn't describe this..."; 45 | } 46 | -------------------------------------------------------------------------------- /src/EnemyTypes/Slimeball.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Slimeball.h" 3 | 4 | Slimeball::Slimeball() { 5 | name = "Slimeball"; 6 | ExperienceAmount = 25; 7 | CoinsDrop = Common::RandomInt(0, 49); 8 | } 9 | 10 | EnemyType Slimeball::GetType() { 11 | return etSlimeball; 12 | } 13 | 14 | int Slimeball::ReturnDamage() { 15 | auto acidSplash = 2; 16 | return 1 + acidSplash + Common::RandomInt(0, 9); 17 | } 18 | 19 | std::string Slimeball::GetIntro() { 20 | return "Gurgle, gurgle, glub, glub..."; 21 | } 22 | 23 | int Slimeball::ReturnRiskAttackDamage() { 24 | int selector = Common::RandomInt(0, 5); 25 | switch(selector) { 26 | case 0: 27 | case 1: 28 | case 2: 29 | case 3: 30 | return 2; 31 | break; 32 | case 4: 33 | case 5: 34 | return 15; 35 | break; 36 | default: 37 | return 0; 38 | break; 39 | } 40 | } 41 | 42 | int Slimeball::ReturnHealAmount() { 43 | return Common::RandomInt(1, 11); 44 | } 45 | -------------------------------------------------------------------------------- /src/EnemyTypes/SmallDragon.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/SmallDragon.h" 3 | 4 | SmallDragon::SmallDragon() { 5 | name = "Small Dragon"; 6 | ExperienceAmount = 135; 7 | CoinsDrop = Common::RandomInt(50, 79); 8 | } 9 | 10 | EnemyType SmallDragon::GetType() { 11 | return etSmallDragon; 12 | } 13 | 14 | int SmallDragon::ReturnDamage() { 15 | return Common::RandomInt(15, 29); 16 | } 17 | 18 | int SmallDragon::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 5); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 5; 26 | break; 27 | case 4: 28 | case 5: 29 | return 30; 30 | break; 31 | default: 32 | return 0; 33 | break; 34 | } 35 | } 36 | 37 | int SmallDragon::ReturnHealAmount() { 38 | return Common::RandomInt(15, 24); 39 | } 40 | 41 | std::string SmallDragon::GetIntro() { 42 | return "You hope there isn't a bigger version of this monster..."; 43 | } 44 | -------------------------------------------------------------------------------- /include/Gambling.h: -------------------------------------------------------------------------------- 1 | #ifndef GAMBLING_H 2 | #define GAMBLING_H 3 | 4 | #include "Player.h" 5 | 6 | class Gambling { 7 | // Contains the functions needed to simulate a gamble for items. 8 | 9 | public: 10 | void Gamble(Player*); 11 | private: 12 | void GenerateValues(); 13 | int ReturnShakenDie(); 14 | char ReturnItem(); 15 | void WinGamble(Player*); 16 | void LoseGamble(Player*); 17 | 18 | // Variables needed for the gamble. 19 | 20 | // The die number required to win the gamble. Player's die must be equal or greater than requirement to win. 21 | int DieRequirement; 22 | // Amount of coins deducted if gamble is lost. 23 | int CoinsDeduction; 24 | // Amount of items won, if gamble is won. 25 | int ItemNumber; 26 | // Character identifying the item won. 27 | // 0 -> Arrows 28 | // 1 -> Bombs 29 | // 2 -> Potions 30 | // 3 -> Whetstones 31 | int Item; 32 | }; 33 | 34 | #endif // GAMBLING_H 35 | -------------------------------------------------------------------------------- /src/EnemyTypes/Cerberus.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Cerberus.h" 3 | 4 | Cerberus::Cerberus() { 5 | name = "Cerberus"; 6 | ExperienceAmount = 120; 7 | CoinsDrop = Common::RandomInt(40, 60); 8 | } 9 | 10 | EnemyType Cerberus::GetType() { 11 | return etCerberus; 12 | } 13 | 14 | int Cerberus::ReturnDamage() { 15 | return Common::RandomInt(15, 25); 16 | } 17 | 18 | int Cerberus::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 6); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 2; 26 | break; 27 | case 4: 28 | case 5: 29 | return 25; 30 | break; 31 | case 7: 32 | return 30; 33 | break; 34 | default: 35 | return 0; 36 | break; 37 | } 38 | } 39 | 40 | int Cerberus::ReturnHealAmount() { 41 | return Common::RandomInt(5, 10); 42 | } 43 | 44 | 45 | std::string Cerberus::GetIntro() { 46 | return "Something is growling behind you..."; 47 | } 48 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.12) 2 | project (Turn) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED On) 6 | set(CMAKE_CXX_EXTENSIONS Off) 7 | 8 | # Find all source files 9 | include(src/sourcelist.cmake) 10 | 11 | add_executable(Turn) 12 | 13 | # Include Directories 14 | target_include_directories(Turn PRIVATE 15 | "include/" 16 | ) 17 | 18 | # Bind source files to target 19 | target_sources(Turn PRIVATE 20 | ${SOURCES} 21 | ) 22 | 23 | # Add warnings 24 | target_compile_options(Turn PRIVATE 25 | $<$:/W3 /EHsc> 26 | $<$,$>:-Wall -Wextra -Wpedantic> 27 | ) 28 | 29 | # Link WinMM required for PlaySound 30 | if (WIN32) 31 | target_link_libraries(Turn winmm.lib) 32 | endif (WIN32) 33 | 34 | if (UNIX) 35 | target_link_libraries(Turn SDL2 SDL2_mixer pthread) 36 | endif (UNIX) 37 | 38 | add_custom_command( 39 | TARGET Turn PRE_BUILD 40 | COMMAND ${CMAKE_COMMAND} -E copy_directory 41 | ${CMAKE_SOURCE_DIR}/sounds/ $/sounds/ 42 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 J.R. Maingat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /include/Enemy.h: -------------------------------------------------------------------------------- 1 | #ifndef ENEMY_H 2 | #define ENEMY_H 3 | 4 | #include 5 | #include "Entity.h" 6 | 7 | enum EnemyType { 8 | etCrab, 9 | etGiantCrab, 10 | etSquid, 11 | etGiantSquid, 12 | etMimic, 13 | etLich, 14 | etZombie, 15 | etPutnafer, 16 | etVampire, 17 | etWerewolf, 18 | etGoblin, 19 | etGargoyle, 20 | etCerberus, 21 | etSkeleton, 22 | etSmallDragon, 23 | etSmallRat, 24 | etMurloc, 25 | etSlimeball, 26 | etRatKing, 27 | etZabra, 28 | etTimidGhost, 29 | etGremlin, 30 | etDemon, 31 | etCockatrice, 32 | etDragon, 33 | etNumEnemyTypes 34 | }; 35 | 36 | 37 | class Enemy : public Entity { 38 | public: 39 | Enemy(); 40 | 41 | int Action(); 42 | void DisplayHUD(); 43 | 44 | std::vector GetDrops(); 45 | int ReturnExperience(); 46 | 47 | virtual EnemyType GetType() = 0; 48 | virtual std::string GetIntro(); 49 | 50 | protected: 51 | int GenericAttack(); 52 | int RiskAttack(); 53 | 54 | int ReturnItemDrop(int); 55 | 56 | int ExperienceAmount; 57 | int CoinsDrop; 58 | }; 59 | 60 | #endif // ENEMY_H 61 | -------------------------------------------------------------------------------- /src/EnemyTypes/SmallRat.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/SmallRat.h" 3 | 4 | SmallRat::SmallRat() { 5 | name = "Small Rat"; 6 | ExperienceAmount = 15; 7 | CoinsDrop = Common::RandomInt(3, 30); 8 | } 9 | 10 | EnemyType SmallRat::GetType() { 11 | return etSmallRat; 12 | } 13 | 14 | int SmallRat::ReturnDamage() { 15 | return Common::RandomInt(2, 6); 16 | } 17 | 18 | int SmallRat::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 9); 20 | switch (selector) { 21 | case 0: 22 | case 1: 23 | case 2: 24 | case 3: 25 | return 0; 26 | break; 27 | case 4: 28 | case 5: 29 | case 6: 30 | case 7: 31 | case 8: 32 | return 2; 33 | break; 34 | case 9: 35 | return 5; 36 | break; 37 | case 10: 38 | return 10; 39 | break; 40 | default: 41 | return 0; 42 | break; 43 | } 44 | } 45 | 46 | int SmallRat::ReturnHealAmount() { 47 | return Common::RandomInt(3, 17); 48 | } 49 | 50 | std::string SmallRat::GetIntro() { 51 | return "Little feet tripping over the floor..."; 52 | } 53 | -------------------------------------------------------------------------------- /include/Game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "Player.h" 5 | #include "Enemy.h" 6 | #include "Gambling.h" 7 | #include "Store.h" 8 | 9 | class Game { 10 | public: 11 | void MainMenu(); 12 | 13 | private: 14 | 15 | enum MenuType { 16 | eMain = 0, 17 | ePlayerClass, 18 | eHowToPlay 19 | }; 20 | 21 | void SetPlayerData(); 22 | int InitializePlayerClass(); 23 | void SetPlayerClass(int); 24 | std::string InitializePlayerName(); 25 | char InitializePlayerGender(); 26 | 27 | void SetEnemy(); 28 | bool PlayAgain(); 29 | void Intermission(); 30 | 31 | void StartGame(); 32 | void Battle(); 33 | void HowToPlay(); 34 | 35 | int GetChoice(MenuType menuType); 36 | void DisplayMenu(MenuType menuType); 37 | 38 | // Pointers needed to call functions from respective classes. 39 | // They are pointers because they have child classes (they polymorph). 40 | Player *_Player; 41 | Enemy *_Enemy; 42 | // This object is not a pointer because it does not have a child class. 43 | Gambling _Gambling; 44 | Store _Store; 45 | }; 46 | 47 | #endif // GAME_H 48 | -------------------------------------------------------------------------------- /src/EnemyTypes/Skeleton.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Skeleton.h" 3 | 4 | Skeleton::Skeleton() { 5 | name = "Skeleton"; 6 | ExperienceAmount = 25; 7 | CoinsDrop = Common::RandomInt(3, 50); 8 | } 9 | 10 | EnemyType Skeleton::GetType() { 11 | return etSkeleton; 12 | } 13 | 14 | int Skeleton::ReturnDamage() { 15 | return Common::RandomInt(3, 7); 16 | } 17 | 18 | int Skeleton::ReturnRiskAttackDamage() { 19 | int selector = Common::RandomInt(0, 9); 20 | switch (selector) { 21 | case 0: 22 | return 0; 23 | break; 24 | case 1: 25 | case 2: 26 | case 3: 27 | return 1; 28 | break; 29 | case 4: 30 | case 5: 31 | case 6: 32 | case 7: 33 | case 8: 34 | return 3; 35 | break; 36 | case 9: 37 | return 5; 38 | break; 39 | case 10: 40 | return 20; 41 | break; 42 | default: 43 | return 0; 44 | break; 45 | } 46 | } 47 | 48 | int Skeleton::ReturnHealAmount() { 49 | return Common::RandomInt(1, 15); 50 | } 51 | 52 | std::string Skeleton::GetIntro() { 53 | return "Clack, clack, clack..."; 54 | } 55 | -------------------------------------------------------------------------------- /src/EnemyTypes/TimidGhost.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/TimidGhost.h" 3 | 4 | TimidGhost::TimidGhost() { 5 | name = "Timid Ghost"; 6 | ExperienceAmount = Common::RandomInt(10, 19); 7 | CoinsDrop = Common::RandomInt(1, 5); 8 | } 9 | 10 | EnemyType TimidGhost::GetType() { 11 | return etTimidGhost; 12 | } 13 | 14 | int TimidGhost::ReturnDamage() { 15 | int damage = Common::RandomInt(0, 2); 16 | int chance = Common::RandomInt(0, 1); // 50% chance 17 | if (chance == 0) { 18 | // TimidGhost musters courage 19 | damage += 5; 20 | } 21 | return damage; 22 | } 23 | 24 | int TimidGhost::ReturnRiskAttackDamage() { 25 | int chance = Common::RandomInt(0, 4); 26 | if (chance == 0) { 27 | return 10; // 20% chance 28 | } else { 29 | return 0; 30 | } 31 | } 32 | 33 | int TimidGhost::ReturnHealAmount() { 34 | return 2; 35 | } 36 | 37 | std::string TimidGhost::GetIntro() { 38 | int choice = Common::RandomInt(0, 1); 39 | if (choice == 0) { 40 | return "The room is brightly lit from all sides, but a shadow creeps up behind you..."; 41 | } else { 42 | return "It approaches you slowly, as if mustering courage..."; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /include/Common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H_INCLUDED 2 | #define COMMON_H_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../include/Console.h" 9 | 10 | // Common functions and data to share across all files. 11 | namespace Common { 12 | void ClearScreen(); 13 | int input(); 14 | 15 | void ColourPrint(std::string, Console::EColour colour); 16 | 17 | void Sleep(int ms); 18 | 19 | int RandomInt(int min, int max); 20 | 21 | template 22 | T RandomEvent(std::vector weights, std::vector outcomes) { 23 | std::vector indices; 24 | int index = 0; // The possible indices for the outcomes vector 25 | for (int weight : weights) { 26 | for (int i = 0; i < weight; i++) { 27 | indices.push_back(index); 28 | } 29 | index++; 30 | } 31 | 32 | int randomIndex = indices.at(RandomInt(0, indices.size()-1)); 33 | return outcomes.at(randomIndex); 34 | } 35 | 36 | // Indicates if the game is still going. 37 | extern bool IsPlaying; 38 | extern const int SLEEP_MS; 39 | 40 | // Number of items held in inventory. 41 | extern const int NUM_ITEMS; 42 | } 43 | 44 | #endif // COMMON_H_INCLUDED 45 | -------------------------------------------------------------------------------- /src/EnemyTypes/RatKing.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/RatKing.h" 3 | 4 | RatKing::RatKing() { 5 | name = "Rat King"; 6 | amountOfRats_ = Common::RandomInt(3, 14); 7 | ExperienceAmount = amountOfRats_ * 15; 8 | CoinsDrop = amountOfRats_ * Common::RandomInt(3, 30); 9 | } 10 | 11 | EnemyType RatKing::GetType() { 12 | return etRatKing; 13 | } 14 | 15 | int RatKing::ReturnDamage() { 16 | return amountOfRats_ * Common::RandomInt(2, 6); 17 | } 18 | 19 | int RatKing::ReturnRiskAttackDamage() { 20 | int selector = Common::RandomInt(0, 9); 21 | switch (selector) { 22 | case 0: 23 | case 1: 24 | case 2: 25 | case 3: 26 | case 4: 27 | case 5: 28 | return 0; 29 | break; 30 | case 6: 31 | case 7: 32 | case 8: 33 | return amountOfRats_ * 7; 34 | break; 35 | case 9: 36 | return amountOfRats_ * 5; 37 | break; 38 | case 10: 39 | return amountOfRats_ * 10; 40 | break; 41 | default: 42 | return 0; 43 | break; 44 | } 45 | } 46 | 47 | int RatKing::ReturnHealAmount() { 48 | return amountOfRats_ * Common::RandomInt(3, 17); 49 | } 50 | 51 | std::string RatKing::GetIntro() { 52 | return "Clumsy yet scary ball of rats approaches..."; 53 | } 54 | -------------------------------------------------------------------------------- /src/sourcelist.cmake: -------------------------------------------------------------------------------- 1 | set (SOURCES ${SOURCES} 2 | src/Common.cpp 3 | src/Console.cpp 4 | src/Entity.cpp 5 | src/Gambling.cpp 6 | src/Game.cpp 7 | src/Player.cpp 8 | src/Sound.cpp 9 | src/Store.cpp 10 | src/StoreGreetings.cpp 11 | src/Turn.cpp 12 | src/Enemy.cpp 13 | 14 | src/EnemyTypes/Cerberus.cpp 15 | src/EnemyTypes/Crab.cpp 16 | src/EnemyTypes/Gargoyle.cpp 17 | src/EnemyTypes/GiantCrab.cpp 18 | src/EnemyTypes/GiantSquid.cpp 19 | src/EnemyTypes/Goblin.cpp 20 | src/EnemyTypes/Gremlin.cpp 21 | src/EnemyTypes/Lich.cpp 22 | src/EnemyTypes/Mimic.cpp 23 | src/EnemyTypes/Murloc.cpp 24 | src/EnemyTypes/Putnafer.cpp 25 | src/EnemyTypes/RatKing.cpp 26 | src/EnemyTypes/Skeleton.cpp 27 | src/EnemyTypes/Slimeball.cpp 28 | src/EnemyTypes/SmallDragon.cpp 29 | src/EnemyTypes/SmallRat.cpp 30 | src/EnemyTypes/Squid.cpp 31 | src/EnemyTypes/TimidGhost.cpp 32 | src/EnemyTypes/Vampire.cpp 33 | src/EnemyTypes/Werewolf.cpp 34 | src/EnemyTypes/Zabra.cpp 35 | src/EnemyTypes/Zombie.cpp 36 | src/EnemyTypes/Demon.cpp 37 | src/EnemyTypes/Dragon.cpp 38 | 39 | src/PlayerTypes/Debugger.cpp 40 | src/PlayerTypes/Healer.cpp 41 | src/PlayerTypes/Rogue.cpp 42 | src/PlayerTypes/Saitama.cpp 43 | src/PlayerTypes/Warrior.cpp 44 | ) 45 | -------------------------------------------------------------------------------- /src/Common.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../include/Common.h" 8 | using namespace std; 9 | 10 | void Common::ClearScreen() { 11 | Console::GetInstance().ClearScreen(); 12 | } 13 | 14 | int Common::input() { 15 | // Converts character code to number, returns. 16 | while (true) { 17 | // Gets character code for input. 18 | int getchCode = Console::GetInstance().GetChar(); 19 | if (getchCode >= 48 && getchCode <= 57) { 20 | return getchCode-48; 21 | } 22 | // Yes/no return 23 | else if (getchCode == 121 || getchCode == 89 || getchCode == 110 || 24 | getchCode == 78) { 25 | return getchCode; 26 | } 27 | } 28 | } 29 | 30 | void Common::ColourPrint(string text, Console::EColour colour) { 31 | Console::GetInstance().SetColour(colour); 32 | cout << text; 33 | Console::GetInstance().SetColour(Console::Default); 34 | } 35 | 36 | void Common::Sleep(int ms) { 37 | std::this_thread::sleep_for(std::chrono::milliseconds(ms)); 38 | } 39 | 40 | int Common::RandomInt(int min, int max) { 41 | static std::mt19937 rng(std::random_device{}()); 42 | std::uniform_int_distribution dist(min, max); 43 | return dist(rng); 44 | } 45 | 46 | bool Common::IsPlaying; 47 | 48 | const int Common::SLEEP_MS = 800; 49 | 50 | const int Common::NUM_ITEMS = 5; 51 | -------------------------------------------------------------------------------- /src/EnemyTypes/Gremlin.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/Common.h" 2 | #include "../../include/EnemyTypes/Gremlin.h" 3 | 4 | Gremlin::Gremlin() { 5 | name = "Gremlin"; 6 | ExperienceAmount = 25; 7 | CoinsDrop = Common::RandomInt(0, 39); 8 | } 9 | 10 | EnemyType Gremlin::GetType() { 11 | return etGremlin; 12 | } 13 | 14 | std::string Gremlin::GetIntro() { 15 | return "Hihihihihi, want some fun ?"; 16 | } 17 | 18 | 19 | 20 | int Gremlin::ReturnDamage() { 21 | return Common::RandomInt(5, 9); 22 | } 23 | 24 | int Gremlin::ReturnHealAmount() { 25 | return Common::RandomInt(3, 10); 26 | } 27 | 28 | 29 | // similar to rolling a d20 : 0 is equal to rolling a d20 in D&D 1, 19 is equal to rolling a 20 30 | int Gremlin::ReturnRiskAttackDamage() { 31 | int selector = Common::RandomInt(0, 19); 32 | switch (selector) { 33 | case 0: 34 | return 0; 35 | break; 36 | case 1: 37 | case 2: 38 | case 3: 39 | case 4: 40 | case 5: 41 | case 6: 42 | case 7: 43 | case 8: 44 | case 9: 45 | return 2; 46 | break; 47 | case 10: 48 | return Common::RandomInt(5, 9); 49 | break; 50 | case 11: 51 | case 12: 52 | case 13: 53 | case 14: 54 | case 15: 55 | case 16: 56 | case 17: 57 | case 18: 58 | return Common::RandomInt(8, 12); 59 | break; 60 | case 19: 61 | return 20; 62 | break; 63 | default: 64 | return 0; 65 | break; 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: [push] 4 | 5 | env: 6 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 7 | BUILD_TYPE: Release 8 | 9 | jobs: 10 | build-linux: 11 | runs-on: ubuntu-20.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Install dependencies 16 | run: sudo apt-get update -qq && sudo apt-get install libegl1-mesa-dev libgles2-mesa-dev libsdl2-dev libsdl2-mixer-dev 17 | 18 | - name: Configure CMake 19 | # Use a bash shell so we can use the same syntax for environment variable 20 | # access regardless of the host operating system 21 | shell: bash 22 | run: cmake -S . -B ${{runner.workspace}}/build -DCMAKE_BUILD_TYPE=$BUILD_TYPE 23 | 24 | - name: Build 25 | shell: bash 26 | # Execute the build. You can specify a specific target with "--target " 27 | run: cmake --build ${{runner.workspace}}/build --config $BUILD_TYPE 28 | - uses: actions/upload-artifact@v1 29 | # upload artifact 30 | with: 31 | name: Turn-linux 32 | path: ${{runner.workspace}}/build/Turn 33 | 34 | build-windows: 35 | runs-on: windows-latest 36 | steps: 37 | - uses: actions/checkout@v2 38 | - name: Configure CMake 39 | shell: powershell 40 | run: cmake -S . -B ${{runner.workspace}}/build 41 | - name: Build 42 | shell: powershell 43 | run: cmake --build ${{runner.workspace}}/build --config $BUILD_TYPE 44 | - uses: actions/upload-artifact@v1 45 | # upload artifact 46 | with: 47 | name: Turn-win.exe 48 | path: ${{runner.workspace}}/build/Debug/Turn.exe 49 | -------------------------------------------------------------------------------- /include/Player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #include "ItemTypes.h" 5 | #include "Entity.h" 6 | #include "Enemy.h" 7 | #include "Sound.h" 8 | 9 | class Player : public Entity, public SoundMaker { 10 | // Contains the functions needed to construct the player's character. 11 | public: 12 | Player(void); 13 | void SaveGame(); 14 | 15 | void SetPlayerData(); 16 | int Action(); 17 | void UseItem(); 18 | void AddToInventory(std::vector); 19 | void AddStoreItemToInventory(ITEMTYPE, int); 20 | bool RemoveStoreItemFromInventory(ITEMTYPE, int); 21 | 22 | void DisplayHUD(Enemy*); 23 | void ReplenishHealth(); 24 | 25 | void AddExperience(int); 26 | void LoseExperience(int); 27 | 28 | void AddCoins(int); 29 | void LoseCoins(int); 30 | 31 | void DisplayInventory(); 32 | int GetCoins(); 33 | 34 | private: 35 | int GenericAttack(); 36 | int RiskAttack(); 37 | int BowAndArrow(); 38 | 39 | void UseWhetstone(); 40 | void UsePotion(); 41 | int UseBomb(); 42 | void DeductDamage(int&); 43 | int ReturnBowDamage(); 44 | void WeakenWeapon(int impact); 45 | 46 | int Flee(); 47 | 48 | void PrintInventoryItem(std::string, int, std::string); 49 | void PrintXPBar(std::string, int, std::string, std::string, int, std::string); 50 | void PrintDivider(char, char, std::string); 51 | void PrintClass(); 52 | 53 | 54 | int player_type; 55 | int level; 56 | char gender; 57 | int experience; 58 | int whetstones; 59 | int arrows; 60 | int potions; 61 | int bombs; 62 | int weaponsharpness; 63 | int coins; 64 | }; 65 | 66 | #endif // PLAYER_H 67 | -------------------------------------------------------------------------------- /include/Sound.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #ifndef _WIN32 6 | #include 7 | #endif 8 | 9 | // 10 | // SoundMaker: A class that ecapsulates 11 | // FileNaming convention: "rouge_attack_miss.wav" 12 | // 13 | #define SNDDIRECTORY "sounds/" 14 | #define ATACKFILENAMEMISS "attack_miss.wav" 15 | #define ATTACKFILENAME1 "attack0.wav" 16 | #define ATTACKFILENAME2 "attack1.wav" 17 | #define ATTACKFILENAME3 "attack2.wav" 18 | #define ATTACKFILENAMECRIT "attack_crit.wav" 19 | 20 | //#define ALTFILENAMEMISS "alt_miss.wav" 21 | #define ALTFILENAME1 "alt0.wav" 22 | //#define ALTFILENAME2 "alt1.wav" 23 | //#define ALTFILENAME3 "alt2.wav" 24 | //#define ALTFILENAMECRIT "alt_crit.wav" 25 | 26 | typedef struct sSoundInfo 27 | { 28 | std::pair attackRange; 29 | //std::pair alternateRange; 30 | std::string fileNamePrefix; 31 | } SoundInfo; 32 | 33 | class PlatformSoundHelper { 34 | public: 35 | PlatformSoundHelper(); 36 | ~PlatformSoundHelper(); 37 | 38 | void PlaySoundFile(std::string const& filename); 39 | private: 40 | #ifndef _WIN32 41 | std::mutex m_resourceMutex; 42 | #endif 43 | }; 44 | 45 | class SoundMaker { 46 | public: 47 | SoundMaker(); 48 | void PlayPrimaryAttack(int damageDealt); 49 | void PlaySecondaryAttack(void); // int damageDealt); 50 | void PlayHeal(void); 51 | void PlaySharpen(void); 52 | void PlayBomb(void); 53 | void PlayPotion(void); 54 | void SetSoundInfo(SoundInfo &info) { mInfo = info; } 55 | private: 56 | 57 | void PlaySoundFile(std::string const& filename); 58 | 59 | SoundInfo mInfo; 60 | std::vector attackFileNames; 61 | std::string altAttackFileName; 62 | std::string healFileName; 63 | std::string whetstoneFileName; 64 | std::string bombFileName; 65 | std::string potionFileName; 66 | 67 | static PlatformSoundHelper ms_SoundHelper; 68 | }; 69 | -------------------------------------------------------------------------------- /src/Entity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../include/Entity.h" 4 | #include "../include/Common.h" 5 | #include "../include/Console.h" 6 | 7 | using namespace std; 8 | using namespace Common; 9 | 10 | Entity::Entity() { 11 | } 12 | 13 | string Entity::GetName() { 14 | // Returns the enemy's name. 15 | return name; 16 | } 17 | 18 | bool Entity::IsDead() { 19 | // Returns a bool value, if the player's health is equal or below 0. 20 | if (health <= 0) { 21 | ColourPrint(name, Console::DarkGrey); 22 | cout << " is dead!" << endl << endl; 23 | Sleep(SLEEP_MS); 24 | return true; 25 | } 26 | return false; 27 | } 28 | 29 | void Entity::TakeDamage(int damage) { 30 | // Doesn't subtract damage points if player chooses to quit. 31 | if (damage == -1) { 32 | IsPlaying = false; 33 | return; 34 | } 35 | // Simply subtracts the damage player deals to the enemy. 36 | health -= damage; 37 | } 38 | 39 | void Entity::DisplayHealthBar() { 40 | string healthBar = " " + to_string(health); 41 | for (size_t i = healthBar.length(); i < 20; i++) { 42 | healthBar += " "; 43 | } 44 | for (size_t i = 0; i < healthBar.length(); i++) { 45 | string currentChar = ""; 46 | currentChar += healthBar.at(i); 47 | if ((i + 1) * 10 <= (size_t)health * 2) { 48 | ColourPrint(currentChar, Console::Background_Red); 49 | } else { 50 | ColourPrint(currentChar, Console::Background_DarkGrey); 51 | } 52 | } 53 | } 54 | 55 | void Entity::Heal() { 56 | int heal = ReturnHealAmount(); 57 | health += heal; 58 | if (health > 100) { 59 | health = 100; 60 | } 61 | ColourPrint(name, Console::DarkGrey); 62 | cout << " gains "; 63 | ColourPrint(to_string(heal), Console::Green); 64 | cout << " HP!" << endl; 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Turn: Hacktober 'n' Slash [![Build Status](https://travis-ci.org/tagniam/Turn.svg?branch=master)](https://travis-ci.org/tagniam/Turn) ![CMake](https://github.com/tagniam/Turn/workflows/CMake/badge.svg?branch=master) 2 | Turn is a turn-based terminal RPG game written in C++. Contributions are encouraged, especially during [Hacktoberfest](https://hacktoberfest.digitalocean.com/)! 3 | 4 | ## Screenshots 5 | 6 | ![Battle screen](screenshots/battle.png) 7 | ![Menu screen](screenshots/menu.png) 8 | 9 | ## Getting Started 10 | ### Prerequisites 11 | * CMake (https://cmake.org) 12 | * SDL2 (https://www.libsdl.org/) for Mac/Linux users 13 | * Install with `brew install sdl2` for Mac users 14 | * Install with `sudo apt install libsdl2-dev libsdl2-mixer-dev` for Linux users 15 | 16 | ### Cloning 17 | Clone this project by running `git clone https://github.com/tagniam/Turn.git` in your terminal. 18 | 19 | ### Building & Running 20 | #### Windows 21 | * In your Command Prompt or Powershell, make sure you are in the `Turn` directory. 22 | * For the right generator see [Visual Studio Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators). 23 | * To build with Visual Studio 16 2019 run the following commands: 24 | 25 | ```shell 26 | $ cmake -S . -B build -G "Visual Studio 16 2019" 27 | $ cmake --build build 28 | ``` 29 | * Start the game by running `build\Turn.exe`. 30 | 31 | Alternative: Generate solution with CMake and build with Visual Studio 32 | 33 | * Run CMake on the `Turn` directory to generate a `.sln` solution file for Visual Studio. You can find a tutorial [here](https://cmake.org/runningcmake/). 34 | 35 | ```shell 36 | $ cmake -S . -B build -G "Visual Studio 16 2019" 37 | ``` 38 | 39 | * Run Visual Studio and open the generated `.sln` solution file. 40 | * Build the project by clicking `Build` -> `Build Solution`. 41 | * Start the game by clicking the green Run button in the toolbar. 42 | 43 | #### Mac/Linux 44 | * In your terminal, make sure you are in the `Turn` directory. 45 | * Run the following commands: 46 | 47 | ```shell 48 | $ cmake -S . -B build 49 | $ cmake --build build 50 | ``` 51 | * Start the game by running `./build/Turn`. 52 | 53 | ### Playing 54 | See the game manual located in the [wiki](https://github.com/tagniam/Turn/wiki). 55 | 56 | ## Contributing 57 | * Please read over the [Code of Conduct](https://github.com/tagniam/Turn/blob/master/CODE_OF_CONDUCT.md) before contributing! 58 | 59 | ## License 60 | * This project is licensed under the MIT License - see the LICENSE file for details. 61 | 62 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/Console.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/Console.h" 2 | #ifdef _WIN32 3 | #include 4 | #include 5 | #else 6 | #include 7 | #include 8 | #include 9 | #include 10 | #endif // _WIN32 11 | 12 | Console::Console() { 13 | #ifdef _WIN32 14 | m_hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 15 | #endif 16 | } 17 | 18 | void Console::ClearScreen() { 19 | #ifdef _WIN32 20 | system("cls"); 21 | #else 22 | system("clear"); 23 | #endif // _WIN32 24 | } 25 | 26 | char Console::GetChar() const { 27 | #ifdef _WIN32 28 | return _getch(); 29 | #else 30 | // The following code attempts to manually reproduce the same behaviour as the 31 | // getch function from Windows' conio.h 32 | // Cache the existing terminal attributes 33 | struct termios cachedAttributes, customAttributes; 34 | tcgetattr(STDIN_FILENO, &cachedAttributes); 35 | // Copy them, and change the flags needed to achieve getch-style behaviour 36 | customAttributes = cachedAttributes; 37 | customAttributes.c_lflag &= ~(ICANON | ECHO); 38 | // Set the attributes to the new ones, read a character with getchar 39 | tcsetattr(STDIN_FILENO, TCSANOW, &customAttributes); 40 | int ch = getchar(); 41 | // Restore the original terminal attribute setup 42 | tcsetattr(STDIN_FILENO, TCSANOW, &cachedAttributes); 43 | // Return the character that was read 44 | return ch; 45 | #endif // _WIN32 46 | } 47 | 48 | void Console::SetColour(EColour colour) { 49 | #ifdef _WIN32 50 | enum WindowsAttributes { 51 | GREY = 7, 52 | DARK_GREY = 8, 53 | RED = 12, 54 | GREEN = 10, 55 | 56 | RED_BACKGROUND = 207, 57 | GREY_BACKGROUND = 127, 58 | DARKGREY_BACKGROUND = 8, 59 | }; 60 | int colourMap[] = { 61 | GREY, // EColour::Grey 62 | DARK_GREY, // EColour::DarkGrey 63 | RED, // EColour::Red 64 | GREEN, // EColour::Green 65 | 66 | RED_BACKGROUND, // EColour::Background_Red 67 | GREY_BACKGROUND, // EColour::Background_Grey 68 | DARKGREY_BACKGROUND, // EColour::Background_DarkGrey 69 | }; 70 | SetConsoleTextAttribute(m_hConsoleHandle, colourMap[colour]); 71 | #else 72 | char const* const colourEscapeCodes[] = { 73 | "\033[0m\033[37m", // EColour::Grey 74 | "\033[0m\033[90m", // EColour::DarkGrey 75 | "\033[0m\033[31m", // EColour::Red 76 | "\033[0m\033[32m", // EColour::Green 77 | 78 | "\033[0m\033[41m", // EColour::Background_Red 79 | "\033[0m\033[47m", // EColour::Background_Grey 80 | "\033[0m\033[100m", // EColour::Background_DarkGrey 81 | }; 82 | printf("%s", colourEscapeCodes[colour]); 83 | #endif // _WIN32 84 | } 85 | 86 | Console& Console::GetInstance() { 87 | static Console singletonInstance; 88 | return singletonInstance; 89 | } 90 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | Using welcoming and inclusive language 12 | Being respectful of differing viewpoints and experiences 13 | Gracefully accepting constructive criticism 14 | Focusing on what is best for the community 15 | Showing empathy towards other community members 16 | Examples of unacceptable behavior by participants include: 17 | 18 | The use of sexualized language or imagery and unwelcome sexual attention or advances 19 | Trolling, insulting/derogatory comments, and personal or political attacks 20 | Public or private harassment 21 | Publishing others' private information, such as a physical or electronic address, without explicit permission 22 | Other conduct which could reasonably be considered inappropriate in a professional setting 23 | 24 | ## Our Responsibilities 25 | 26 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 27 | 28 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 29 | 30 | ## Scope 31 | 32 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 33 | 34 | ## Enforcement 35 | 36 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [contributors section](https://github.com/tagniam/Turn/graphs/contributors). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 37 | 38 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 39 | 40 | ## Attribution 41 | 42 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at [http://contributor-covenant.org/version/1/4](http://contributor-covenant.org/version/1/4). -------------------------------------------------------------------------------- /src/Enemy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../include/Common.h" 6 | #include "../include/Enemy.h" 7 | #include "../include/Console.h" 8 | 9 | using namespace std; 10 | using namespace Common; 11 | 12 | 13 | Enemy::Enemy() { 14 | // Sets up the default variables for the enemy. 15 | // Sets health to max. 16 | health = 100; 17 | // Sets experience amount to 0, just an initialization for the child classes to modify. 18 | ExperienceAmount = 0; 19 | } 20 | 21 | int Enemy::Action() { 22 | // Returns damage hit for the player. Uses random number to select enemy's move. 23 | int selector = Common::RandomInt(0, 8); 24 | switch(selector) { 25 | case 0: 26 | case 1: 27 | // 2/9 chance of risk attacking. 28 | return RiskAttack(); 29 | break; 30 | case 2: 31 | case 3: 32 | // 2/9 chance of healing. 33 | Heal(); 34 | return 0; 35 | break; 36 | case 4: 37 | case 5: 38 | case 6: 39 | case 7: 40 | case 8: 41 | // 5/9 chance of generically attacking. 42 | return GenericAttack(); 43 | break; 44 | default: 45 | // Returns 0 damage in case selector goes wrong. 46 | return 0; 47 | break; 48 | } 49 | } 50 | 51 | void Enemy::DisplayHUD() { 52 | // Displays the enemy's health bar. 53 | cout << "\t"; 54 | DisplayHealthBar(); 55 | cout << endl << endl; 56 | } 57 | 58 | 59 | 60 | vector Enemy::GetDrops() { 61 | // Returns the number of items dropped when the enemy is defeated depending on the item won. 62 | vector drops; 63 | for (int i = 0; i < NUM_ITEMS; i++) { 64 | drops.push_back(ReturnItemDrop(i)); 65 | } 66 | return drops; 67 | } 68 | 69 | int Enemy::ReturnExperience() { 70 | // Returns the amount of experience the player gets when the enemy dies, or the amount of experience 71 | // lost if the player dies. 72 | return ExperienceAmount; 73 | } 74 | 75 | int Enemy::GenericAttack() { 76 | // Returns a generic attack, just a simple attack. 77 | int damage = ReturnDamage(); 78 | // Prints how much damage the enemy deals to the player. 79 | ColourPrint(name, Console::DarkGrey); 80 | cout << " attacks! It deals "; 81 | ColourPrint(to_string(damage), Console::Red); 82 | cout << " damage!" << endl << endl; 83 | return damage; 84 | } 85 | 86 | int Enemy::RiskAttack() { 87 | // Returns a risk attack, having a chance of dealing either very low points or high points. 88 | int damage = ReturnRiskAttackDamage(); 89 | // Prints how much damage the enemy deals to the player. 90 | ColourPrint(name, Console::DarkGrey); 91 | cout << " takes a risk and attacks! It deals "; 92 | ColourPrint(to_string(damage), Console::Red); 93 | cout << " damage!" << endl << endl; 94 | return damage; 95 | } 96 | 97 | int Enemy::ReturnItemDrop(int item) { 98 | int ArrowSelector = Common::RandomInt(0, 5); 99 | int WhetstoneSelector = Common::RandomInt(0, 1); 100 | int PotionSelector = Common::RandomInt(0, 9); 101 | /* 102 | 0 Arrows 103 | 1 Bombs 104 | 2 Potions 105 | 3 Whetstones 106 | 4 Coins 107 | */ 108 | switch(item) { 109 | case 0: // Arrows 110 | if (ArrowSelector<=1) { 111 | return 0; 112 | } else if (ArrowSelector==2||ArrowSelector==3) { 113 | return 3; 114 | } else { 115 | return 5; 116 | } 117 | case 1: 118 | case 2: 119 | if (PotionSelector == 0) { 120 | return 1; 121 | } else if (PotionSelector == 1) { 122 | return 2; 123 | } else { 124 | return 0; 125 | } 126 | case 3: 127 | if (WhetstoneSelector==1) { 128 | return 1; 129 | } else { 130 | return 0; 131 | } 132 | case 4: 133 | return CoinsDrop; 134 | default: 135 | return 0; 136 | break; 137 | } 138 | } 139 | 140 | std::string Enemy::GetIntro() { 141 | return "A distant noise coming closer..."; 142 | } 143 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xm 213 | 214 | # Glitching Visual Studio 215 | *.VC.opendb 216 | 217 | # Ignore CMake files 218 | CMakeLists.txt.user 219 | CMakeCache.txt 220 | CMakeFiles 221 | CMakeScripts 222 | Testing 223 | Makefile 224 | cmake_install.cmake 225 | install_manifest.txt 226 | compile_commands.json 227 | CTestTestfile.cmake 228 | _deps 229 | 230 | # Ignore game files 231 | Turn 232 | data.txt 233 | -------------------------------------------------------------------------------- /src/Sound.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/Common.h" 2 | #include "../include/Sound.h" 3 | 4 | #ifdef _WIN32 5 | #include 6 | #include 7 | #else 8 | #include 9 | #include 10 | #include 11 | #endif 12 | 13 | // Sounds found online at: 14 | // https://freesound.org/people/XxChr0nosxX/sounds/268227/ attack miss 15 | // https://freesound.org/people/Taira%20Komori/sounds/213696/ attack crit 16 | // https://freesound.org/people/lostchocolatelab/sounds/1468/ attack0 17 | // https://freesound.org/people/JohnBuhr/sounds/326868/ attack1 18 | // https://freesound.org/people/loudernoises/sounds/334169/ attack2 19 | // https://freesound.org/people/Ali_6868/sounds/384915/ arrow 20 | // https://freesound.org/people/KeshaFilm/sounds/471834/ heal 21 | // https://freesound.org/people/GameDevC/sounds/422832/ whetstone 22 | // https://freesound.org/people/Taira%20Komori/sounds/215595/ bomb 23 | // https://freesound.org/people/Jamius/sounds/41529/ potion 24 | 25 | PlatformSoundHelper SoundMaker::ms_SoundHelper; 26 | 27 | PlatformSoundHelper::PlatformSoundHelper() { 28 | #ifndef _WIN32 29 | m_resourceMutex.lock(); 30 | SDL_Init(SDL_INIT_AUDIO); 31 | Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); 32 | m_resourceMutex.unlock(); 33 | #endif 34 | } 35 | 36 | PlatformSoundHelper::~PlatformSoundHelper() { 37 | #ifndef _WIN32 38 | m_resourceMutex.lock(); 39 | Mix_CloseAudio(); 40 | SDL_Quit(); 41 | m_resourceMutex.unlock(); 42 | #endif 43 | } 44 | 45 | void PlatformSoundHelper::PlaySoundFile(std::string const& filename) { 46 | #ifdef _WIN32 47 | PlaySound(filename.c_str(), NULL, SND_ASYNC); 48 | #else 49 | // It would be possible to pre-cache the sounds for SDL_mixer, however instead 50 | // this simply loads plays and unloads them. This closer emulates how PlaySound 51 | // works on Windows and should be fine for this scenario. If, however, it happens 52 | // to give poor results, it should be changed to cache the sounds and take care of 53 | // unloading them properly 54 | std::thread t([=]() { 55 | m_resourceMutex.lock(); 56 | Mix_Chunk* waveSound = Mix_LoadWAV(filename.c_str()); 57 | if (waveSound) { 58 | int channel = Mix_PlayChannel(-1, waveSound, 0); 59 | while (Mix_Playing(channel)) { 60 | // Sleep for a tiny amount of time to avoid maxing out the CPU in an idle loop 61 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 62 | } 63 | Mix_FreeChunk(waveSound); 64 | } 65 | m_resourceMutex.unlock(); 66 | }); 67 | t.detach(); 68 | #endif 69 | } 70 | 71 | SoundMaker::SoundMaker():mInfo(), 72 | altAttackFileName("sounds/arrow.wav"), 73 | healFileName("sounds/heal.wav"), 74 | whetstoneFileName("sounds/whetstone.wav"), 75 | bombFileName("sounds/bomb.wav"), 76 | potionFileName("sounds/potion.wav") { 77 | // 78 | // Initialize file name array to names of files for attacks 79 | // 80 | std::string FileName = SNDDIRECTORY; 81 | if (!mInfo.fileNamePrefix.empty()) { 82 | FileName += mInfo.fileNamePrefix + std::string("_"); 83 | } 84 | attackFileNames.push_back(FileName + ATACKFILENAMEMISS); 85 | attackFileNames.push_back(FileName + ATTACKFILENAME1); 86 | attackFileNames.push_back(FileName + ATTACKFILENAME2); 87 | attackFileNames.push_back(FileName + ATTACKFILENAME3); 88 | attackFileNames.push_back(FileName + ATTACKFILENAMECRIT); 89 | } 90 | 91 | void SoundMaker::PlayPrimaryAttack(int damageDealt) { 92 | // 93 | // play attack sound based on damage delt. 0 is miss, top is 94 | // crit, all other are ramdomized 95 | // 96 | int index = 0; 97 | if (damageDealt > 0 && damageDealt < mInfo.attackRange.second) { 98 | index = Common::RandomInt(1, 3); 99 | } else if (damageDealt >= mInfo.attackRange.second) { 100 | index = 4; 101 | } 102 | PlaySoundFile(attackFileNames[index]); 103 | } 104 | 105 | void SoundMaker::PlaySecondaryAttack(void) { 106 | PlaySoundFile(altAttackFileName.c_str()); 107 | } 108 | 109 | void SoundMaker::PlayHeal(void) { 110 | PlaySoundFile(healFileName.c_str()); 111 | } 112 | 113 | void SoundMaker::PlaySharpen(void) { 114 | PlaySoundFile(whetstoneFileName.c_str()); 115 | } 116 | 117 | void SoundMaker::PlayBomb(void) { 118 | PlaySoundFile(bombFileName.c_str()); 119 | } 120 | 121 | void SoundMaker::PlayPotion(void) { 122 | PlaySoundFile(potionFileName.c_str()); 123 | } 124 | 125 | void SoundMaker::PlaySoundFile(std::string const& filename) { 126 | ms_SoundHelper.PlaySoundFile(filename); 127 | } 128 | -------------------------------------------------------------------------------- /src/Store.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../include/Common.h" 5 | #include "../include/Store.h" 6 | #include "../include/StoreGreetings.h" 7 | #include "../include/ItemTypes.h" 8 | 9 | 10 | using namespace std; 11 | using namespace Common; 12 | 13 | // Messages 14 | const string notEnoughItemsMessage = " Insufficient Items !"; 15 | const string lowCoinsMessage = " Insufficient Coins !"; 16 | const string invalidChoice = " Invalid Choice !"; 17 | 18 | Store::Store() noexcept { 19 | buy_stock = { 20 | {ITEMTYPE::WHETSTONE, {"Whetstone", 1, 20}}, 21 | {ITEMTYPE::POTION, {"Potion", 1, 150}}, 22 | {ITEMTYPE::BOMB, {"Bomb", 1, 100}}, 23 | {ITEMTYPE::ARROWS, {"Arrows", 5, 40}} 24 | }; 25 | sell_stock = { 26 | {ITEMTYPE::WHETSTONE, {"Whetstone", 1, 20}}, 27 | {ITEMTYPE::POTION, {"Potion", 1, 150}}, 28 | {ITEMTYPE::BOMB, {"Bomb", 1, 100}}, 29 | {ITEMTYPE::ARROWS, {"Arrows", 5, 40}} 30 | }; 31 | } 32 | 33 | void Store::StoreFront(Player* _Player) { 34 | // Displays store menu and allows player to buy/sell items. 35 | bool isValidChoice = false; 36 | do { 37 | // Display the store's main menu 38 | DisplayStoreMainMenu(_Player); 39 | // Input choice 40 | unsigned short choice = input(); 41 | cout << endl; 42 | isValidChoice = true; 43 | switch (choice) { 44 | case 1: // Buy 45 | BuyFront(_Player); 46 | break; 47 | case 2: // Sell 48 | SellFront(_Player); 49 | break; 50 | case 0: // Exit 51 | break; 52 | default: 53 | cout << invalidChoice << endl; 54 | isValidChoice = false; 55 | Sleep(SLEEP_MS); 56 | break; 57 | } 58 | } while (!isValidChoice); 59 | } 60 | 61 | void Store::BuyFront(Player* _Player) { 62 | // Displays the buy front 63 | while (true) { 64 | ClearScreen(); 65 | cout << "\n\n"; 66 | _Player->DisplayInventory(); 67 | DisplayStock(buy_stock); 68 | cout << " What do you want to buy today?\n\n "; 69 | int choice = input(); 70 | if (choice == 0 /* exit */) { 71 | break; 72 | } 73 | const auto& item = buy_stock.find(static_cast(choice)); 74 | if (item != std::end(buy_stock)) { 75 | BuyItem(_Player, static_cast(choice), item->second); 76 | } else { 77 | cout << invalidChoice << '\n'; 78 | } 79 | Sleep(SLEEP_MS); 80 | } 81 | } 82 | 83 | void Store::SellFront(Player* _Player) { 84 | // Displays the sell front 85 | while (true) { 86 | ClearScreen(); 87 | cout << "\n\n"; 88 | _Player->DisplayInventory(); 89 | DisplayStock(sell_stock); 90 | cout << " What do you want to sell today?\n\n "; 91 | int choice = input(); 92 | if (choice == 0 /* exit */) { 93 | break; 94 | } 95 | const auto& item = sell_stock.find(static_cast(choice)); 96 | if (item != std::end(sell_stock)) { 97 | SellItem(_Player, static_cast(choice), item->second); 98 | } else { 99 | cout << invalidChoice << '\n'; 100 | } 101 | Sleep(SLEEP_MS); 102 | } 103 | } 104 | 105 | void Store::BuyItem(Player* _Player, ITEMTYPE _Item, ItemInfo _ItemInfo) { 106 | // Buys a specific item, if possible 107 | auto price = _ItemInfo.amount * _ItemInfo.piece_price; 108 | if (_Player->GetCoins() >= price) { 109 | cout << "Bought " << _ItemInfo.amount << ' ' << _ItemInfo.item_name + " !\n"; 110 | _Player->AddStoreItemToInventory(_Item, _ItemInfo.amount); 111 | _Player->LoseCoins(price); 112 | } else { 113 | cout << lowCoinsMessage << '\n'; 114 | } 115 | } 116 | 117 | void Store::SellItem(Player* _Player, ITEMTYPE _Item, ItemInfo _ItemInfo) { 118 | // Sells a specific item from a player. 119 | if (_Player->RemoveStoreItemFromInventory(_Item, _ItemInfo.amount)) { 120 | cout << "Sold " << _ItemInfo.amount << ' ' << _ItemInfo.item_name << " !\n"; 121 | _Player->AddCoins(_ItemInfo.piece_price * _ItemInfo.amount); 122 | } else { 123 | cout << notEnoughItemsMessage << '\n'; 124 | } 125 | } 126 | 127 | void Store::DisplayStock(const catalogue_t& _Catalog) const { 128 | // Displays Jeremy's Tools Store's stock 129 | cout << endl << " Jeremy's Tools Store\n\n"; 130 | cout << " ----ITEM----------------COST------ \n\n"; 131 | int item_idx = 1; 132 | for (const auto& item: _Catalog) { 133 | cout << ' ' + to_string(item_idx++) << ") "; 134 | if (item.second.amount > 1) { 135 | cout << item.second.item_name << " x " << item.second.amount << "\t\t" 136 | << item.second.piece_price * item.second.amount << '\n'; 137 | } else { 138 | cout << item.second.item_name << "\t\t" << item.second.piece_price << '\n'; 139 | } 140 | } 141 | cout << endl << " 0) Exit\n\n"; 142 | cout << " ---------------------------------- \n\n"; 143 | } 144 | 145 | void Store::DisplayStoreMainMenu(Player* _Player) const { 146 | // Displays Jeremy's Tools Store's main menu 147 | ClearScreen(); 148 | cout << endl << endl; 149 | _Player->DisplayInventory(); 150 | cout << endl << " Jeremy's Tools Store\n"; 151 | cout << " \"" << random_greeting() << "\"\n\n"; 152 | cout << " ---------------------------------- \n\n"; 153 | cout << " 1) Buy\n"; 154 | cout << " 2) Sell\n\n"; 155 | cout << " 0) Exit\n\n"; 156 | cout << " ---------------------------------- \n\n"; 157 | cout << " What would you like to do today? \n\n "; 158 | } 159 | -------------------------------------------------------------------------------- /src/Gambling.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | #include 4 | 5 | #include "../include/Common.h" 6 | #include "../include/Gambling.h" 7 | #include "../include/Player.h" 8 | 9 | using namespace std; 10 | using namespace Common; 11 | 12 | // Contains the functions needed to simulate a gamble for items. 13 | 14 | void Gambling::Gamble(Player *_Player) { 15 | // A gambling arena, in which the die you roll must be equal or higher than requirement 16 | // Uses the Player object passed in to give won items to player. 17 | /// Maybe check Coins? If too low then can't gamble. 18 | // Generates random values for the local variables declared in the class. 19 | GenerateValues(); 20 | // check if the player has enough money to play 21 | if (_Player->GetCoins() < CoinsDeduction) { 22 | // the player does not have enough money 23 | cout << "You need at least " << CoinsDeduction << " coins to gamble." << endl; 24 | Sleep(SLEEP_MS); 25 | return; 26 | } 27 | // Player's die. Equal to a random number between 1 and 9. 28 | int Die=ReturnShakenDie(); 29 | // Initialized to analyze user input. 30 | int choice = 0; 31 | // Loops until player chooses to reveal die. 32 | while (choice!=1) { 33 | /// Since the ClearScreen() method is in class Game, system("CLS") is used instead. 34 | /// Must fix. 35 | ClearScreen(); 36 | // Prints required die number to win gamble. 37 | /// Currently says 'REQUIREMENT: 9 and over' when DieRequirement==9, when dies cannot go over 9. 38 | cout << endl << "REQUIREMENT: " << DieRequirement << " and over" << endl; 39 | // Prints the amount of items received if gamble is won. 40 | cout << "PRIZE: [" << ItemNumber << "] "; 41 | // Prints the item name according to the char Item. 42 | switch(Item) { 43 | case 0: 44 | cout << "arrows" << endl; 45 | break; 46 | case 1: 47 | cout << "bombs" << endl; 48 | break; 49 | case 2: 50 | cout << "potions" << endl; 51 | break; 52 | case 3: 53 | cout << "whetstones" << endl; 54 | break; 55 | default: 56 | // No default, since ReturnItem(), which GenerateValue() calls, already has one. 57 | // Technically impossible for char Item to be other than b, p, w, a. 58 | break; 59 | } 60 | // Prints Coins deduction if you lose the gamble. 61 | cout << "PENALTY: [" << CoinsDeduction << "] coins" << endl << endl; 62 | cout << "1) Reveal Die" << endl; 63 | cout << "2) Shake Die" << endl; 64 | cout << "0) Pass" << endl << "\n"; 65 | choice = input(); 66 | switch (choice) { 67 | case 1: 68 | // Only breaks because the loop stops since choice==1. 69 | break; 70 | case 2: 71 | cout << "You shake the die." << endl; 72 | Sleep(SLEEP_MS); 73 | // Generates another random number for the die, simulating the real life die shake. 74 | Die=ReturnShakenDie(); 75 | break; 76 | case 0: 77 | // Returns to Intermission(). 78 | return; 79 | default: 80 | break; 81 | } 82 | } 83 | // Prints what you rolled. 84 | cout << "You rolled a " << Die << "." << endl; 85 | Sleep(SLEEP_MS); 86 | // Evaluates whether or not you won the bet. 87 | if (Die>=DieRequirement) 88 | // Passes in Player object to give player the items won. 89 | { 90 | WinGamble(_Player); 91 | } else 92 | // Passes in Player object to deduct experience from the player for losing the gamble. 93 | { 94 | LoseGamble(_Player); 95 | } 96 | } 97 | 98 | void Gambling::GenerateValues() { 99 | // Generates values for the variables used in the gamble. 100 | // Generates a number between 1 and 9, the number that the player's die must be equal to or greater than. 101 | DieRequirement = Common::RandomInt(1, 9); 102 | // The amount of items won if the player win the gamble. 103 | ItemNumber = Common::RandomInt(1, 4); 104 | // The amount of experience lost if the player loses the gamble. 105 | CoinsDeduction=100; 106 | // Initializes Item equal to a random char to indicate the item won. 107 | Item=ReturnItem(); 108 | } 109 | 110 | int Gambling::ReturnShakenDie() { 111 | // Returns a random integer between 1 and 9. 112 | return Common::RandomInt(1, 9); 113 | } 114 | 115 | char Gambling::ReturnItem() { 116 | // Generates a random char with a random integer selector, indicating the item won in the gamble. 117 | int selector=Common::RandomInt(0, 3); 118 | switch(selector) { 119 | case 0: 120 | // Arrows are the item. 121 | return 0; 122 | case 1: 123 | // Bombs are the item. 124 | return 1; 125 | case 2: 126 | // Potions are the item. 127 | return 2; 128 | case 3: 129 | // Whetstones are the item. 130 | return 3; 131 | default: 132 | // By default, arrows are the item if the random integer does not equal any of the above cases. 133 | return 0; 134 | } 135 | } 136 | 137 | void Gambling::WinGamble(Player *_Player) { 138 | // Executes the events when the gamble is won. 139 | // Uses the Player object to give player items won. 140 | cout << "You win the bet!" << endl; 141 | vector drops; 142 | for (int i = 0; i < NUM_ITEMS; i++) { 143 | drops.push_back((Item == i) ? ItemNumber : 0); 144 | } 145 | // Evaluates local class variable Item to see what item was won. 146 | // ItemNumber is passed in to AddToInventory() to provide the number of items won. 147 | // The place of ItemNumber in the arguments is to specify which item was won. 148 | // More clarification and information in the _Player->AddToInventory(int, int, int ,int) function. 149 | _Player->AddToInventory(drops); 150 | // Used to pause the console to let the player see what they won. 151 | /// Must use something more efficient. 152 | system("PAUSE"); 153 | } 154 | 155 | void Gambling::LoseGamble(Player *_Player) { 156 | // Executes the events when gamble is lost. 157 | // Uses the Player object passed in to deduct experience. 158 | cout << "You lost the bet! You lose " << CoinsDeduction << " coins!" << endl; 159 | // Deducts the player's experience. 160 | _Player->LoseCoins(CoinsDeduction); 161 | system("PAUSE"); 162 | } 163 | -------------------------------------------------------------------------------- /src/Game.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../include/Game.h" 8 | #include "../include/Common.h" 9 | #include "../include/Console.h" 10 | 11 | #include "../include/PlayerTypes/PlayerTypes.h" 12 | #include "../include/EnemyTypes/EnemyTypes.h" 13 | 14 | 15 | using namespace std; 16 | using namespace Common; 17 | 18 | // To avoid conflict with numeric_limits::max used in Game::GetChoice() 19 | #ifdef max 20 | #undef max 21 | #endif 22 | 23 | #define SKIP_TURN -2 24 | 25 | void Game::MainMenu() { 26 | // Main menu. Loops until you start 27 | // a game or quit. 28 | for (int choice=-1; choice!=0;) { 29 | choice = GetChoice(MenuType::eMain); 30 | switch(choice) { 31 | case 1: 32 | StartGame(); 33 | break; 34 | case 2: 35 | HowToPlay(); 36 | break; 37 | case 0: 38 | break; 39 | } 40 | } 41 | } 42 | 43 | string Game::InitializePlayerName() { 44 | ClearScreen(); 45 | string name; 46 | cout << "What is your name?" 47 | << endl << endl 48 | << "> "; 49 | cin.ignore(); 50 | getline(cin, name); // Change to full name 51 | return name; 52 | } 53 | 54 | char Game::InitializePlayerGender() { 55 | char gender; 56 | do { 57 | ClearScreen(); 58 | cout << "What is your gender (M or F)?" 59 | << endl << endl 60 | << "> "; 61 | cin >> gender; 62 | gender = toupper(gender); 63 | } while (gender != 'M' && gender != 'F'); 64 | return gender; 65 | } 66 | 67 | 68 | int Game::InitializePlayerClass() { 69 | // Initializes the player's class through user choice. 70 | int player_class = 0; 71 | player_class = GetChoice(MenuType::ePlayerClass); 72 | SetPlayerClass(player_class); 73 | return player_class; 74 | } 75 | 76 | void Game::SetPlayerClass(int player_class) { 77 | // Sets the Player class according to player code given. 78 | switch (player_class) { 79 | case 1: 80 | // Player's class is a warrior. 81 | _Player = new Warrior; 82 | break; 83 | case 2: 84 | // Player's class is a rogue. 85 | _Player = new Rogue; 86 | break; 87 | case 3: 88 | // Player's class is a healer. 89 | _Player = new Healer; 90 | break; 91 | case 4: 92 | // Player's class is a debugger. 93 | // Used to easily defeat enemies. Only for development purposes. 94 | _Player = new Debugger; 95 | break; 96 | case 5: 97 | // You are Saitama. 98 | // Do I have to explain?? 99 | _Player = new Saitama; 100 | break; 101 | default: 102 | // If input does not equal any of the cases, the default class is a warrior. 103 | _Player = new Warrior; 104 | break; 105 | } 106 | } 107 | 108 | void Game::SetPlayerData() { 109 | /* Data initialized in order of: 110 | * class code 111 | * name 112 | * level 113 | * experience 114 | * health 115 | * arrows 116 | * bombs 117 | * potions 118 | * whetstones 119 | * weaponsharpness 120 | * coins 121 | */ 122 | ifstream ReadData; 123 | ReadData.open("data.txt"); 124 | // Runs if user has never played the game before or data is not found. 125 | if (!ReadData) { 126 | ReadData.close(); 127 | ofstream WriteData; 128 | WriteData.open("data.txt"); 129 | WriteData << InitializePlayerClass() << endl 130 | << InitializePlayerName() << endl 131 | << InitializePlayerGender() << endl 132 | << 1 << endl 133 | << 0 << endl 134 | << 100 << endl 135 | << 10 << endl 136 | << 1 << endl 137 | << 1 << endl 138 | << 1 << endl 139 | << 100 << endl 140 | << 0; 141 | WriteData.close(); 142 | } else { 143 | // Initializes player type from class code given in data.txt 144 | int player_class; 145 | ReadData >> player_class; 146 | SetPlayerClass(player_class); 147 | ReadData.close(); 148 | } 149 | } 150 | 151 | void Game::SetEnemy() { 152 | // Generates a random integer to determine class of the enemy. 153 | // The abstract class Enemy is morphed with one of its child classes. 154 | EnemyType selector = EnemyType(Common::RandomInt(0, etNumEnemyTypes - 1)); 155 | switch(selector) { 156 | case etSlimeball: 157 | // Enemy is a slimeball. 158 | _Enemy = new Slimeball; 159 | break; 160 | case etCrab: 161 | // Enemy is a crab. 162 | _Enemy = new Crab; 163 | break; 164 | case etGiantCrab: 165 | // Enemy is a giant crab. 166 | _Enemy = new GiantCrab; 167 | break; 168 | case etSquid: 169 | // Enemy is a squid. 170 | _Enemy = new Squid; 171 | break; 172 | case etGiantSquid: 173 | // Enemy is a giant squid. 174 | _Enemy = new GiantSquid; 175 | break; 176 | case etMimic: 177 | // Enemy is a Mimic 178 | _Enemy = new Mimic; 179 | break; 180 | case etLich: 181 | // Enemy is a Lich 182 | _Enemy = new Lich; 183 | break; 184 | case etMurloc: 185 | //Enemy is a Murloc 186 | _Enemy = new Murloc; 187 | break; 188 | case etPutnafer: 189 | // Enemy is a Putnafer 190 | _Enemy = new Putnafer; 191 | break; 192 | case etZombie: 193 | // Enemy is a Zombie 194 | _Enemy = new Zombie; 195 | break; 196 | case etVampire: 197 | // Enemy is a Vampire 198 | _Enemy = new Vampire; 199 | break; 200 | case etWerewolf: 201 | // Enemy is a Werewolf 202 | _Enemy = new Werewolf; 203 | break; 204 | case etGoblin: 205 | // Enemy is a Goblin 206 | _Enemy = new Goblin; 207 | break; 208 | case etGargoyle: 209 | // Enemy is a Goblin 210 | _Enemy = new Gargoyle; 211 | break; 212 | case etCerberus: 213 | // Enemy is a Cerberus 214 | _Enemy = new Cerberus; 215 | break; 216 | case etSkeleton: 217 | // Enemy is a Skeleton 218 | _Enemy = new Skeleton; 219 | break; 220 | case etSmallDragon: 221 | // Enemy is a Small Dragon 222 | _Enemy = new SmallDragon; 223 | break; 224 | case etSmallRat: 225 | // Enemy is a Small Rat 226 | _Enemy = new SmallRat; 227 | break; 228 | case etRatKing: 229 | // Enemy is a Rat King 230 | _Enemy = new RatKing; 231 | break; 232 | case etZabra: 233 | _Enemy = new Zabra; 234 | break; 235 | case etGremlin: 236 | //Enemy is a Gremlin 237 | _Enemy = new Gremlin; 238 | break; 239 | case etTimidGhost: 240 | //enemy is a TimidGhost 241 | _Enemy = new TimidGhost; 242 | break; 243 | case etDemon: 244 | //enymy is a Demon 245 | _Enemy = new Demon; 246 | break; 247 | case etDragon: 248 | //enemy is a Dragon 249 | _Enemy = new Dragon; 250 | break; 251 | default: 252 | // If the above cases do not match the selector for any reason, 253 | // the enemy defaults on the crab class. 254 | _Enemy = new Crab; 255 | break; 256 | } 257 | // Simply prints that the enemy's class was encountered. 258 | cout << _Enemy->GetIntro() << endl; 259 | Sleep(SLEEP_MS); 260 | ColourPrint(_Enemy->GetName(), Console::DarkGrey); 261 | cout << " encountered!" << endl << endl; 262 | Sleep(SLEEP_MS); 263 | } 264 | 265 | bool Game::PlayAgain() { 266 | // Returns a bool value to determine if the player wants to play again. 267 | char choice; 268 | cout << "Keep going? (y/n)" << endl << endl; 269 | choice = (char)input(); 270 | // Returns true if the player says yes (Y, y, 1). 271 | if (choice == 'y' || choice == 'Y' || choice == '1') { 272 | return true; 273 | } 274 | // Returns false otherwise, regardless of choice=='n'. 275 | return false; 276 | } 277 | 278 | 279 | void Game::Intermission() { 280 | // Saves game in case player unexpectedly quits (uses X instead of 281 | // in-game quit. 282 | _Player->SaveGame(); 283 | // Loops until the player starts another battle or they quit (IsPlaying=false). 284 | for (int choice=0; IsPlaying;) { 285 | ClearScreen(); 286 | cout << "*--------- Intermission ----------* " << endl << endl; 287 | _Player->DisplayInventory(); 288 | cout << "1) Start battle" << endl; 289 | cout << "2) Store" << endl; 290 | cout << "3) Gamble" << endl; 291 | cout << "4) Use Item" << endl; 292 | cout << "0) Quit" << endl << endl; 293 | choice = input(); 294 | switch(choice) { 295 | case 1: 296 | // Returns to StartGame()'s loop, calling Battle(). 297 | return; 298 | case 2: 299 | // Goes to the store where the player can buy items. 300 | /// Currently in working progress. 301 | _Store.StoreFront(_Player); 302 | break; 303 | case 3: 304 | // Goes to the gambling arena. 305 | // _Player is passed in to add items won to the player inventory. 306 | _Gambling.Gamble(_Player); 307 | break; 308 | case 4: 309 | _Player->UseItem(); 310 | _Player->SaveGame(); 311 | break; 312 | case 0: 313 | // Breaks the loop in StartGame(), going back to MainMenu(). 314 | IsPlaying=false; 315 | break; 316 | } 317 | } 318 | } 319 | 320 | void Game::StartGame() { 321 | // Starts the game by initializing values for a new game. 322 | IsPlaying=true; 323 | // SetPlayerData() initializes the variables in this end. 324 | ClearScreen(); 325 | SetPlayerData(); 326 | // This initializes the variables on the Player end. 327 | ClearScreen(); 328 | _Player->SetPlayerData(); 329 | // Loops while the game is still playing. 330 | // Alternates between battles and intermission (gambling, store, et) 331 | while(IsPlaying) { 332 | Intermission(); 333 | if (!IsPlaying) { 334 | break; 335 | } 336 | Battle(); 337 | } 338 | // Saves the player's data to an external file before quitting. 339 | _Player->SaveGame(); 340 | } 341 | 342 | void Game::Battle() { 343 | ClearScreen(); 344 | // Uses random integers to determine class of the enemy. 345 | SetEnemy(); 346 | // Loops the actual battle while playing. 347 | while(IsPlaying) { 348 | ClearScreen(); 349 | // Displays the name and health bar of the player and enemy. 350 | // The Enemy* argument is to display the enemy's 351 | // name. Explained more in _Player->DisplayHealthBar(). 352 | _Player->DisplayHUD(_Enemy); 353 | _Enemy->DisplayHUD(); 354 | int damagePlayer = _Player->Action(); 355 | // Player's turn to attack Enemy or choose other action. 356 | if (damagePlayer != SKIP_TURN) { 357 | _Enemy->TakeDamage(damagePlayer); 358 | // Pauses console and ignores user input for SLEEP_MS milliseconds. 359 | Sleep(SLEEP_MS); 360 | } 361 | // Leaves battle if player chooses to. 362 | if (!IsPlaying) { 363 | IsPlaying = true; 364 | return; 365 | } 366 | // Executes when the enemy's health is 0 or below. 367 | if (_Enemy->IsDead()) { 368 | // Adds drops to player's inventory from defeated enemy. 369 | _Player->AddToInventory(_Enemy->GetDrops()); 370 | // Adds points to player's experience. 371 | _Player->AddExperience(_Enemy->ReturnExperience()); 372 | // Replenishes player's health for the next round. 373 | _Player->ReplenishHealth(); 374 | // If player wants to battle again, it breaks the loop and uses tail recursion to play again. 375 | if (PlayAgain()) { 376 | break; 377 | } 378 | // Returns to StartGame()'s loop, and executes Intermission(). 379 | return; 380 | } 381 | // Enemy's turn to attack player. 382 | if (damagePlayer != SKIP_TURN) { 383 | _Player->TakeDamage(_Enemy->Action()); 384 | } 385 | Sleep(SLEEP_MS); 386 | // Executes when player's health is 0 or below. 387 | if (_Player->IsDead()) { 388 | // Player loses the amount of experience points gained when you defeat the enemy. 389 | _Player->LoseExperience(_Enemy->ReturnExperience()); 390 | // Replenishes player's health for the next round. 391 | _Player->ReplenishHealth(); 392 | if (PlayAgain()) { 393 | break; 394 | } 395 | return; 396 | } 397 | } 398 | Battle(); 399 | } 400 | 401 | void Game::HowToPlay() { 402 | GetChoice(MenuType::eHowToPlay); 403 | } 404 | 405 | int Game::GetChoice(MenuType menuType) { 406 | DisplayMenu(menuType); 407 | int choice = -1; 408 | while (!(cin >> choice)) { 409 | cin.clear(); 410 | cin.ignore(numeric_limits::max(), '\n'); 411 | cout << "Invalid input. Please try again."; 412 | Sleep(SLEEP_MS); 413 | DisplayMenu(menuType); 414 | } 415 | return choice; 416 | } 417 | 418 | void Game::DisplayMenu(MenuType menuType) { 419 | ClearScreen(); 420 | switch (menuType) { 421 | case Game::eMain: 422 | cout << "========== TURN-BASED FIGHTING GAME ==========" << endl << endl 423 | << "1) Start Game" << endl 424 | << "2) How to play" << endl 425 | << "0) Exit" << endl << endl << "> "; 426 | break; 427 | case Game::ePlayerClass: 428 | cout << endl 429 | << "Which class do you want to play as?" << endl 430 | << "1) Warrior (high damage, low healing capabilities)" << endl 431 | << "2) Rogue (moderate damage, moderate healing capabilities)" << endl 432 | << "3) Healer (low damage, high healing capabilities)" << endl 433 | << "4) Debugger (INFINITE DAMAGE!!!!)" << endl 434 | << "5) Saitama (self-explanatory)" << endl 435 | << endl << endl 436 | << "> "; 437 | break; 438 | case Game::eHowToPlay: 439 | cout << "============== HOW TO PLAY ==============" << endl << endl 440 | << "Turn is a turn-based RPG game." << endl 441 | << "Create your character and start playing." << endl 442 | << "For playing you have to choose what to do by typing" << endl 443 | << "the corresponding number." << endl 444 | << "You can perform actions and use items." << endl << endl 445 | << "-- Actions --" << endl 446 | << "Attack: Regular attack" << endl 447 | << "Risk Attack: Attack deals more damage, but with a chance of missing" << endl 448 | << "Heal: Restore an amount of your HP" << endl 449 | << "Flee: Run away from battle" << endl << endl 450 | << "-- Items --" << endl 451 | << "Bombs: Deals 50HP to your opponent with no chance of missing" << endl 452 | << "Arrows: Deals 10-15HP to your opponent with no chance of missing" << endl 453 | << "Potion: Replenishes your HP to 100" << endl 454 | << "Whetstone: Restores your weapon's sharpness." << endl << endl 455 | << "Good luck and have fun!" << endl << endl 456 | << "0) Back" << endl << endl << "> "; 457 | break; 458 | default: 459 | break; 460 | } 461 | } 462 | -------------------------------------------------------------------------------- /src/Player.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "../include/Common.h" 7 | #include "../include/Player.h" 8 | #include "../include/Console.h" 9 | #include "../include/ItemTypes.h" 10 | 11 | using namespace std; 12 | using namespace Common; 13 | 14 | #define SKIP_TURN -2 15 | 16 | Player::Player(void) { 17 | // Initialize default sounds, attackRange should be 18 | // the result range of the ReturnDamage method in the child class 19 | // Child constructor should call SetSoundInfo with appropriate stuff 20 | SoundInfo info; 21 | info.attackRange = std::make_pair(1, 1); 22 | SetSoundInfo(info); 23 | } 24 | 25 | void Player::SaveGame() { 26 | ofstream WriteData; 27 | WriteData.open("data.txt"); 28 | if (WriteData.is_open()) { 29 | WriteData << player_type << endl 30 | << name << endl 31 | << gender << endl 32 | << level << endl 33 | << experience << endl 34 | << health << endl 35 | << arrows << endl 36 | << bombs << endl 37 | << potions << endl 38 | << whetstones << endl 39 | << weaponsharpness << endl 40 | << coins; 41 | WriteData.close(); 42 | } else { 43 | cout << "Error opening savegame data (data.txt)." << endl; 44 | } 45 | } 46 | 47 | 48 | 49 | void Player::SetPlayerData() { 50 | // Primarily initializes default values at the beginning of the game. 51 | ifstream ReadData; 52 | ReadData.clear(); 53 | ReadData.open("data.txt"); 54 | if (ReadData.is_open()) { 55 | ReadData >> player_type; 56 | ReadData.ignore(); // Ignore rest of line ready for getline 57 | getline(ReadData, name); 58 | ReadData >> gender; 59 | ReadData >> level; 60 | ReadData >> experience; 61 | ReadData >> health; 62 | ReadData >> arrows; 63 | ReadData >> bombs; 64 | ReadData >> potions; 65 | ReadData >> whetstones; 66 | ReadData >> weaponsharpness; 67 | ReadData >> coins; 68 | ReadData.close(); 69 | } else { 70 | cout << "Error opening savegame data (data.txt)." << endl; 71 | } 72 | } 73 | 74 | int Player::Action() { 75 | // Returns the amount of attack points the player gives. 76 | // Also the main battle screen. 77 | int choice = 0; 78 | // Displays the inventory. 79 | DisplayInventory(); 80 | // Gives player a list of moves to choose from. 81 | cout << "Choose your move:" << endl 82 | << "1) Attack" << endl 83 | << "2) Risk Attack" << endl 84 | << "3) Bow and Arrow" << endl 85 | << "4) Heal" << endl << endl 86 | << "5) Use Bomb" << endl 87 | << "6) Use Potion" << endl 88 | << "7) Use Whetstone" << endl 89 | << "0) Get me out of here!" << endl << endl; 90 | while (true) { 91 | choice = input(); 92 | int damage = 0; 93 | // Evaluates player's choice. 94 | switch (choice) { 95 | case 0: 96 | return Flee(); 97 | case 1: 98 | // Player generically attacks. 99 | damage = GenericAttack(); 100 | PlayPrimaryAttack(damage); 101 | return damage; 102 | case 2: 103 | // Player takes a risk and attacks. 104 | damage = RiskAttack(); 105 | PlayPrimaryAttack(damage); 106 | return damage; 107 | case 3: 108 | // Player shoots their bow. 109 | if (arrows > 0) { 110 | PlaySecondaryAttack(); 111 | return BowAndArrow(); 112 | } else { 113 | cout << "No arrows in the inventory!" << endl; 114 | Sleep(SLEEP_MS); 115 | return SKIP_TURN; 116 | } 117 | case 4: 118 | // Player heals, no damage is done to enemy. 119 | PlayHeal(); 120 | Heal(); 121 | return 0; 122 | case 5: 123 | // Player throws a bomb. 124 | // Does not execute if there are no bombs in the inventory. 125 | if (bombs > 0) { 126 | PlayBomb(); 127 | return UseBomb(); 128 | } else { 129 | cout << "No bombs in the inventory!" << endl; 130 | return SKIP_TURN; 131 | } 132 | case 6: 133 | // Player drinks a potion. 134 | // Does not execute if there are no potions in the inventory. 135 | if (potions > 0) { 136 | PlayPotion(); 137 | UsePotion(); 138 | return 0; 139 | } else { 140 | cout << "No potions in the inventory!" << endl; 141 | return SKIP_TURN; 142 | } 143 | case 7: 144 | // Player sharpens their weapon with a whetstone. 145 | // Does not execute if there are no whetstones in inventory. 146 | // No damage is done to the enemy. 147 | if (whetstones > 0) { 148 | PlaySharpen(); 149 | UseWhetstone(); 150 | return 0; 151 | } else { 152 | cout << "No whetstones in the inventory!" << endl; 153 | return SKIP_TURN; 154 | } 155 | default: 156 | // Generically attacks by default if player's choice does not equal above cases. 157 | return GenericAttack(); 158 | } 159 | } 160 | } 161 | 162 | void Player::UseItem() { 163 | // Use item from inventory 164 | int choice = 0; 165 | while (true) { 166 | ClearScreen(); 167 | // Displays the inventory. 168 | DisplayInventory(); 169 | // Gives player a list of moves to choose from. 170 | cout << "Choose which item use:" << endl 171 | << "1) Use Potion" << endl 172 | << "2) Use Whetstone" << endl 173 | << "0) Quit" << endl << endl; 174 | choice = input(); 175 | // Evaluates player's choice. 176 | switch (choice) { 177 | case 0: 178 | return; 179 | case 1: 180 | // Player drinks a potion. 181 | // Does not execute if there are no potions in the inventory. 182 | if (potions > 0) { 183 | UsePotion(); 184 | Sleep(SLEEP_MS); 185 | } else { 186 | cout << "No potions in the inventory!" << endl; 187 | Sleep(SLEEP_MS); 188 | } 189 | break; 190 | case 2: 191 | // Player sharpens their weapon with a whetstone. 192 | // Does not execute if there are no whetstones in inventory. 193 | // No damage is done to the enemy. 194 | if (whetstones > 0) { 195 | UseWhetstone(); 196 | Sleep(SLEEP_MS); 197 | } else { 198 | cout << "No whetstones in the inventory!" << endl; 199 | Sleep(SLEEP_MS); 200 | } 201 | break; 202 | default: 203 | cout<<"Item not present in the inventory!"< drops) { 211 | // Adds items to inventory and prints out what the player received. 212 | // Adds items received to total items. 213 | arrows += drops.at(0); 214 | bombs += drops.at(1); 215 | potions += drops.at(2); 216 | whetstones += drops.at(3); 217 | coins += drops.at(4); 218 | // Prints number of items received. 219 | cout << "You have gained: " << endl; 220 | if (drops[0] > 0) { 221 | cout << "[" << drops.at(0) << "] arrows" << endl; 222 | } 223 | if (drops[1] > 0) { 224 | cout << "[" << drops.at(1) << "] bombs" << endl; 225 | } 226 | if (drops[2] > 0) { 227 | cout << "[" << drops.at(2) << "] potions" << endl; 228 | } 229 | if (drops[3] > 0) { 230 | cout << "[" << drops.at(3) << "] whetstones" << endl; 231 | } 232 | if (drops[4] > 0) { 233 | cout << "[" << drops.at(4) << "] coins" << endl; 234 | } 235 | cout << endl; 236 | } 237 | 238 | void Player::AddStoreItemToInventory(ITEMTYPE type, int amount) { 239 | // Adds items bought to total items. 240 | switch (type) { 241 | case ITEMTYPE::ARROWS: 242 | arrows += amount; 243 | break; 244 | case ITEMTYPE::BOMB: 245 | bombs += amount; 246 | break; 247 | case ITEMTYPE::POTION: 248 | potions += amount; 249 | break; 250 | case ITEMTYPE::WHETSTONE: 251 | whetstones += amount; 252 | break; 253 | } 254 | } 255 | 256 | bool Player::RemoveStoreItemFromInventory(ITEMTYPE type, int amount) { 257 | // Removes sold items from the inventory. 258 | switch (type) { 259 | case ITEMTYPE::ARROWS: 260 | if (arrows >= amount) { 261 | arrows -= amount; 262 | return true; 263 | } 264 | break; 265 | case ITEMTYPE::BOMB: 266 | if (bombs >= amount) { 267 | bombs -= amount; 268 | return true; 269 | } 270 | break; 271 | case ITEMTYPE::POTION: 272 | if (potions >= amount) { 273 | potions -= amount; 274 | return true; 275 | } 276 | break; 277 | case ITEMTYPE::WHETSTONE: 278 | if (whetstones >= amount) { 279 | whetstones -= amount; 280 | return true; 281 | } 282 | break; 283 | } 284 | // Invalid action (insufficient items) 285 | return false; 286 | } 287 | 288 | void Player::DisplayHUD(Enemy *_Enemy) { 289 | // Displays player's name and health bar. Enemy object is used to print name on the same line as player name for aesthetics. 290 | // Prints player's name. 291 | cout << endl; 292 | ColourPrint(name, Console::DarkGrey); 293 | // Tabs to make room for enemy's name. 294 | if (name.length() > 5) { 295 | cout << "\t\t\t"; 296 | } else { 297 | cout <<" \t\t\t"; 298 | } 299 | // Prints enemy name. 300 | ColourPrint(_Enemy->GetName(), Console::DarkGrey); 301 | cout << endl; 302 | DisplayHealthBar(); 303 | } 304 | 305 | void Player::ReplenishHealth() { 306 | // Adds health points after player has defeated an enemy. 307 | if (health <= 0) { 308 | health = 100; 309 | } else { 310 | health += 30; 311 | if (health > 100) { 312 | health = 100; 313 | } 314 | } 315 | } 316 | 317 | void Player::AddExperience(int xp) { 318 | // Adds points to the player's experience and levels player up. 319 | // Adds experience from passed in integer to local class variable experience. 320 | experience += xp; 321 | // Evaluates if experience is higher than 99, which means a level up is in order. 322 | if (experience>99) { 323 | // Experience is set to 0. 324 | experience = 0; 325 | // Player is leveled up. 326 | level+=1; 327 | // Sets level cap to 50, player cannot level higher than that. 328 | if (level >= 50) { 329 | level = 50; 330 | } 331 | // Alerts player that they have leveled up. 332 | cout << "You leveled up! Now you are level " << level << "!" << endl; 333 | Sleep(SLEEP_MS); 334 | } 335 | } 336 | 337 | void Player::LoseExperience(int xp) { 338 | // Deducts points from the player's experience and de-levels player. 339 | // Deducts experience from passed in integer to local class variable experience. 340 | experience -= xp; 341 | // Evaluates if experience is less than 0. 342 | if (experience<0) { 343 | // Experience is deducted continuing from the experience which de-leveled the player (hard to explain...) 344 | experience = 100-(0-experience); 345 | // De-levels player. 346 | level-=1; 347 | // Checks any glitches and sets player level to 1 if level is below 1 or above 50. 348 | // Also resets experience points. 349 | if (level<1 || level>50) { 350 | level=1; 351 | experience = 0; 352 | } 353 | // Alerts the player that they have de-leveled. 354 | else { 355 | cout << "You de-leveled back to level " << level << "..." << endl; 356 | Sleep(SLEEP_MS); 357 | } 358 | } 359 | } 360 | 361 | void Player::AddCoins(int c) { 362 | coins += c; 363 | } 364 | 365 | void Player::LoseCoins(int c) { 366 | coins -= c; 367 | if (coins < 0) { 368 | coins = 0; 369 | } 370 | } 371 | 372 | void Player::DisplayInventory() { 373 | // Checks valid weapon sharpness. 374 | if (weaponsharpness < 0) { 375 | weaponsharpness = 0; 376 | } 377 | // Simply prints the player's inventory. 378 | PrintDivider('*', '-', " INVENTORY "); 379 | PrintXPBar("Level ", level, "", "", experience, "/100 xp"); 380 | PrintClass(); 381 | PrintDivider('+', '-', ""); 382 | PrintInventoryItem("Arrows: [", arrows, "]"); 383 | PrintInventoryItem("Potions: [", potions, "]"); 384 | PrintInventoryItem("Bombs: [", bombs, "]"); 385 | PrintInventoryItem("Whetstones: [", whetstones, "]"); 386 | PrintInventoryItem("Weapon sharpness: [", weaponsharpness, "%]"); 387 | PrintInventoryItem("Wealth: [", coins, "] coins"); 388 | PrintDivider('*', '-', ""); 389 | } 390 | 391 | int Player::GetCoins() { 392 | return coins; 393 | } 394 | 395 | int Player::GenericAttack() { 396 | int damage = ReturnDamage(); 397 | DeductDamage(damage); 398 | ColourPrint(name, Console::DarkGrey); 399 | if (gender == 'M') { 400 | cout << " attacks! He deals "; 401 | } else { 402 | cout << " attacks! She deals "; 403 | } 404 | ColourPrint(to_string(damage), Console::Red); 405 | cout << " damage points!" << endl; 406 | if (damage>0) { 407 | WeakenWeapon(2); 408 | } 409 | return damage; 410 | } 411 | 412 | int Player::RiskAttack() { 413 | int damage = ReturnRiskAttackDamage(); 414 | DeductDamage(damage); 415 | ColourPrint(name, Console::DarkGrey); 416 | cout << " takes a risk and attack! It deals "; 417 | ColourPrint(to_string(damage), Console::Red); 418 | cout << " damage points!" << endl; 419 | if (damage>0) { 420 | WeakenWeapon(4); 421 | } 422 | return damage; 423 | } 424 | 425 | void Player::WeakenWeapon(int impact) { 426 | if (impact >= 0) { 427 | weaponsharpness -= impact + Common::RandomInt(0, 4); 428 | } else { 429 | weaponsharpness -= Common::RandomInt(0, 4); 430 | } 431 | if (weaponsharpness < 0) { 432 | weaponsharpness = 0; 433 | } 434 | } 435 | 436 | int Player::BowAndArrow() { 437 | int damage = ReturnBowDamage(); 438 | ColourPrint(name, Console::DarkGrey); 439 | if (gender == 'M') { 440 | cout << " shoots his bow! He deals "; 441 | } else { 442 | cout << " shoots her bow! She deals "; 443 | } 444 | Console::GetInstance().SetColour(Console::EColour::Red); 445 | cout << damage; 446 | Console::GetInstance().SetColour(Console::EColour::Default); 447 | cout << " damage points!" << endl; 448 | return damage; 449 | } 450 | 451 | void Player::UseWhetstone() { 452 | weaponsharpness=100; 453 | ColourPrint(name, Console::DarkGrey); 454 | if (gender == 'M') { 455 | cout << " sharpened his weapon!" << endl; 456 | } else { 457 | cout << " sharpened her weapon!" << endl; 458 | } 459 | whetstones--; 460 | } 461 | 462 | void Player::UsePotion() { 463 | health=100; 464 | ColourPrint(name, Console::DarkGrey); 465 | cout << " drank a healing potion!" << endl; 466 | potions--; 467 | } 468 | 469 | int Player::UseBomb() { 470 | ColourPrint(name, Console::DarkGrey); 471 | cout << " hurls a bomb! It deals "; 472 | ColourPrint("50", Console::Red); 473 | cout << " damage points!" << endl; 474 | bombs--; 475 | return 50; 476 | } 477 | 478 | void Player::DeductDamage(int& damage) { 479 | if (weaponsharpness<=75&&weaponsharpness>50) { 480 | damage-=1; 481 | } else if (weaponsharpness<=50&&weaponsharpness>30) { 482 | damage-=4; 483 | } else if (weaponsharpness<=30&&weaponsharpness>20) { 484 | damage-=5; 485 | } else if (weaponsharpness<=20&&weaponsharpness>10) { 486 | damage-=6; 487 | } else if (weaponsharpness<=10) { 488 | damage-=7; 489 | } 490 | if (damage<0) { 491 | damage=0; 492 | } 493 | } 494 | 495 | int Player::ReturnBowDamage() { 496 | if (arrows < 1) { 497 | return 0; 498 | } 499 | arrows--; 500 | return Common::RandomInt(10, 15); 501 | } 502 | 503 | int Player::Flee() { 504 | ColourPrint(name, Console::DarkGrey); 505 | cout << " chooses to flee!" << endl; 506 | return -1; 507 | } 508 | 509 | void Player::PrintInventoryItem(string preText, int itemCount, string postText) { 510 | size_t countLength = 0, countCopy = itemCount; 511 | // Calculate length of itemCount 512 | do { 513 | countLength++; 514 | countCopy /= 10; 515 | } while (countCopy); 516 | // Subtract space used in line (4 spaces for front and back dash/space combos, length of start and end text, length of itemCount) from the total available width 517 | size_t freeSpace = 35 - 4 - preText.length() - postText.length() - countLength; 518 | // Create a string with the appropriate number of spaces to make the line meet required width 519 | string spaces(freeSpace, ' '); 520 | // Print the line 521 | cout << "| " << preText << itemCount << postText << spaces << " |" << endl; 522 | } 523 | 524 | void Player::PrintXPBar(string preText1, int level, string postText1, string preText2, int experience, string postText2) { 525 | size_t countLength = 0, levelCopy = level, experienceCopy = experience; 526 | // Calculate length of level and experience 527 | do { 528 | countLength++; 529 | levelCopy /= 10; 530 | } while (levelCopy); 531 | do { 532 | countLength++; 533 | experienceCopy /= 10; 534 | } while (experienceCopy); 535 | // Subtract space used in line (4 spaces for front and back dash/space combos, length of start and end text, length of level and experience) from the total available width 536 | size_t freeSpace = 35 - 4 - preText1.length() - postText1.length() - preText2.length() - postText2.length() - countLength; 537 | // Create a string with the appropriate number of spaces to make the line meet required width 538 | string spaces(freeSpace, ' '); 539 | // Print the line 540 | cout << "| " << preText1 << level << postText1 << spaces << preText2 << experience << postText2 << " |" << endl; 541 | } 542 | 543 | void Player::PrintDivider(char edge, char filler, string centerText) { 544 | // Subtract space used in line (2 spaces for edge symbols, length of centerText) from the total available width 545 | size_t freeSpace = 35 - 2 - centerText.length(); 546 | size_t frontSpace = freeSpace/2; 547 | size_t rearSpace = freeSpace - frontSpace; 548 | // Create a the front and rear filler string 549 | string frontFiller(frontSpace, filler); 550 | string rearFiller(rearSpace, filler); 551 | // Print the line 552 | cout << edge << frontFiller << centerText << rearFiller << edge << endl; 553 | } 554 | void Player::PrintClass() { //print the player class in inventory format 555 | int freespace = 35; //freespace is the amount of blank space in the beginning, backspace is the amount of blankspace after class name print 556 | int backspace = 0; 557 | std::cout << "| "; //begin 558 | switch (player_type) { // get class type and ouput the class name, class type variable is used (declaration located in player.h) 559 | case 1: //following comments are applied to all cases 560 | std::cout << "Warrior"; //output class name 561 | backspace = freespace - 10; //get the amount of blank filler needed 562 | break; 563 | case 2: 564 | std::cout << "Rogue"; 565 | backspace = freespace - 8; 566 | break; 567 | case 3: 568 | std::cout << "Healer"; 569 | backspace = freespace - 9; 570 | break; 571 | case 4: 572 | std::cout << "Debugger"; 573 | backspace = freespace -11; 574 | break; 575 | case 5: 576 | std::cout << "Saitama"; 577 | backspace = freespace - 10; 578 | break; 579 | default: //default makes it warrior in accordance to character creation 580 | std::cout << "Warrior"; 581 | backspace = freespace - 10; 582 | break; 583 | } 584 | string rear(backspace, ' '); //create blank string for filler 585 | std::cout << rear << "|\n"; //output the filler and end 586 | } 587 | --------------------------------------------------------------------------------