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

Revision 174, 3.7 kB (checked in by yumileroy, 17 years ago)

[svn] Implemented player on player and player on creature possession:
* Implemented packet and vision forwarding through possessed units
* Added new OnPossess? script call alerting scripts on when possession is applied/removed
* Moved fall damage and fall under map calculations into the Player class
* Added new PossessedAI that is applied only while possession on creature is active
* Implemented summon possessed spell effect
* Fixed Eyes of the Beast

Original author: gvcoman
Date: 2008-11-05 20:51:05-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( i_pet.getVictim() || !u )
28        return;
29
30    if(i_pet.Attack(u, true))
31        i_victimGuid = u->GetGUID();
32
33    // Do not autochase our target, and also make sure our current movement generator
34    // is removed since the motion master is reset before this function is called
35    i_pet.GetMotionMaster()->Clear(false);
36    i_pet.GetMotionMaster()->MoveIdle();
37}
38
39bool PossessedAI::_needToStop() const
40{
41    if(!i_pet.getVictim() || !i_pet.isAlive())
42        return true;
43
44    // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
45    if(i_pet.getVictim() == i_pet.GetCharmer())
46        return true;
47
48    return !i_pet.getVictim()->isTargetableForAttack();
49}
50
51void PossessedAI::_stopAttack()
52{
53    if( !i_victimGuid )
54        return;
55
56    Unit* victim = Unit::GetUnit(i_pet, i_victimGuid );
57
58    if ( !victim )
59        return;
60
61    assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
62
63    if( !i_pet.isAlive() )
64    {
65        i_pet.StopMoving();
66        i_pet.GetMotionMaster()->Clear(false);
67        i_pet.GetMotionMaster()->MoveIdle();
68        i_victimGuid = 0;
69        i_pet.CombatStop();
70        i_pet.getHostilRefManager().deleteReferences();
71
72        return;
73    }
74
75    i_pet.GetMotionMaster()->Clear(false);
76    i_pet.GetMotionMaster()->MoveIdle();
77    i_victimGuid = 0;
78    i_pet.AttackStop();
79}
80
81void PossessedAI::UpdateAI(const uint32 diff)
82{
83    // update i_victimGuid if i_pet.getVictim() !=0 and changed
84    if(i_pet.getVictim())
85        i_victimGuid = i_pet.getVictim()->GetGUID();
86
87    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
88    if( i_victimGuid )
89    {
90        if( _needToStop() )
91        {
92            _stopAttack();                                  // i_victimGuid == 0 && i_pet.getVictim() == NULL now
93            return;
94        }
95        else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady())
96        {
97            i_pet.AttackerStateUpdate(i_pet.getVictim());
98
99            i_pet.resetAttackTimer();
100
101            if( _needToStop() )
102                _stopAttack();
103        }
104    }
105}
106
107bool PossessedAI::_isVisible(Unit *u) const
108{
109    return i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
110        && u->isVisibleForOrDetect(&i_pet,true);
111}
112
113void PossessedAI::JustDied(Unit *u)
114{
115    // We died while possessed, disable our loot
116    i_pet.RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
117}
118
119void PossessedAI::KilledUnit(Unit* victim)
120{
121    // We killed a creature, disable victim's loot
122    if (victim->GetTypeId() == TYPEID_UNIT)
123        victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
124}
Note: See TracBrowser for help on using the browser.