diff --git a/Pokemon/Header/Pokemon/Pokemon.hpp b/Pokemon/Header/Pokemon/Pokemon.hpp index d0b2c572..07edbd73 100644 --- a/Pokemon/Header/Pokemon/Pokemon.hpp +++ b/Pokemon/Header/Pokemon/Pokemon.hpp @@ -7,51 +7,58 @@ #include"../Pokemon/Move.hpp" #include"../Pokemon/PokemonType.hpp" #include"../Pokemon/PokemonChoice.hpp" +#include"StatusEffects/IStatusEffect.hpp" +#include"StatusEffects/StatusEffectType.hpp" +#include"StatusEffects/ParalyzedEffect.hpp" + using namespace std; struct Move; namespace N_Pokemon { + using namespace N_StatusEffects; class Pokemon { public: - - // Default constructor - Pokemon(); + //basic attributes + string name; + PokemonType type; + int health; + int maxHealth; + vector moves; + int attackBonus = 0; - // Parameterized constructor + //constructors + Pokemon(); Pokemon(std::string p_name, PokemonType p_type, int p_health, vector p_moves); - - // Copy constructor Pokemon(const Pokemon* other); + //destructor ~Pokemon(); + //battle methods virtual void attack(Move selectedMove, Pokemon* target) = 0; - void heal(); - void takeDamage(int damage); - bool isFainted() const; - //getters and setters + //getter and setter methods string getName(); - void setName(string _name); void selectAndUseMove(Pokemon* target); - void reduceAttackPower(int reducedDamage); + //status effect members + IStatusEffect* appliedEffect; + + bool canAttack(); + void applyEffect(StatusEffectType effectToApply); + void clearEffect(); + bool canApplyEffect(); + protected: - string name; - PokemonType type; - int health; - int maxHealth; - vector moves; - int attackBonus = 0; - + //Pokemon move methods void printAvailableMoves(); int selectMove(); void useMove(Move selectedMove, Pokemon* target); diff --git a/Pokemon/Header/Pokemon/StatusEffects/IStatusEffect.hpp b/Pokemon/Header/Pokemon/StatusEffects/IStatusEffect.hpp new file mode 100644 index 00000000..221940b4 --- /dev/null +++ b/Pokemon/Header/Pokemon/StatusEffects/IStatusEffect.hpp @@ -0,0 +1,26 @@ +#pragma once +#include"../Pokemon.hpp" + +namespace N_Pokemon +{ + namespace N_StatusEffects + { + class IStatusEffect { + public: + // Apply the effect (e.g., poison, burn) + virtual void applyEffect(Pokemon* target) = 0; + + // Get the name of the effect + virtual std::string getEffectName() = 0; + + // Apply the changes due to effect after the end of each turn + // Returns true if the Pokémon can move, else false + virtual bool turnEndEffect(Pokemon* target) = 0; + + // Remove the effect + virtual void clearEffect(Pokemon* target) = 0; + + virtual ~IStatusEffect() = default; + }; + } +} diff --git a/Pokemon/Header/Pokemon/StatusEffects/ParalyzedEffect.hpp b/Pokemon/Header/Pokemon/StatusEffects/ParalyzedEffect.hpp new file mode 100644 index 00000000..c47395cc --- /dev/null +++ b/Pokemon/Header/Pokemon/StatusEffects/ParalyzedEffect.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "IStatusEffect.hpp" + +namespace N_Pokemon +{ + namespace N_StatusEffects + { + class ParalyzedEffect : public IStatusEffect + { + private: + int turnsLeft; // Track the remaining turns for the effect + public: + void applyEffect(Pokemon* target) override; + std::string getEffectName() override; + bool turnEndEffect(Pokemon* target) override; + void clearEffect(Pokemon* target) override; + }; + } +} diff --git a/Pokemon/Header/Pokemon/StatusEffects/StatusEffectType.hpp b/Pokemon/Header/Pokemon/StatusEffects/StatusEffectType.hpp new file mode 100644 index 00000000..9235ccbc --- /dev/null +++ b/Pokemon/Header/Pokemon/StatusEffects/StatusEffectType.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace N_Pokemon +{ + namespace N_StatusEffects + { + enum class StatusEffectType + { + PARALYZED, + SLEEPING, + BURNED, + POISONED + }; + } +} diff --git a/Pokemon/Pokemon.vcxproj b/Pokemon/Pokemon.vcxproj index 2025189d..9418fcab 100644 --- a/Pokemon/Pokemon.vcxproj +++ b/Pokemon/Pokemon.vcxproj @@ -166,6 +166,7 @@ + @@ -179,8 +180,10 @@ + + @@ -192,6 +195,7 @@ + diff --git a/Pokemon/Pokemon.vcxproj.filters b/Pokemon/Pokemon.vcxproj.filters index c78e9074..a122e933 100644 --- a/Pokemon/Pokemon.vcxproj.filters +++ b/Pokemon/Pokemon.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + @@ -113,5 +116,14 @@ Header Files + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/Pokemon/Src/Battle/BattleManager.cpp b/Pokemon/Src/Battle/BattleManager.cpp index 870243e9..6eae9a28 100644 --- a/Pokemon/Src/Battle/BattleManager.cpp +++ b/Pokemon/Src/Battle/BattleManager.cpp @@ -18,26 +18,19 @@ namespace N_Battle } //className* ptrname; declaration //ptrname->name; - void BattleManager::battle() { - while (battleState.battleOngoing) { - if (battleState.playerTurn) { - // Player's turn to attack + void BattleManager::battle() + { + while (battleState.battleOngoing) + { + if (battleState.playerTurn && battleState.playerPokemon->canAttack()) battleState.playerPokemon->selectAndUseMove(battleState.wildPokemon); - } - else { - // Wild Pokémon's turn to attack + else if (battleState.wildPokemon->canAttack()) battleState.wildPokemon->selectAndUseMove(battleState.playerPokemon); - } - // Update the battle state after the turn updateBattleState(); - - // Switch turns battleState.playerTurn = !battleState.playerTurn; - Utility::waitForEnter(); } - handleBattleOutcome(); } diff --git a/Pokemon/Src/Pokemon/Pokemon.cpp b/Pokemon/Src/Pokemon/Pokemon.cpp index 51c5e912..6c02d636 100644 --- a/Pokemon/Src/Pokemon/Pokemon.cpp +++ b/Pokemon/Src/Pokemon/Pokemon.cpp @@ -7,8 +7,11 @@ using namespace std; using namespace N_Utility; + namespace N_Pokemon { + using namespace N_StatusEffects; + Pokemon::Pokemon() { name = "Unknown"; type = PokemonType::NORMAL; @@ -79,8 +82,43 @@ namespace N_Pokemon cout << target->name << " has " << target->health << " HP left.\n"; } + bool Pokemon::canAttack() + { + if (appliedEffect == nullptr) + return true; + else + return appliedEffect->turnEndEffect(this); + } - Pokemon::~Pokemon() { } + bool Pokemon::canApplyEffect() + { + return appliedEffect == nullptr; + } + + void Pokemon::applyEffect(StatusEffectType effectToApply) + { + switch (effectToApply) + { + case StatusEffectType::PARALYZED: + appliedEffect = new ParalyzedEffect(); + appliedEffect->applyEffect(this); + break; + default: + appliedEffect = nullptr; + } + } + + void Pokemon::clearEffect() { appliedEffect = nullptr; } + + void Pokemon::printAvailableMoves() + { + cout << name << "'s available moves:\n"; + + // List out all moves for the player to choose from + for (size_t i = 0; i < moves.size(); ++i) { + cout << i + 1 << ": " << moves[i].name << " (Power: " << moves[i].power << ")\n"; + } + } void Pokemon::attack(Move selectedMove, Pokemon* target) { target->takeDamage((selectedMove.power + attackBonus)); @@ -117,5 +155,9 @@ namespace N_Pokemon { attackBonus -= reducedDamage; } + + + + Pokemon::~Pokemon() { } } \ No newline at end of file diff --git a/Pokemon/Src/Pokemon/Pokemons/Pikachu.cpp b/Pokemon/Src/Pokemon/Pokemons/Pikachu.cpp index 809ca549..160a2810 100644 --- a/Pokemon/Src/Pokemon/Pokemons/Pikachu.cpp +++ b/Pokemon/Src/Pokemon/Pokemons/Pikachu.cpp @@ -25,7 +25,14 @@ namespace N_Pokemon { } else Pokemon::attack(selectedMove, target); + if (selectedMove.name == "THUNDER SHOCK") + { + + if (target->canApplyEffect()) + target->applyEffect(StatusEffectType::PARALYZED); + + } } } } \ No newline at end of file diff --git a/Pokemon/Src/Pokemon/StatusEffects/ParalyzedEffect.cpp b/Pokemon/Src/Pokemon/StatusEffects/ParalyzedEffect.cpp new file mode 100644 index 00000000..d487d36c --- /dev/null +++ b/Pokemon/Src/Pokemon/StatusEffects/ParalyzedEffect.cpp @@ -0,0 +1,53 @@ +#include "../../../Header/Pokemon/StatusEffects/ParalyzedEffect.hpp" +#include "../../../Header/Pokemon/StatusEffects/StatusEffectType.hpp" +#include + +namespace N_Pokemon +{ + namespace N_StatusEffects + { + void ParalyzedEffect::applyEffect(Pokemon* target) + { + std::cout << target->getName() << " is paralyzed! It may not be able to move!\n"; + + // Effect lasts between 1 and 3 turns randomly + turnsLeft = rand() % 3 + 1; + } + + std::string ParalyzedEffect::getEffectName() + { + return "Paralyzed"; + } + + // Determines whether the Pokémon can act at the end of the turn + // Returns false if the paralysis prevents the Pokémon from moving + bool ParalyzedEffect::turnEndEffect(Pokemon* target) + { + if (turnsLeft <= 0) { + clearEffect(target); + return true; // Can move as the effect is cleared + } + turnsLeft--; + + // Generates a number between 0 and 3 + int paralysis_chance = rand() % 4; + + // 25% chance that the Pokémon cannot move due to paralysis + if (paralysis_chance == 0) + { + std::cout << target->getName() << " is paralyzed! It can't move!\n"; + return false; // Pokémon cannot act this turn + } + + // Otherwise, it can act normally + std::cout << target->getName() << " shakes off the paralysis momentarily and can move!\n"; + return true; // Pokémon can act this turn + } + + void ParalyzedEffect::clearEffect(Pokemon* target) + { + std::cout << target->getName() << " is no longer paralyzed!\n"; + target->clearEffect(); + } + } +} \ No newline at end of file