146 lines
5.1 KiB
C++
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
|