diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/scripts/Pet/pet_hunter.cpp | 87 | 
1 files changed, 40 insertions, 47 deletions
| diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 50c61f4c885..c5300523175 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -61,81 +61,74 @@ class npc_pet_hunter_snake_trap : public CreatureScript          struct npc_pet_hunter_snake_trapAI : public ScriptedAI          { -            npc_pet_hunter_snake_trapAI(Creature* creature) : ScriptedAI(creature) -            { -                Initialize(); -            } - -            void Initialize() -            { -                _spellTimer = 0; -                _isViper = false; -            } +            npc_pet_hunter_snake_trapAI(Creature* creature) : ScriptedAI(creature), _isViper(false), _spellTimer(0) { }              void JustEngagedWith(Unit* /*who*/) override { }              void Reset() override              { -                Initialize(); - -                CreatureTemplate const* Info = me->GetCreatureTemplate(); - -                _isViper = Info->Entry == NPC_HUNTER_VIPER ? true : false; +                _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 -                uint32 delta = (rand32() % 7) * 100; -                me->SetAttackTime(BASE_ATTACK, Info->BaseAttackTime + delta); -                //me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower)); +                me->SetAttackTime(BASE_ATTACK, me->GetAttackTime(BASE_ATTACK) + urandms(0,6)); -                // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target -                if (!me->GetVictim() && me->IsSummon()) -                    if (Unit* Owner = me->ToTempSummon()->GetSummoner()) -                        if (Owner->getAttackerForHelper()) -                            AttackStart(Owner->getAttackerForHelper()); - -                if (!_isViper) +                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 MoveInLineOfSight(Unit* who) override { } + +            void UpdateAI(uint32 diff) override              { -                if (!me->GetVictim() && me->CanCreatureAttack(who)) -                { -                    if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) -                        return; +                if (me->GetVictim() && me->GetVictim()->HasBreakableByDamageCrowdControlAura()) +                { // don't break cc +                    me->GetThreatManager().ClearFixate(); +                    me->InterruptNonMeleeSpells(false); +                    me->AttackStop(); +                    return; +                } -                    float attackRadius = me->GetAttackDistance(who); -                    if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who)) +                if (me->IsSummon() && !me->GetThreatManager().GetFixateTarget()) +                { // find new target +                    Unit* summoner = me->ToTempSummon()->GetSummoner(); + +                    std::vector<Unit*> targets; +                    for (std::pair<ObjectGuid const, PvPCombatReference*> const& pair : summoner->GetCombatManager().GetPvPCombatRefs())                      { -                        if (!(rand32() % 5)) +                        Unit* enemy = pair.second->GetOther(summoner); +                        if (!enemy->HasBreakableByDamageCrowdControlAura() && me->CanCreatureAttack(enemy) && me->IsWithinDistInMap(enemy, me->GetAttackDistance(enemy))) +                            targets.push_back(enemy); +                    } + +                    if (targets.empty()) +                        for (std::pair<ObjectGuid const, CombatReference*> const& pair : summoner->GetCombatManager().GetPvECombatRefs())                          { -                            me->setAttackTimer(BASE_ATTACK, (rand32() % 10) * 100); -                            _spellTimer = (rand32() % 10) * 100; -                            AttackStart(who); +                            Unit* enemy = pair.second->GetOther(summoner); +                            if (!enemy->HasBreakableByDamageCrowdControlAura() && me->CanCreatureAttack(enemy) && me->IsWithinDistInMap(enemy, me->GetAttackDistance(enemy))) +                                targets.push_back(enemy);                          } + +                    for (Unit* target : targets) +                        me->EngageWithTarget(target); + +                    if (!targets.empty()) +                    { +                        Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); +                        me->GetThreatManager().FixateTarget(target);                      }                  } -            } -            void UpdateAI(uint32 diff) override -            { -                if (!UpdateVictim() || !me->GetVictim()) +                if (!UpdateVictim())                      return; -                if (me->EnsureVictim()->HasBreakableByDamageCrowdControlAura(me)) -                { -                    me->InterruptNonMeleeSpells(false); -                    return; -                } -                  // Viper                  if (_isViper)                  {                      if (_spellTimer <= diff)                      { -                        if (urand(0, 2) == 0) // 33% chance to cast +                        if (!urand(0, 2)) // 33% chance to cast                              DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON));                          _spellTimer = 3000; | 
