feat: implement freeze effect

This commit is contained in:
2021-10-08 19:04:26 +02:00
parent 48b5372533
commit 4fcf25b5bc
5 changed files with 79 additions and 5 deletions

View File

@@ -34,6 +34,7 @@ typedef std::uint32_t MobID;
typedef std::uint8_t MobLevel; typedef std::uint8_t MobLevel;
typedef std::vector<TowerType> TowerImmunities; typedef std::vector<TowerType> TowerImmunities;
typedef std::vector<EffectType> EffectImmunities; typedef std::vector<EffectType> EffectImmunities;
typedef std::pair<EffectType, float> EffectDuration;
class MobStats { class MobStats {
private: private:
@@ -71,6 +72,7 @@ private:
PlayerID m_Sender; PlayerID m_Sender;
MobLevel m_Level; MobLevel m_Level;
Direction m_Direction; Direction m_Direction;
std::vector<EffectDuration> m_Effects;
float m_X = 0, m_Y = 0; float m_X = 0, m_Y = 0;
public: public:
@@ -80,7 +82,7 @@ public:
virtual MobType getType() const = 0; virtual MobType getType() const = 0;
virtual void tick(std::uint64_t delta) {} virtual void tick(std::uint64_t delta);
const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); } const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); }
const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); } const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); }
@@ -99,10 +101,19 @@ public:
float getY() const { return m_Y; } float getY() const { return m_Y; }
void setY(float y) { m_Y = y; } void setY(float y) { m_Y = y; }
bool isImmuneTo(TowerType type);
bool isImmuneTo(EffectType type);
void addEffect(EffectType type, float durationSec);
bool hasEffect(EffectType type);
Direction getDirection() const { return m_Direction; } Direction getDirection() const { return m_Direction; }
void setDirection(Direction dir) { m_Direction = dir; } void setDirection(Direction dir) { m_Direction = dir; }
protected: protected:
void initHealth() { m_Health = (float)getStats()->getMaxLife(); } void initHealth() { m_Health = (float)getStats()->getMaxLife(); }
private:
void updateEffects(std::uint64_t delta);
}; };
typedef std::shared_ptr<Mob> MobPtr; typedef std::shared_ptr<Mob> MobPtr;

View File

@@ -187,6 +187,7 @@ public:
virtual void OnArrowShot(MobPtr target, Tower* shooter); virtual void OnArrowShot(MobPtr target, Tower* shooter);
private: private:
void moveMobs(std::uint64_t delta); void moveMobs(std::uint64_t delta);
void tickMobs(std::uint64_t delta);
void cleanDeadMobs(); void cleanDeadMobs();
}; };

View File

@@ -1,9 +1,53 @@
#include "game/Mobs.h" #include "game/Mobs.h"
#include <map> #include <map>
#include <algorithm>
namespace td { namespace td {
namespace game { namespace game {
bool Mob::isImmuneTo(TowerType type) {
return std::find(getTowerImmunities().begin(), getTowerImmunities().end(), type) != getTowerImmunities().end();
}
bool Mob::isImmuneTo(EffectType type) {
return std::find(getEffectImmunities().begin(), getEffectImmunities().end(), type) != getEffectImmunities().end();
}
void Mob::addEffect(EffectType effectType, float durationSec) {
if (isImmuneTo(effectType))
return;
if (hasEffect(effectType)) {
auto it = std::find_if(m_Effects.begin(), m_Effects.end(), [&effectType](EffectDuration effect){ return effect.first == effectType;});
EffectDuration& effect = *it;
if(effect.second < durationSec)
effect.second = durationSec; // setting new duration if it's greater then the actual
} else {
m_Effects.push_back({ effectType, durationSec });
}
}
void Mob::tick(std::uint64_t delta) {
updateEffects(delta);
}
void Mob::updateEffects(std::uint64_t delta) {
float deltaSec = (float)delta / 1000.0f;
for (auto it = m_Effects.begin(); it != m_Effects.end(); it++) {
EffectDuration& effect = *it;
effect.second -= deltaSec;
if (effect.second < 0) // effect has gone
m_Effects.erase(it);
}
}
bool Mob::hasEffect(EffectType type) {
return std::find_if(m_Effects.begin(), m_Effects.end(), [&type](EffectDuration effect){ return effect.first == type;}) != m_Effects.end();
}
typedef std::pair<MobType, std::uint8_t> MobKey; typedef std::pair<MobType, std::uint8_t> MobKey;
const std::map<MobKey, MobStats> MobConstants = { const std::map<MobKey, MobStats> MobConstants = {

View File

@@ -28,7 +28,7 @@ const std::map<std::pair<TowerType, TowerLevel>, TowerStats> TowerConstants = {
{{TowerType::Ice, {1, TowerPath::Top}}, {1, 0, 10}}, {{TowerType::Ice, {1, TowerPath::Top}}, {1, 0, 10}},
{{TowerType::Ice, {2, TowerPath::Top}}, {1, 0, 12}}, {{TowerType::Ice, {2, TowerPath::Top}}, {1, 0, 12}},
{{TowerType::Ice, {3, TowerPath::Top}}, {1, 0, 13}}, {{TowerType::Ice, {3, TowerPath::Top}}, {1, 0, 13}},
{{TowerType::Ice, {4, TowerPath::Top}}, {1, 0, 15}}, {{TowerType::Ice, {4, TowerPath::Top}}, {1, 4, 15}},
//----------------------------------------------------------------- //-----------------------------------------------------------------
@@ -183,7 +183,15 @@ void ArcherTower::tick(std::uint64_t delta, World* world) {
} }
void IceTower::tick(std::uint64_t delta, World* world) { void IceTower::tick(std::uint64_t delta, World* world) {
if (m_Timer.update(delta)) {
float damage = getStats()->getDamage();
for (MobPtr mob : world->getMobList()) {
if (isMobInRange(mob)) {
mob->addEffect(EffectType::Slowness, 1); // slowness for 1s every second
mob->damage(damage);
}
}
}
} }
void MageTower::tick(std::uint64_t delta, World* world) { void MageTower::tick(std::uint64_t delta, World* world) {

View File

@@ -321,6 +321,7 @@ bool World::saveMap(const std::string& fileName) const {
void World::tick(std::uint64_t delta) { void World::tick(std::uint64_t delta) {
moveMobs(delta); moveMobs(delta);
tickMobs(delta);
for(TowerPtr tower : m_Towers){ for(TowerPtr tower : m_Towers){
tower->tick(delta, this); tower->tick(delta, this);
} }
@@ -341,6 +342,12 @@ TowerPtr World::placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::in
return tower; return tower;
} }
void World::tickMobs(std::uint64_t delta) {
for(MobPtr mob : m_Mobs) {
mob->tick(delta);
}
}
void World::moveMobs(std::uint64_t delta) { void World::moveMobs(std::uint64_t delta) {
for (MobPtr mob : m_Mobs) { for (MobPtr mob : m_Mobs) {
TilePtr tile = getTile(mob->getX(), mob->getY()); TilePtr tile = getTile(mob->getX(), mob->getY());
@@ -354,6 +361,9 @@ void World::moveMobs(std::uint64_t delta) {
float walkAmount = mobWalkSpeed * ((float)delta / 1000.0f); float walkAmount = mobWalkSpeed * ((float)delta / 1000.0f);
if(mob->hasEffect(EffectType::Slowness))
walkAmount *= 0.70;
switch (mob->getDirection()) { switch (mob->getDirection()) {
case Direction::NegativeX: { case Direction::NegativeX: {
mob->setX(mob->getX() - walkAmount); mob->setX(mob->getX() - walkAmount);