/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
/*
* Ordered alphabetically using scriptname.
* Scriptnames of files in this file should be prefixed with "npc_pet_hun_".
*/
#include "ScriptMgr.h"
#include "Containers.h"
#include "CreatureAIImpl.h"
#include "ScriptedCreature.h"
#include "TemporarySummon.h"
enum HunterSpells
{
SPELL_HUNTER_CRIPPLING_POISON = 30981, // Viper
SPELL_HUNTER_DEADLY_POISON_PASSIVE = 34657, // Venomous Snake
SPELL_HUNTER_MIND_NUMBING_POISON = 25810 // Viper
};
enum HunterCreatures
{
NPC_HUNTER_VIPER = 19921
};
struct npc_pet_hunter_snake_trap : public ScriptedAI
{
npc_pet_hunter_snake_trap(Creature* creature) : ScriptedAI(creature), _isViper(false), _spellTimer(0) { }
void JustEngagedWith(Unit* /*who*/) override { }
void JustAppeared() override
{
_isViper = me->GetEntry() == NPC_HUNTER_VIPER ? true : false;
me->SetMaxHealth(uint32(107 * (me->GetLevel() - 40) * 0.025f));
// Add delta to make them not all hit the same time
me->SetBaseAttackTime(BASE_ATTACK, me->GetBaseAttackTime(BASE_ATTACK) + urandms(0,6));
if (!_isViper && !me->HasAura(SPELL_HUNTER_DEADLY_POISON_PASSIVE))
DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true);
}
// Redefined for random target selection:
void MoveInLineOfSight(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override
{
if (me->GetVictim() && me->GetVictim()->HasBreakableByDamageCrowdControlAura())
{ // don't break cc
me->GetThreatManager().ClearFixate();
me->InterruptNonMeleeSpells(false);
me->AttackStop();
return;
}
if (me->IsSummon() && !me->GetThreatManager().GetFixateTarget())
{ // find new target
Unit* summoner = me->ToTempSummon()->GetSummonerUnit();
std::vector targets;
auto addTargetIfValid = [this, &targets, summoner](CombatReference* ref) mutable
{
Unit* enemy = ref->GetOther(summoner);
if (!enemy->HasBreakableByDamageCrowdControlAura() && me->CanCreatureAttack(enemy) && me->IsWithinDistInMap(enemy, me->GetAttackDistance(enemy)))
targets.push_back(enemy);
};
for (std::pair const& pair : summoner->GetCombatManager().GetPvPCombatRefs())
addTargetIfValid(pair.second);
if (targets.empty())
for (std::pair const& pair : summoner->GetCombatManager().GetPvECombatRefs())
addTargetIfValid(pair.second);
for (Unit* target : targets)
me->EngageWithTarget(target);
if (!targets.empty())
{
Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
me->GetThreatManager().FixateTarget(target);
}
}
if (!UpdateVictim())
return;
// Viper
if (_isViper)
{
if (_spellTimer <= diff)
{
if (!urand(0, 2)) // 33% chance to cast
DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON));
_spellTimer = 3000;
}
else
_spellTimer -= diff;
}
}
private:
bool _isViper;
uint32 _spellTimer;
};
void AddSC_hunter_pet_scripts()
{
RegisterCreatureAI(npc_pet_hunter_snake_trap);
}