root/trunk/src/game/PossessedAI.cpp @ 200

Revision 200, 3.8 kB (checked in by yumileroy, 17 years ago)

[svn] * Disabled the move and stay commands while pet is possessed
* Make pet come back to its owner after possession ends if it's not currently in combat
* Allow the possessed unit to properly change attack targets
* Also remove charm effects from charmed target on owner aura cancel

Original author: gvcoman
Date: 2008-11-08 23:32:15-06:00

Line 
1/*
2 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
3 *
4 * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "PossessedAI.h"
22#include "Creature.h"
23#include "World.h"
24
25void PossessedAI::AttackStart(Unit *u)
26{
27    if( !u )
28        return;
29
30    if (i_pet.getVictim() && u != i_pet.getVictim())
31        i_pet.AttackStop();
32
33    if(i_pet.Attack(u, true))
34        i_victimGuid = u->GetGUID();
35
36    // Do not autochase our target, and also make sure our current movement generator
37    // is removed since the motion master is reset before this function is called
38    i_pet.GetMotionMaster()->Clear(false);
39    i_pet.GetMotionMaster()->MoveIdle();
40}
41
42bool PossessedAI::_needToStop() const
43{
44    if(!i_pet.getVictim() || !i_pet.isAlive())
45        return true;
46
47    // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
48    if(i_pet.getVictim() == i_pet.GetCharmer())
49        return true;
50
51    return !i_pet.canAttack(i_pet.getVictim());
52}
53
54void PossessedAI::_stopAttack()
55{
56    if( !i_victimGuid )
57        return;
58
59    Unit* victim = Unit::GetUnit(i_pet, i_victimGuid );
60
61    if ( !victim )
62        return;
63
64    assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
65
66    if( !i_pet.isAlive() )
67    {
68        i_pet.StopMoving();
69        i_pet.GetMotionMaster()->Clear(false);
70        i_pet.GetMotionMaster()->MoveIdle();
71        i_victimGuid = 0;
72        i_pet.CombatStop();
73        i_pet.getHostilRefManager().deleteReferences();
74
75        return;
76    }
77
78    i_pet.GetMotionMaster()->Clear(false);
79    i_pet.GetMotionMaster()->MoveIdle();
80    i_victimGuid = 0;
81    i_pet.AttackStop();
82}
83
84void PossessedAI::UpdateAI(const uint32 diff)
85{
86    // update i_victimGuid if i_pet.getVictim() !=0 and changed
87    if(i_pet.getVictim())
88        i_victimGuid = i_pet.getVictim()->GetGUID();
89
90    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
91    if( i_victimGuid )
92    {
93        if( _needToStop() )
94        {
95            _stopAttack();                                  // i_victimGuid == 0 && i_pet.getVictim() == NULL now
96            return;
97        }
98        else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady())
99        {
100            i_pet.AttackerStateUpdate(i_pet.getVictim());
101
102            i_pet.resetAttackTimer();
103
104            if( _needToStop() )
105                _stopAttack();
106        }
107    }
108}
109
110bool PossessedAI::_isVisible(Unit *u) const
111{
112    return i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
113        && u->isVisibleForOrDetect(&i_pet,true);
114}
115
116void PossessedAI::JustDied(Unit *u)
117{
118    // We died while possessed, disable our loot
119    i_pet.RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
120}
121
122void PossessedAI::KilledUnit(Unit* victim)
123{
124    // We killed a creature, disable victim's loot
125    if (victim->GetTypeId() == TYPEID_UNIT)
126        victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
127}
Note: See TracBrowser for help on using the browser.