Files
pokemon-battle-engine/include/core/pokemon.h
cdemeyer-teachx aff99a507c code refactor
2025-08-20 13:02:04 +09:00

146 lines
5.1 KiB
C++

#ifndef POKEMON_H
#define POKEMON_H
#include "config.h"
#include "stats.h"
#include "types.h"
#include <string>
#include <string_view>
#include <array>
#include <unordered_map>
namespace PokEng {
// Pokemon species data structure
struct PokemonSpecies {
std::string_view name;
uint16_t id;
BaseStats base_stats;
PokemonTypes types;
constexpr PokemonSpecies(uint16_t id_, std::string_view name_,
const BaseStats& stats, const PokemonTypes& types_)
: name(name_), id(id_), base_stats(stats), types(types_) {}
};
// Pokemon Archetype - contains information on how a pokemon will be instantiated
class PokemonArchetype {
public:
PokemonArchetype() = default;
PokemonArchetype(uint16_t species_id, uint8_t level = 50,
Nature nature = Nature::HARDY(),
const IndividualValues& ivs = IndividualValues(),
const EffortValues& evs = EffortValues(),
uint32_t exp = 0)
: m_species_id(species_id), m_level(level), m_nature(nature),
m_ivs(ivs), m_evs(evs), m_exp(exp) {}
// Getters
uint16_t getSpeciesId() const { return m_species_id; }
uint8_t getLevel() const { return m_level; }
Nature getNature() const { return m_nature; }
const IndividualValues& getIVs() const { return m_ivs; }
const EffortValues& getEVs() const { return m_evs; }
uint32_t getExp() const { return m_exp; }
// Setters
void setSpeciesId(uint16_t species_id) { m_species_id = species_id; }
void setLevel(uint8_t level) { m_level = (level > 100) ? 100 : level; }
void setNature(Nature nature) { m_nature = nature; }
void setIVs(const IndividualValues& ivs) { m_ivs = ivs; }
void setEVs(const EffortValues& evs) { if (evs.isValid()) m_evs = evs; }
void setExp(uint32_t exp) { m_exp = exp; }
// Calculate battle stats for different generations
template<Generation Gen>
BattleStats calculateBattleStats() const;
private:
uint16_t m_species_id = 0;
uint8_t m_level = 50;
Nature m_nature = Nature::HARDY();
IndividualValues m_ivs;
EffortValues m_evs;
uint32_t m_exp = 0; // For Gen I & II stat calculations
};
// Pokemon Instance - only contains data needed for battle
class PokemonInstance {
public:
PokemonInstance() = default;
PokemonInstance(uint16_t species_id, const BattleStats& stats,
const PokemonTypes& types, uint8_t friendship = 0)
: m_species_id(species_id), m_battle_stats(stats), m_types(types),
m_current_hp(stats.hp), m_friendship(friendship) {}
// Create from archetype
template<Generation Gen>
static PokemonInstance fromArchetype(const PokemonArchetype& archetype, uint8_t friendship = 0);
// Getters
uint16_t getSpeciesId() const { return m_species_id; }
uint16_t getCurrentHP() const { return m_current_hp; }
uint16_t getMaxHP() const { return m_battle_stats.hp; }
const BattleStats& getBattleStats() const { return m_battle_stats; }
const PokemonTypes& getTypes() const { return m_types; }
Type getPrimaryType() const { return m_types.getPrimary(); }
Type getSecondaryType() const { return m_types.getSecondary(); }
uint8_t getFriendship() const { return m_friendship; }
// Battle stat getters
uint16_t getAttack() const { return m_battle_stats.attack; }
uint16_t getDefense() const { return m_battle_stats.defense; }
uint16_t getSpAttack() const { return m_battle_stats.sp_attack; }
uint16_t getSpDefense() const { return m_battle_stats.sp_defense; }
uint16_t getSpeed() const { return m_battle_stats.speed; }
// Setters
void setCurrentHP(uint16_t hp) {
m_current_hp = (hp > m_battle_stats.hp) ? m_battle_stats.hp : hp;
}
void setFriendship(uint8_t friendship) { m_friendship = friendship; }
// Type-based operations
template <Generation Gen = Generation::I>
uint32_t calculateDamageTaken(uint32_t baseDamage, Type attackType) const {
return calculateDamage<Gen>(baseDamage, attackType, m_types);
}
private:
uint16_t m_species_id = 0;
BattleStats m_battle_stats;
PokemonTypes m_types;
uint16_t m_current_hp = 0;
uint8_t m_friendship = 0;
};
// Pokemon lookup tables for each generation
template<Generation Gen>
class PokemonDataTable {
public:
// Get Pokemon species data by ID
static const PokemonSpecies* getSpecies(uint16_t id);
// Get Pokemon species data by name
static const PokemonSpecies* getSpecies(std::string_view name);
// Check if Pokemon exists in this generation
static bool exists(uint16_t id);
// Get total number of Pokemon in this generation
static size_t getCount();
private:
static const std::unordered_map<uint16_t, PokemonSpecies>& getTable();
static const std::unordered_map<std::string_view, uint16_t>& getNameTable();
};
// Convenience typedefs for different generations
using Gen1PokemonData = PokemonDataTable<Generation::I>;
using Gen2PokemonData = PokemonDataTable<Generation::II>;
using Gen3PokemonData = PokemonDataTable<Generation::III>;
} // namespace PokEng
#endif // POKEMON_H