#include "game/Mobs.h" #include #include namespace td { 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(); } EffectDuration& Mob::getEffect(EffectType effectType){ return *std::find_if(m_Effects.begin(), m_Effects.end(), [&effectType](EffectDuration effect) { return effect.type == effectType;}); } void Mob::addEffect(EffectType effectType, float durationSec, const Tower* tower) { if (isImmuneTo(effectType)) return; if (hasEffect(effectType)) { EffectDuration& effect = getEffect(effectType); if (effect.duration < durationSec) effect.duration = durationSec; // setting new duration if it's greater then the actual } else { m_Effects.push_back({ effectType, durationSec, tower }); } } void Mob::tick(std::uint64_t delta) { updateEffects(delta); } void Mob::updateEffects(std::uint64_t delta) { float deltaSec = (float)delta / 1000.0f; for (std::size_t i = 0; i < m_Effects.size(); i++) { EffectDuration& effect = m_Effects[i]; effect.duration -= deltaSec; if (effect.duration < 0){ // effect has gone m_Effects.erase(m_Effects.begin() + i); switch(effect.type){ case EffectType::Fire:{ m_EffectFireTimer.reset(); break; } case EffectType::Poison:{ m_EffectPoisonTimer.reset(); break; } case EffectType::Heal:{ m_EffectHealTimer.reset(); } default: break; } } } if(hasEffect(EffectType::Fire)){ if(m_EffectFireTimer.update(delta)){ damage(3, getEffect(EffectType::Fire).tower); } } if(hasEffect(EffectType::Poison)){ if(m_EffectPoisonTimer.update(delta)){ damage(3, getEffect(EffectType::Poison).tower); } } if(hasEffect(EffectType::Heal)){ if(m_EffectFireTimer.update(delta)){ heal(10); } } } bool Mob::hasEffect(EffectType type) { return std::find_if(m_Effects.begin(), m_Effects.end(), [&type](EffectDuration effect) { return effect.type == type;}) != m_Effects.end(); } typedef std::pair MobKey; const std::map MobConstants = { // damage speed money_cost exp_cost exp_reward max_health {{MobType::Zombie, 1},{MobStats{1, 1.6, 15, 0, 7, 40}}}, {{MobType::Zombie, 2},{MobStats{1, 1.6, 18, 88, 9, 56}}}, {{MobType::Zombie, 3},{MobStats{1, 1.6, 22, 153, 10, 78}}}, {{MobType::Zombie, 4},{MobStats{1.5, 1.6, 26, 268, 13, 110}}}, {{MobType::Zombie, 5},{MobStats{2, 1.6, 31, 469, 15, 154}}}, {{MobType::Spider, 1},{MobStats{1, 1.6, 25, 100, 15, 80}}}, {{MobType::Spider, 2},{MobStats{1, 2, 30, 175, 16, 112}}}, {{MobType::Spider, 3},{MobStats{1.5, 2, 36, 306, 18, 157}}}, {{MobType::Spider, 4},{MobStats{2.5, 2, 43, 536, 19, 222}}}, {{MobType::Spider, 5},{MobStats{1.5, 2.5, 52, 938, 22, 307}}}, {{MobType::Skeleton, 1},{MobStats{0, 0, 0, 0, 0, 350}}}, {{MobType::Skeleton, 2},{MobStats{0, 0, 0, 0, 0, 490}}}, {{MobType::Skeleton, 3},{MobStats{0, 0, 0, 0, 0, 686}}}, {{MobType::Skeleton, 4},{MobStats{0, 0, 0, 0, 0, 960}}}, {{MobType::Skeleton, 5},{MobStats{0, 0, 0, 0, 0, 1345}}}, {{MobType::Pigman, 1},{MobStats{0, 0, 0, 0, 0, 150}}}, {{MobType::Pigman, 2},{MobStats{0, 0, 0, 0, 0, 210}}}, {{MobType::Pigman, 3},{MobStats{0, 0, 0, 0, 0, 297}}}, {{MobType::Pigman, 4},{MobStats{0, 0, 0, 0, 0, 412}}}, {{MobType::Pigman, 5},{MobStats{0, 0, 0, 0, 0, 576}}}, {{MobType::Creeper, 1},{MobStats{0, 0, 0, 0, 0, 350}}}, {{MobType::Creeper, 2},{MobStats{0, 0, 0, 0, 0, 460}}}, {{MobType::Creeper, 3},{MobStats{0, 0, 0, 0, 0, 630}}}, {{MobType::Creeper, 4},{MobStats{0, 0, 0, 0, 0, 900}}}, {{MobType::Creeper, 5},{MobStats{0, 0, 0, 0, 0, 1250}}}, {{MobType::Silverfish, 1},{MobStats{0, 0, 0, 0, 0, 120}}}, {{MobType::Silverfish, 2},{MobStats{0, 0, 0, 0, 0, 170}}}, {{MobType::Silverfish, 3},{MobStats{0, 0, 0, 0, 0, 225}}}, {{MobType::Silverfish, 4},{MobStats{0, 0, 0, 0, 0, 310}}}, {{MobType::Silverfish, 5},{MobStats{0, 0, 0, 0, 0, 390}}}, {{MobType::Blaze, 1},{MobStats{0, 0, 0, 0, 0, 410}}}, {{MobType::Blaze, 2},{MobStats{0, 0, 0, 0, 0, 574}}}, {{MobType::Blaze, 3},{MobStats{0, 0, 0, 0, 0, 804}}}, {{MobType::Blaze, 4},{MobStats{0, 0, 0, 0, 0, 1125}}}, {{MobType::Blaze, 5},{MobStats{0, 0, 0, 0, 0, 1575}}}, {{MobType::Witch, 1},{MobStats{0, 0, 0, 0, 0, 300}}}, {{MobType::Witch, 2},{MobStats{0, 0, 0, 0, 0, 405}}}, {{MobType::Witch, 3},{MobStats{0, 0, 0, 0, 0, 547}}}, {{MobType::Witch, 4},{MobStats{0, 0, 0, 0, 0, 738}}}, {{MobType::Witch, 5},{MobStats{0, 0, 0, 0, 0, 996}}}, {{MobType::Slime, 1},{MobStats{0, 0, 0, 0, 0, 800}}}, {{MobType::Slime, 2},{MobStats{0, 0, 0, 0, 0, 880}}}, {{MobType::Slime, 3},{MobStats{0, 0, 0, 0, 0, 968}}}, {{MobType::Slime, 4},{MobStats{0, 0, 0, 0, 0, 1065}}}, {{MobType::Slime, 5},{MobStats{0, 0, 0, 0, 0, 1171}}}, {{MobType::Giant, 1},{MobStats{0, 0, 0, 0, 0, 6250}}}, {{MobType::Giant, 2},{MobStats{0, 0, 0, 0, 0, 9375}}}, {{MobType::Giant, 3},{MobStats{0, 0, 0, 0, 0, 14062}}}, {{MobType::Giant, 4},{MobStats{0, 0, 0, 0, 0, 21093}}}, {{MobType::Giant, 5},{MobStats{0, 0, 0, 0, 0, 31640}}}, }; const MobStats* getMobStats(MobType type, std::uint8_t level) { return &MobConstants.at(MobKey{ type, level }); } const std::map MobsTowerImmunities = { {{MobType::Zombie, 1},{}}, {{MobType::Zombie, 2},{}}, {{MobType::Zombie, 3},{}}, {{MobType::Zombie, 4},{}}, {{MobType::Zombie, 5},{}}, {{MobType::Spider, 1},{}}, {{MobType::Spider, 2},{}}, {{MobType::Spider, 3},{}}, {{MobType::Spider, 4},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}}, {{MobType::Spider, 5},{TowerType::Archer, TowerType::Artillery, TowerType::Leach, TowerType::Necromancer, TowerType::Poison, TowerType::Quake, TowerType::Sorcerer, TowerType::Turret, TowerType::Zeus}}, {{MobType::Skeleton, 1},{}}, {{MobType::Skeleton, 2},{}}, {{MobType::Skeleton, 3},{}}, {{MobType::Skeleton, 4},{}}, {{MobType::Skeleton, 5},{}}, {{MobType::Pigman, 1},{TowerType::Zeus}}, {{MobType::Pigman, 2},{TowerType::Zeus}}, {{MobType::Pigman, 3},{TowerType::Zeus}}, {{MobType::Pigman, 4},{TowerType::Zeus}}, {{MobType::Pigman, 5},{TowerType::Zeus}}, {{MobType::Creeper, 1},{}}, {{MobType::Creeper, 2},{}}, {{MobType::Creeper, 3},{}}, {{MobType::Creeper, 4},{}}, {{MobType::Creeper, 5},{}}, {{MobType::Silverfish, 1},{}}, {{MobType::Silverfish, 2},{}}, {{MobType::Silverfish, 3},{}}, {{MobType::Silverfish, 4},{}}, {{MobType::Silverfish, 5},{}}, {{MobType::Blaze, 1},{}}, {{MobType::Blaze, 2},{}}, {{MobType::Blaze, 3},{}}, {{MobType::Blaze, 4},{}}, {{MobType::Blaze, 5},{}}, {{MobType::Witch, 1},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}}, {{MobType::Witch, 2},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}}, {{MobType::Witch, 3},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}}, {{MobType::Witch, 4},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}}, {{MobType::Witch, 5},{TowerType::Zeus, TowerType::Mage, TowerType::Poison}}, {{MobType::Slime, 1},{}}, {{MobType::Slime, 2},{}}, {{MobType::Slime, 3},{}}, {{MobType::Slime, 4},{}}, {{MobType::Slime, 5},{}}, {{MobType::Giant, 1},{}}, {{MobType::Giant, 2},{}}, {{MobType::Giant, 3},{}}, {{MobType::Giant, 4},{}}, {{MobType::Giant, 5},{}}, }; const TowerImmunities& getMobTowerImmunities(MobType type, std::uint8_t level) { return MobsTowerImmunities.at({ type, level }); } const std::map MobsEffectImmunities = { {{MobType::Zombie, 1},{}}, {{MobType::Zombie, 2},{}}, {{MobType::Zombie, 3},{}}, {{MobType::Zombie, 4},{}}, {{MobType::Zombie, 5},{}}, {{MobType::Spider, 1},{}}, {{MobType::Spider, 2},{}}, {{MobType::Spider, 3},{}}, {{MobType::Spider, 4},{}}, {{MobType::Spider, 5},{}}, {{MobType::Skeleton, 1},{}}, {{MobType::Skeleton, 2},{}}, {{MobType::Skeleton, 3},{EffectType::Fire}}, {{MobType::Skeleton, 4},{EffectType::Fire}}, {{MobType::Skeleton, 5},{EffectType::Fire}}, {{MobType::Pigman, 1},{EffectType::Fire}}, {{MobType::Pigman, 2},{EffectType::Fire}}, {{MobType::Pigman, 3},{EffectType::Fire}}, {{MobType::Pigman, 4},{EffectType::Fire}}, {{MobType::Pigman, 5},{EffectType::Fire}}, {{MobType::Creeper, 1},{}}, {{MobType::Creeper, 2},{}}, {{MobType::Creeper, 3},{}}, {{MobType::Creeper, 4},{}}, {{MobType::Creeper, 5},{}}, {{MobType::Silverfish, 1},{}}, {{MobType::Silverfish, 2},{}}, {{MobType::Silverfish, 3},{}}, {{MobType::Silverfish, 4},{EffectType::Fire}}, {{MobType::Silverfish, 5},{EffectType::Fire}}, {{MobType::Blaze, 1},{EffectType::Fire}}, {{MobType::Blaze, 2},{EffectType::Fire}}, {{MobType::Blaze, 3},{EffectType::Fire}}, {{MobType::Blaze, 4},{EffectType::Fire}}, {{MobType::Blaze, 5},{EffectType::Fire}}, {{MobType::Witch, 1},{}}, {{MobType::Witch, 2},{}}, {{MobType::Witch, 3},{}}, {{MobType::Witch, 4},{}}, {{MobType::Witch, 5},{}}, {{MobType::Slime, 1},{}}, {{MobType::Slime, 2},{}}, {{MobType::Slime, 3},{}}, {{MobType::Slime, 4},{EffectType::Fire}}, {{MobType::Slime, 5},{EffectType::Fire}}, {{MobType::Giant, 1},{EffectType::Stun}}, {{MobType::Giant, 2},{EffectType::Stun}}, {{MobType::Giant, 3},{EffectType::Stun}}, {{MobType::Giant, 4},{EffectType::Stun}}, {{MobType::Giant, 5},{EffectType::Stun}}, }; const EffectImmunities& getMobEffectImmunities(MobType type, std::uint8_t level) { return MobsEffectImmunities.at({ type, level }); } MobPtr MobFactory::createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender) { using MobCreator = std::function(MobID, std::uint8_t, PlayerID)>; static std::map mobFactory = { {MobType::Zombie, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Spider, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Skeleton, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Pigman, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Creeper, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Silverfish, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Blaze, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Witch, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Slime, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, {MobType::Giant, [](MobID id, std::uint8_t level, PlayerID sender) -> MobPtr {return std::make_shared(id, level, sender);} }, }; return mobFactory[type](id, level, sender); } std::string MobFactory::getMobName(MobType type){ switch(type){ case MobType::Zombie: return "Zombie"; case MobType::Spider: return "Spider"; case MobType::Skeleton: return "Skeleton"; case MobType::Pigman: return "Pigman"; case MobType::Creeper: return "Creeper"; case MobType::Silverfish: return "Silverfish"; case MobType::Blaze: return "Blaze"; case MobType::Witch: return "Witch"; case MobType::Slime: return "Slime"; case MobType::Giant: return "Giant"; default: return "Unknow"; } } } // namespace game } // namespace td