diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 6b0291c8581..112feea35f0 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1724,104 +1724,65 @@ enum TrainingDummy SPELL_ARCANE_MISSILES = 5143, }; -class npc_training_dummy : public CreatureScript +struct npc_training_dummy : NullCreatureAI { -public: - npc_training_dummy() : CreatureScript("npc_training_dummy") { } - - struct npc_training_dummyAI : PassiveAI + npc_training_dummy(Creature* creature) : NullCreatureAI(creature) { - npc_training_dummyAI(Creature* creature) : PassiveAI(creature), _combatCheckTimer(500) - { - uint32 const entry = me->GetEntry(); - if (entry == NPC_TARGET_DUMMY || entry == NPC_ADVANCED_TARGET_DUMMY) - { - _combatCheckTimer = 0; - me->DespawnOrUnsummon(16s); - } - } + uint32 const entry = me->GetEntry(); + if (entry == NPC_TARGET_DUMMY || entry == NPC_ADVANCED_TARGET_DUMMY) + me->DespawnOrUnsummon(16s); + } - void Reset() override - { - _damageTimes.clear(); - } + void DamageTaken(Unit* attacker, uint32& damage) override + { + damage = 0; - void EnterEvadeMode(EvadeReason why) override - { - if (!_EnterEvadeMode(why)) - return; + if (!attacker) + return; - Reset(); - } + _combatTimer[attacker->GetGUID()] = int32(5 * IN_MILLISECONDS); + } - void DamageTaken(Unit* doneBy, uint32& damage) override + // Todo: the involved training dummys have a proc aura for that. Drop this part here, once converted. + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + switch (spell->Id) { - _damageTimes[doneBy->GetGUID()] = GameTime::GetGameTime(); - damage = 0; - } - - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - switch (spell->Id) - { - case SPELL_CHARGE: // Charge - Warrior - case SPELL_JUDGEMENT: // Judgement - Paladin - case SPELL_STEADY_SHOT: // Steady Shot - Hunter - case SPELL_EVISCERATE: // Eviscerate - Rouge - case SPELL_PRIMAL_STRIKE: // Primal Strike - Shaman - case SPELL_IMMOLATE: // Immolate - Warlock - case SPELL_ARCANE_MISSILES: // Arcane Missiles - Mage + case SPELL_CHARGE: // Charge - Warrior + case SPELL_JUDGEMENT: // Judgement - Paladin + case SPELL_STEADY_SHOT: // Steady Shot - Hunter + case SPELL_EVISCERATE: // Eviscerate - Rouge + case SPELL_PRIMAL_STRIKE: // Primal Strike - Shaman + case SPELL_IMMOLATE: // Immolate - Warlock + case SPELL_ARCANE_MISSILES: // Arcane Missiles - Mage if (caster->GetTypeId() == TYPEID_PLAYER) caster->ToPlayer()->KilledMonsterCredit(NPC_SPELL_PRACTICE_CREDIT); break; default: break; - } } - - void UpdateAI(uint32 diff) override - { - if (!_combatCheckTimer || !me->IsInCombat()) - return; - - if (diff < _combatCheckTimer) - { - _combatCheckTimer -= diff; - return; - } - - _combatCheckTimer = 500; - - time_t const now = GameTime::GetGameTime(); - auto const& pveRefs = me->GetCombatManager().GetPvECombatRefs(); - for (auto itr = _damageTimes.begin(); itr != _damageTimes.end();) - { - // If unit has not dealt damage to training dummy for 5 seconds, remove him from combat - if (itr->second < now - 5) - { - auto it = pveRefs.find(itr->first); - if (it != pveRefs.end()) - it->second->EndCombat(); - - itr = _damageTimes.erase(itr); - } - else - ++itr; - } - - for (auto const& pair : pveRefs) - if (_damageTimes.find(pair.first) == _damageTimes.end()) - _damageTimes[pair.first] = now; - } - - std::unordered_map _damageTimes; - uint32 _combatCheckTimer; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_training_dummyAI(creature); } + + void UpdateAI(uint32 diff) override + { + for (auto itr = _combatTimer.begin(); itr != _combatTimer.end();) + { + itr->second -= diff; + if (itr->second <= 0) + { + auto const& pveRefs = me->GetCombatManager().GetPvECombatRefs(); + auto it = pveRefs.find(itr->first); + if (it != pveRefs.end()) + it->second->EndCombat(); + + itr = _combatTimer.erase(itr); + } + else + ++itr; + } + } +private: + std::unordered_map _combatTimer; }; /*###### @@ -3210,7 +3171,7 @@ void AddSC_npcs_special() new npc_tonk_mine(); new npc_tournament_mount(); new npc_brewfest_reveler(); - new npc_training_dummy(); + RegisterCreatureAI(npc_training_dummy); new npc_wormhole(); new npc_pet_trainer(); new npc_experience();