mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
Scripts/World: drop unnecessary GameTime shenanigans from training dummy's script and correct scripting model for current combat / threading model. The dummy will no longer get stuck in a 'engaged' state.
* additionally the combat times will now be updated in realtime instead of a 500ms interval which will lead to pin-point accurate results.
This commit is contained in:
@@ -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<ObjectGuid, time_t> _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<ObjectGuid /*attackerGUID*/, int32 /*combatTime*/> _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();
|
||||
|
||||
Reference in New Issue
Block a user