diff --git a/include/AssetManager.h b/include/AssetManager.h index a5f635f..7f84143 100644 --- a/include/AssetManager.h +++ b/include/AssetManager.h @@ -24,7 +24,6 @@ public: AssetManager(Manager* manager); ~AssetManager(); - void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner); void createPowerup(Vector2D pos, std::function pickupFunc, Textures texture); Vector2D calculateSpawnPosition(); diff --git a/include/DataComponent.h b/include/DataComponent.h new file mode 100644 index 0000000..805fd30 --- /dev/null +++ b/include/DataComponent.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include "Component.h" + +class DataComponent : public Component +{ +public: + DataComponent() {}; + ~DataComponent() {}; + /** + * @brief Set a key-value pair of any type in the data map + * @details e.g. setEntry("speed", 180); in this case the key is "speed" and the value is set to an integer of 180 + * @param key The name to store the value under + * @param value The value to store of type T + */ + template + void setEntry(const std::string& key, const T& value) { dataMap.insert_or_assign(key, value); } + + /** + * @brief Get a value of type T from the data map + * @details e.g. getEntry("speed"); in this case the key is "speed" and the value is returned as an integer + * @param key The name to retrieve the value from + * @return An optional of type T containing the value if it exists and matches in typeid, otherwise std::nullopt + */ + template + std::optional getEntry(std::string key) const { + if (!this->dataMap.contains(key)) return std::nullopt; + const std::any& value = this->dataMap.at(key); + if (value.type() != typeid(T)) { return std::nullopt; } + return std::any_cast(value); + } +private: + std::map dataMap; +}; \ No newline at end of file diff --git a/include/Entity.h b/include/Entity.h index 0ce952c..5f8f3cc 100644 --- a/include/Entity.h +++ b/include/Entity.h @@ -102,7 +102,7 @@ public: return *c; }; - template T& getComponent() const //! \returns Component of type T + template T& getComponent() const //!< \todo: rewrite to use optionals { auto ptr(componentArray[getComponentTypeID()]); return *static_cast(ptr); diff --git a/include/PowerupComponent.h b/include/PowerupComponent.h index a0a3f36..7229283 100644 --- a/include/PowerupComponent.h +++ b/include/PowerupComponent.h @@ -6,6 +6,10 @@ class PowerupComponent : public Component { public: + /** + * @brief Construct a new Powerup Component object + * @param func The function to be called when the powerup is picked up + */ PowerupComponent(std::function func); ~PowerupComponent() {}; diff --git a/include/StatEffectsComponent.h b/include/StatEffectsComponent.h index ca32d05..698fc6d 100644 --- a/include/StatEffectsComponent.h +++ b/include/StatEffectsComponent.h @@ -3,11 +3,15 @@ #include "Constants.h" #include #include +#include -enum class Stats -{ - MOVEMENT_SPEED, - ATTACK_SPEED +/** + * @brief Struct to hold the duration, reset function and start time of a stat effect + */ +struct StatEffect { + uint32_t duration; //!< Duration of the effect in milliseconds + std::function resetFunction; //!< Function to reset the effect, will be called on expiry of duration + uint32_t startTime; }; class StatEffectsComponent : public Component{ @@ -17,12 +21,13 @@ public: void init() override; void update(uint_fast16_t diffTime) override; - - void modifyStatDur(Stats stat, int duration, int value); - - void modifyStatValue(Stats stat, int modifier); - void resetStatValue(Stats stat); + /** + * @brief Add a stat effect to the entity + * @param duration The duration of the effect in milliseconds + * @param resetFunction The function to reset the effect, will be called on expiry of duration + */ + void addEffect(uint32_t duration, std::function resetFunction); private: - std::array buffs = { 0 }; + std::vector effects = {}; }; \ No newline at end of file diff --git a/include/TransformComponent.h b/include/TransformComponent.h index c325fce..886e314 100644 --- a/include/TransformComponent.h +++ b/include/TransformComponent.h @@ -3,6 +3,7 @@ #include "Component.h" #include "Vector2D.h" #include "Constants.h" +#include "DataComponent.h" class TransformComponent : public Component { @@ -14,22 +15,14 @@ public: int width = 32; int scale = 1; - int getSpeed() { return speed + speedMod; }; - void resetSpeedMod() { speedMod = 0; }; - - TransformComponent(); - explicit TransformComponent(int scale); - TransformComponent(float x, float y); - TransformComponent(float x, float y, int scale); - TransformComponent(float x, float y, int w, int h, int scale); + explicit TransformComponent(int scale = 1); + TransformComponent(float x, float y, int scale = 1); + TransformComponent(float x, float y, int w, int h, int scale = 1); void init() override; /*! TODO: document usage of collision handler */ void update(uint_fast16_t diffTime) override; void setPositionAfterCollision(Vector2D& positionChange); - void modifySpeed(int8_t modifier); + int getSpeed(); -private: - int speed = 180; - int speedMod = 0; }; diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 75e78ec..85f31e3 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -42,16 +42,6 @@ Mix_Music* AssetManager::getMusic(std::string id) return music.at(id); } -void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner) { - - auto& projectile(man->addEntity()); - projectile.addComponent(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects - projectile.addComponent(textureEnum, 4); - projectile.addComponent(range, speed, velocity, owner); - projectile.addComponent("projectile", 0.6f); - projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE); -} - void AssetManager::createPowerup(Vector2D pos, std::function pickupFunc, Textures texture) { auto& powerups(man->addEntity()); diff --git a/src/StatEffectsComponent.cpp b/src/StatEffectsComponent.cpp index 8d4d7ee..5de70c9 100644 --- a/src/StatEffectsComponent.cpp +++ b/src/StatEffectsComponent.cpp @@ -1,7 +1,6 @@ #include "StatEffectsComponent.h" #include "Entity.h" #include "TransformComponent.h" -// #include "KeyboardController.h" #include #include @@ -10,45 +9,18 @@ void StatEffectsComponent::init() void StatEffectsComponent::update(uint_fast16_t diffTime) { - for (int i = 0; i < MAX_STATS; i++) - { - this->buffs.at(i) -= diffTime; - if (this->buffs.at(i) <= 0) { - this->resetStatValue((Stats)i); + for (auto it = effects.begin(); it != effects.end(); ) { + it->duration -= diffTime; + + if (it->duration <= 0) { + it->resetFunction(); + it = effects.erase(it); + continue; } - } + it++; + } } -void StatEffectsComponent::modifyStatDur(Stats stat, int duration, int value) -{ - if(this->buffs.at((uint8_t)stat) == 0) this->modifyStatValue(stat, value); - this->buffs.at((uint8_t)stat) += duration; -} - -void StatEffectsComponent::modifyStatValue(Stats stat, int modifier) //modifier is basically there so the modifyfuncs in the components know if stats should be increased or decreased -{ - switch (stat) - { - case Stats::MOVEMENT_SPEED: - this->entity->getComponent().modifySpeed(modifier); - break; - case Stats::ATTACK_SPEED: - // this->entity->getComponent().modifyAtkSpeed(modifier); - break; - default: break; - } -} - -void StatEffectsComponent::resetStatValue(Stats stat) -{ - switch (stat) - { - case Stats::MOVEMENT_SPEED: - this->entity->getComponent().resetSpeedMod(); - break; - case Stats::ATTACK_SPEED: - // this->entity->getComponent().resetAtkSpeedMod(); - break; - default: break; - } +void StatEffectsComponent::addEffect(uint32_t duration, std::function resetFunction) { + effects.push_back({duration, resetFunction}); } \ No newline at end of file diff --git a/src/TransformComponent.cpp b/src/TransformComponent.cpp index c50fb5a..12e5ff2 100644 --- a/src/TransformComponent.cpp +++ b/src/TransformComponent.cpp @@ -9,26 +9,16 @@ #include #include #include +#include #include "SoundManager.h" -TransformComponent::TransformComponent() -{ - position.zero(); -} - TransformComponent::TransformComponent(int scale) { position.zero(); this->scale = scale; } -TransformComponent::TransformComponent(float x, float y) -{ - this->position.x = x; - this->position.y = y; -} - TransformComponent::TransformComponent(float x, float y, int scale) { this->position.x = x; @@ -65,9 +55,11 @@ void TransformComponent::update(uint_fast16_t diffTime) position += positionChange; } -void TransformComponent::modifySpeed(int8_t modifier) -{ - this->speedMod += modifier; +int TransformComponent::getSpeed() +{ + return (this->entity->hasComponent() + ? this->entity->getComponent().getEntry("speed").value_or(0) + : 0); } void TransformComponent::setPositionAfterCollision(Vector2D& positionChange)