forked from insider42/scriptdev2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpet_ai.cpp
More file actions
126 lines (104 loc) · 4.12 KB
/
pet_ai.cpp
File metadata and controls
126 lines (104 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Copyright (C) 2006 - 2011 ScriptDev2 <http://www.scriptdev2.com/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
/* ScriptData
SDName: ScriptedPetAI
SD%Complete: 50
SDComment: Intended to be used with Guardian/Protector/Minipets. Little/no control over when pet enter/leave combat. Must be considered to be under development.
SDCategory: Npc
EndScriptData */
#include "precompiled.h"
#include "pet_ai.h"
ScriptedPetAI::ScriptedPetAI(Creature* pCreature) : CreatureAI(pCreature)
{}
void ScriptedPetAI::MoveInLineOfSight(Unit* pWho)
{
if (m_creature->getVictim())
return;
if (!m_creature->GetCharmInfo() || !m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE))
return;
if (m_creature->CanInitiateAttack() && pWho->isTargetableForAttack() &&
m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
{
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
return;
if (m_creature->IsWithinDistInMap(pWho, m_creature->GetAttackDistance(pWho)) && m_creature->IsWithinLOSInMap(pWho))
{
pWho->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
AttackStart(pWho);
}
}
}
void ScriptedPetAI::AttackStart(Unit* pWho)
{
if (pWho && m_creature->Attack(pWho, true))
m_creature->GetMotionMaster()->MoveChase(pWho);
}
void ScriptedPetAI::AttackedBy(Unit* pAttacker)
{
if (m_creature->getVictim())
return;
if (m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
m_creature->CanReachWithMeleeAttack(pAttacker))
AttackStart(pAttacker);
}
void ScriptedPetAI::ResetPetCombat()
{
Unit* pOwner = m_creature->GetCharmerOrOwner();
if (pOwner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
m_creature->GetMotionMaster()->MoveFollow(pOwner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
else
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
}
m_creature->AttackStop();
debug_log("SD2: ScriptedPetAI reset pet combat and stop attack.");
Reset();
}
void ScriptedPetAI::UpdatePetAI(const uint32 uiDiff)
{
DoMeleeAttackIfReady();
}
void ScriptedPetAI::UpdateAI(const uint32 uiDiff)
{
if (!m_creature->isAlive()) // should not be needed, isAlive is checked in mangos before calling UpdateAI
return;
// UpdateAllies() is done in the generic PetAI in Mangos, but we can't do this from script side.
// Unclear what side effects this has, but is something to be resolved from Mangos.
if (m_creature->getVictim()) // in combat
{
if (!m_creature->getVictim()->isTargetableForAttack())
{
// target no longer valid for pet, so either attack stops or new target are selected
// doesn't normally reach this, because of how petAi is designed in Mangos. CombatStop
// are called before this update diff, and then pet will already have no victim.
ResetPetCombat();
return;
}
// update when in combat
UpdatePetAI(uiDiff);
}
else if (m_creature->GetCharmInfo())
{
Unit* pOwner = m_creature->GetCharmerOrOwner();
if (!pOwner)
return;
if (pOwner->isInCombat() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE))
{
// Not correct in all cases.
// When mob initiate attack by spell, pet should not start attack before spell landed.
AttackStart(pOwner->getAttackerForHelper());
}
else if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
// not following, so start follow
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW))
m_creature->GetMotionMaster()->MoveFollow(pOwner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
// update when not in combat
UpdatePetOOCAI(uiDiff);
}
}
}