diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-06-17 21:13:40 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-06-17 21:13:40 +0200 |
commit | 0f0cea104dcceb029fc74e12f60f913e55d267fc (patch) | |
tree | c043240313f9c3103a9e83681598d659314b7f06 | |
parent | 646fa3cb990e115bb9a454f557c93a1213c045c0 (diff) |
Scripts/Misc: Fixed training dummies not entering combat
-rw-r--r-- | src/server/scripts/World/npcs_special.cpp | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index b3dc57cf028..e67823a2939 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1519,7 +1519,10 @@ class npc_brewfest_reveler : public CreatureScript enum TrainingDummy { NPC_ADVANCED_TARGET_DUMMY = 2674, - NPC_TARGET_DUMMY = 2673 + NPC_TARGET_DUMMY = 2673, + + EVENT_TD_CHECK_COMBAT = 1, + EVENT_TD_DESPAWN = 2 }; class npc_training_dummy : public CreatureScript @@ -1532,20 +1535,22 @@ public: npc_training_dummyAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); - entry = creature->GetEntry(); } - uint32 entry; - uint32 resetTimer; - uint32 despawnTimer; + EventMap _events; + std::unordered_map<uint64, time_t> _damageTimes; void Reset() override { me->SetControlled(true, UNIT_STATE_STUNNED);//disable rotate me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);//imune to knock aways like blast wave - resetTimer = 5000; - despawnTimer = 15000; + _events.Reset(); + _damageTimes.clear(); + if (me->GetEntry() != NPC_ADVANCED_TARGET_DUMMY && me->GetEntry() != NPC_TARGET_DUMMY) + _events.ScheduleEvent(EVENT_TD_CHECK_COMBAT, 1000); + else + _events.ScheduleEvent(EVENT_TD_DESPAWN, 15000); } void EnterEvadeMode() override @@ -1556,37 +1561,52 @@ public: Reset(); } - void DamageTaken(Unit* /*doneBy*/, uint32& damage) override + void DamageTaken(Unit* doneBy, uint32& damage) override { - resetTimer = 5000; + me->AddThreat(doneBy, float(damage)); // just to create threat reference + _damageTimes[doneBy->GetGUID()] = time(NULL); damage = 0; } void UpdateAI(uint32 diff) override { - if (!UpdateVictim()) + if (!me->IsInCombat()) return; if (!me->HasUnitState(UNIT_STATE_STUNNED)) me->SetControlled(true, UNIT_STATE_STUNNED);//disable rotate - if (entry != NPC_ADVANCED_TARGET_DUMMY && entry != NPC_TARGET_DUMMY) + _events.Update(diff); + + if (uint32 eventId = _events.ExecuteEvent()) { - if (resetTimer <= diff) + switch (eventId) { - EnterEvadeMode(); - resetTimer = 5000; + case EVENT_TD_CHECK_COMBAT: + { + time_t now = time(NULL); + for (std::unordered_map<uint64, time_t>::iterator 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) + { + if (Unit* unit = ObjectAccessor::GetUnit(*me, itr->first)) + unit->getHostileRefManager().deleteReference(me); + + itr = _damageTimes.erase(itr); + } + else + ++itr; + } + _events.ScheduleEvent(EVENT_TD_CHECK_COMBAT, 1000); + break; + } + case EVENT_TD_DESPAWN: + me->DespawnOrUnsummon(1); + break; + default: + break; } - else - resetTimer -= diff; - return; - } - else - { - if (despawnTimer <= diff) - me->DespawnOrUnsummon(); - else - despawnTimer -= diff; } } |