R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
BuffSystem.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** RTYPE
4** File description:
5** BuffSystem implementation
6*/
7
8#include "BuffSystem.hpp"
9#include <algorithm>
11
12namespace ecs {
13
14 void BuffSystem::update(Registry &registry, float deltaTime) {
15 // Get all entities with Buff component
16 auto entities = registry.view<Buff>();
17
18 for (auto entity : entities) {
19 Buff &buff = registry.getComponent<Buff>(entity);
20
21 // Update buff timers and remove expired ones
22 _updateBuffTimers(buff, deltaTime);
23
24 // Apply buff effects to entity stats
25 if (buff.hasAnyBuffs()) {
26 _applyBuffEffects(entity, registry, buff);
27 }
28
29 // Remove Buff component if no buffs remain
30 if (!buff.hasAnyBuffs()) {
31 registry.removeComponent<Buff>(entity);
32 }
33 }
34 }
35
37 ComponentMask mask = 0;
38 mask |= (1ULL << getComponentType<Buff>());
39 return mask;
40 }
41
42 void BuffSystem::_updateBuffTimers(Buff &buff, float deltaTime) {
43 auto &buffs = buff.getBuffsMutable();
44
45 // Remove expired buffs
46 auto initialSize = buffs.size();
47 buffs.erase(std::remove_if(buffs.begin(), buffs.end(),
48 [deltaTime](BuffInstance &b) {
49 if (b.isPermanent) {
50 return false; // Never remove permanent buffs
51 }
52 b.duration -= deltaTime;
53 if (b.duration <= 0.0f) {
54 // Log expired buff
55 const char *buffName = "Unknown";
56 switch (b.type) {
58 buffName = "SpeedBoost";
59 break;
61 buffName = "DamageBoost";
62 break;
64 buffName = "FireRateBoost";
65 break;
67 buffName = "Shield";
68 break;
70 buffName = "HealthRegen";
71 break;
72 default:
73 break;
74 }
75 LOG_INFO("[BUFF] ", buffName, " expired");
76 return true;
77 }
78 return false;
79 }),
80 buffs.end());
81
82 if (buffs.size() < initialSize) {
83 LOG_DEBUG("[BUFF] Removed ", (initialSize - buffs.size()), " expired buff(s)");
84 }
85 }
86
87 void BuffSystem::_applyBuffEffects(Address address, Registry &registry, const Buff &buff) {
88 const auto &buffs = buff.getBuffs();
89
90 for (const auto &b : buffs) {
91 switch (b.type) {
92 case BuffType::SpeedBoost:
93 if (registry.hasComponent<Velocity>(address)) {
94 Velocity &vel = registry.getComponent<Velocity>(address);
95 _applySpeedBoost(vel, b.value);
96 }
97 break;
98
99 case BuffType::DamageBoost:
100 if (registry.hasComponent<Weapon>(address)) {
101 Weapon &weapon = registry.getComponent<Weapon>(address);
102 _applyDamageBoost(weapon, b.value);
103 }
104 break;
105
106 case BuffType::FireRateBoost:
107 if (registry.hasComponent<Weapon>(address)) {
108 Weapon &weapon = registry.getComponent<Weapon>(address);
109 _applyFireRateBoost(weapon, b.value);
110 }
111 break;
112
113 case BuffType::Shield:
114 if (registry.hasComponent<Health>(address)) {
115 Health &health = registry.getComponent<Health>(address);
116 _applyShield(health, b.duration);
117 }
118 break;
119
120 case BuffType::HealthRegen:
121 if (registry.hasComponent<Health>(address)) {
122 Health &health = registry.getComponent<Health>(address);
123 // b.value = regen rate (HP per second)
124 _applyHealthRegen(health, 0.016f, b.value); // Assume ~60 FPS
125 }
126 break;
127
128 // Permanent buffs (modify behavior, handled by weapon system)
129 case BuffType::MultiShot:
130 case BuffType::DoubleShot:
131 case BuffType::TripleShot:
132 case BuffType::PiercingShot:
133 case BuffType::HomingShot:
134 // These are checked by WeaponSystem when firing
135 break;
136
137 case BuffType::MaxHealthIncrease:
138 // Already applied when buff was added (permanent increase)
139 // No per-frame processing needed
140 break;
141 }
142 }
143 }
144
145 void BuffSystem::_applySpeedBoost(Velocity &velocity, float multiplier) {
146 // Apply speed multiplier to base speed
147 float baseSpeed = velocity.getBaseSpeed();
148 float newSpeed = baseSpeed * multiplier;
149 velocity.setSpeed(newSpeed);
150 }
151
152 void BuffSystem::_applyDamageBoost(Weapon &weapon, float multiplier) {
153 // Apply damage multiplier to base damage
154 int baseDamage = weapon.getBaseDamage();
155 int newDamage = static_cast<int>(baseDamage * multiplier);
156 weapon.setDamage(newDamage);
157 }
158
159 void BuffSystem::_applyFireRateBoost(Weapon &weapon, float multiplier) {
160 // Apply fire rate multiplier to base fire rate
161 float baseFireRate = weapon.getBaseFireRate();
162 float newFireRate = baseFireRate * multiplier;
163 weapon.setFireRate(newFireRate);
164 }
165
166 void BuffSystem::_applyShield(Health &health, float duration) {
167 if (duration > 0.0f) {
168 health.setInvincible(true);
169 health.setInvincibilityTimer(duration);
170 }
171 }
172
173 void BuffSystem::_applyHealthRegen(Health &health, float deltaTime, float regenRate) {
174 int currentHealth = health.getCurrentHealth();
175 int maxHealth = health.getMaxHealth();
176
177 if (currentHealth < maxHealth) {
178 float regenAmount = regenRate * deltaTime;
179 int newHealth = std::min(currentHealth + static_cast<int>(regenAmount), maxHealth);
180 health.setCurrentHealth(newHealth);
181 }
182 }
183
184} // namespace ecs
#define LOG_INFO(...)
Definition Logger.hpp:181
#define LOG_DEBUG(...)
Definition Logger.hpp:180
void _applyBuffEffects(Address address, Registry &registry, const Buff &buff)
Apply buff effects to entity stats.
void update(Registry &registry, float deltaTime) override
Update buff timers and apply effects.
void _updateBuffTimers(Buff &buff, float deltaTime)
Update buff timers and remove expired ones.
ComponentMask getComponentMask() const override
Gets the component mask for this system.
Component managing active buffs on an entity.
Definition Buff.hpp:58
std::vector< BuffInstance > & getBuffsMutable()
Get mutable reference to buffs (for system updates)
Definition Buff.hpp:145
const std::vector< BuffInstance > & getBuffs() const
Get all active buffs.
Definition Buff.hpp:139
bool hasAnyBuffs() const
Check if any buffs are active.
Definition Buff.hpp:151
Component representing entity health and invincibility.
Definition Health.hpp:20
int getCurrentHealth() const
Get current health points.
Definition Health.hpp:44
void setInvincible(bool invincible)
Set invincibility state.
Definition Health.hpp:80
void setInvincibilityTimer(float timer)
Set invincibility timer.
Definition Health.hpp:86
void setCurrentHealth(int health)
Set current health.
Definition Health.hpp:74
int getMaxHealth() const
Get maximum health points.
Definition Health.hpp:50
Manages entities, their signatures and component type registrations.
Definition Registry.hpp:68
void removeComponent(Address address)
Remove a component from an entity.
T & getComponent(Address address)
Get a component from an entity.
bool hasComponent(Address address)
Check if an entity has a specific component.
std::vector< Address > view()
Get all entities that have a specific set of components.
Component representing movement direction and speed.
Definition Velocity.hpp:20
void setSpeed(float speed)
Set the movement speed.
Definition Velocity.hpp:73
float getBaseSpeed() const
Get the base movement speed (before buffs).
Definition Velocity.hpp:57
Component for entities capable of shooting projectiles.
Definition Weapon.hpp:28
float getBaseFireRate() const
Get base fire rate (before buffs).
Definition Weapon.hpp:80
void setFireRate(float fireRate)
Set fire rate.
Definition Weapon.hpp:92
void setDamage(float damage)
Set damage value.
Definition Weapon.hpp:110
int getBaseDamage() const
Get base damage (before buffs).
Definition Weapon.hpp:86
Maximum number of distinct component types supported by the Registry.
Definition GameLogic.hpp:26
@ DamageBoost
Increases weapon damage.
@ FireRateBoost
Increases fire rate.
@ Shield
Temporary invincibility.
@ HealthRegen
Regenerates health over time.
@ SpeedBoost
Increases movement speed.
std::uint32_t Address
Type used to represent an entity address/ID.
std::uint64_t ComponentMask
Type alias for component bitmask.
Definition ISystem.hpp:24
Individual buff with its properties.
Definition Buff.hpp:41
float duration
Remaining duration (0.0f = permanent)
Definition Buff.hpp:43
BuffType type
Type of buff.
Definition Buff.hpp:42