[10053] Use UNIT_STAT_CONTROLED for mark unit state under direct player control.

* This allow prevent move home/to caster at apply
* Also replace AI and reset movegens at control time
* Also stop combat and clear threat/hostile list at lost control for prevent combat with freindly units.
This commit is contained in:
VladimirMangos 2010-06-14 08:26:21 +04:00
parent e427ce80cc
commit b4b45333d8
9 changed files with 60 additions and 32 deletions

View file

@ -36,7 +36,7 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell,
if (!isTriggered) if (!isTriggered)
{ {
// State does not allow // State does not allow
if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT)) if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
return CAST_FAIL_STATE; return CAST_FAIL_STATE;
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))

View file

@ -1319,7 +1319,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
return false; return false;
//Silenced so we can't cast //Silenced so we can't cast
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) || if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL) ||
m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))) m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
return false; return false;

View file

@ -67,7 +67,7 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
pl->UpdateVisibilityOf(viewPoint,c); pl->UpdateVisibilityOf(viewPoint,c);
// Creature AI reaction // Creature AI reaction
if (!c->hasUnitState(UNIT_STAT_FLEEING)) if (!c->hasUnitState(UNIT_STAT_LOST_CONTROL))
{ {
if (c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode()) if (c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode())
c->AI()->MoveInLineOfSight(pl); c->AI()->MoveInLineOfSight(pl);
@ -76,13 +76,13 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2) inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
{ {
if (!c1->hasUnitState(UNIT_STAT_FLEEING)) if (!c1->hasUnitState(UNIT_STAT_LOST_CONTROL))
{ {
if (c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode()) if (c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode())
c1->AI()->MoveInLineOfSight(c2); c1->AI()->MoveInLineOfSight(c2);
} }
if (!c2->hasUnitState(UNIT_STAT_FLEEING)) if (!c2->hasUnitState(UNIT_STAT_LOST_CONTROL))
{ {
if (c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode()) if (c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode())
c2->AI()->MoveInLineOfSight(c1); c2->AI()->MoveInLineOfSight(c1);

View file

@ -41,10 +41,11 @@ void
MotionMaster::Initialize() MotionMaster::Initialize()
{ {
// clear ALL movement generators (including default) // clear ALL movement generators (including default)
i_owner->StopMoving();
Clear(false,true); Clear(false,true);
// set new default movement generator // set new default movement generator
if (i_owner->GetTypeId() == TYPEID_UNIT) if (i_owner->GetTypeId() == TYPEID_UNIT && !i_owner->hasUnitState(UNIT_STAT_CONTROLED))
{ {
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner); MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
push(movement == NULL ? &si_idleMovement : movement); push(movement == NULL ? &si_idleMovement : movement);
@ -226,7 +227,7 @@ void MotionMaster::MoveRandom()
void void
MotionMaster::MoveTargetedHome() MotionMaster::MoveTargetedHome()
{ {
if(i_owner->hasUnitState(UNIT_STAT_FLEEING)) if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
return; return;
Clear(false); Clear(false);
@ -281,6 +282,9 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
void void
MotionMaster::MoveFollow(Unit* target, float dist, float angle) MotionMaster::MoveFollow(Unit* target, float dist, float angle)
{ {
if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
return;
Clear(); Clear();
// ignore movement request if target not exist // ignore movement request if target not exist

View file

@ -2236,7 +2236,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
return NULL; return NULL;
// not in interactive state // not in interactive state
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT)) if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
return NULL; return NULL;
// exist (we need look pets also for some interaction (quest/etc) // exist (we need look pets also for some interaction (quest/etc)
@ -2290,7 +2290,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo
return NULL; return NULL;
// not in interactive state // not in interactive state
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT)) if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
return NULL; return NULL;
if (GameObject *go = GetMap()->GetGameObject(guid)) if (GameObject *go = GetMap()->GetGameObject(guid))

View file

@ -3619,6 +3619,8 @@ void Aura::HandleModPossess(bool apply, bool Real)
if( apply ) if( apply )
{ {
target->addUnitState(UNIT_STAT_CONTROLED);
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
target->SetCharmerGUID(p_caster->GetGUID()); target->SetCharmerGUID(p_caster->GetGUID());
@ -3630,24 +3632,28 @@ void Aura::HandleModPossess(bool apply, bool Real)
p_caster->SetClientControl(target, 1); p_caster->SetClientControl(target, 1);
p_caster->SetMover(target); p_caster->SetMover(target);
target->CombatStop(); target->CombatStop(true);
target->DeleteThreatList(); target->DeleteThreatList();
target->getHostileRefManager().deleteReferences();
if(CharmInfo *charmInfo = target->InitCharmInfo(target))
{
charmInfo->InitPossessCreateSpells();
charmInfo->SetReactState(REACT_PASSIVE);
charmInfo->SetCommandState(COMMAND_STAY);
}
p_caster->PossessSpellInitialize();
if(target->GetTypeId() == TYPEID_UNIT) if(target->GetTypeId() == TYPEID_UNIT)
{ {
target->StopMoving(); ((Creature*)target)->AIM_Initialize();
target->GetMotionMaster()->Clear();
target->GetMotionMaster()->MoveIdle();
} }
else if(target->GetTypeId() == TYPEID_PLAYER) else if(target->GetTypeId() == TYPEID_PLAYER)
{ {
((Player*)target)->SetClientControl(target, 0); ((Player*)target)->SetClientControl(target, 0);
} }
if(CharmInfo *charmInfo = target->InitCharmInfo(target))
charmInfo->InitPossessCreateSpells();
p_caster->PossessSpellInitialize();
} }
else else
{ {
@ -3664,6 +3670,12 @@ void Aura::HandleModPossess(bool apply, bool Real)
if(m_removeMode == AURA_REMOVE_BY_DELETE) if(m_removeMode == AURA_REMOVE_BY_DELETE)
return; return;
target->clearUnitState(UNIT_STAT_CONTROLED);
target->CombatStop(true);
target->DeleteThreatList();
target->getHostileRefManager().deleteReferences();
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
target->SetCharmerGUID(0); target->SetCharmerGUID(0);
@ -3772,8 +3784,9 @@ void Aura::HandleModCharm(bool apply, bool Real)
target->CastStop(target == caster ? GetId() : 0); target->CastStop(target == caster ? GetId() : 0);
caster->SetCharm(target); caster->SetCharm(target);
target->CombatStop(); target->CombatStop(true);
target->DeleteThreatList(); target->DeleteThreatList();
target->getHostileRefManager().deleteReferences();
if(target->GetTypeId() == TYPEID_UNIT) if(target->GetTypeId() == TYPEID_UNIT)
{ {
@ -3848,6 +3861,10 @@ void Aura::HandleModCharm(bool apply, bool Real)
if(caster->GetTypeId() == TYPEID_PLAYER) if(caster->GetTypeId() == TYPEID_PLAYER)
((Player*)caster)->RemovePetActionBar(); ((Player*)caster)->RemovePetActionBar();
target->CombatStop(true);
target->DeleteThreatList();
target->getHostileRefManager().deleteReferences();
if(target->GetTypeId() == TYPEID_UNIT) if(target->GetTypeId() == TYPEID_UNIT)
{ {
((Creature*)target)->AIM_Initialize(); ((Creature*)target)->AIM_Initialize();

View file

@ -13736,4 +13736,4 @@ bool Unit::CheckAndIncreaseCastCounter()
++m_castCounter; ++m_castCounter;
return true; return true;
} }

View file

@ -420,24 +420,25 @@ enum UnitState
UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun
UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot
UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity
UNIT_STAT_CONTROLED = 0x00000040, // Aura::HandleAuraModPossess
// persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen) // persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen)
UNIT_STAT_IN_FLIGHT = 0x00000040, // player is in flight mode (in fact interrupted at far teleport until next map telport landing) UNIT_STAT_IN_FLIGHT = 0x00000080, // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
UNIT_STAT_DISTRACTED = 0x00000080, // DistractedMovementGenerator active UNIT_STAT_DISTRACTED = 0x00000100, // DistractedMovementGenerator active
// persistent movement generator state with non-persistent mirror states for stop support // persistent movement generator state with non-persistent mirror states for stop support
// (can be removed temporary by stop command or another movement generator apply) // (can be removed temporary by stop command or another movement generator apply)
// not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc // not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc
UNIT_STAT_CONFUSED = 0x00000100, // ConfusedMovementGenerator active/onstack UNIT_STAT_CONFUSED = 0x00000200, // ConfusedMovementGenerator active/onstack
UNIT_STAT_CONFUSED_MOVE = 0x00000200, UNIT_STAT_CONFUSED_MOVE = 0x00000400,
UNIT_STAT_ROAMING = 0x00000400, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set) UNIT_STAT_ROAMING = 0x00000800, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
UNIT_STAT_ROAMING_MOVE = 0x00000800, UNIT_STAT_ROAMING_MOVE = 0x00001000,
UNIT_STAT_CHASE = 0x00001000, // ChaseMovementGenerator active UNIT_STAT_CHASE = 0x00002000, // ChaseMovementGenerator active
UNIT_STAT_CHASE_MOVE = 0x00002000, UNIT_STAT_CHASE_MOVE = 0x00004000,
UNIT_STAT_FOLLOW = 0x00004000, // FollowMovementGenerator active UNIT_STAT_FOLLOW = 0x00008000, // FollowMovementGenerator active
UNIT_STAT_FOLLOW_MOVE = 0x00008000, UNIT_STAT_FOLLOW_MOVE = 0x00010000,
UNIT_STAT_FLEEING = 0x00010000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack UNIT_STAT_FLEEING = 0x00020000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
UNIT_STAT_FLEEING_MOVE = 0x00020000, UNIT_STAT_FLEEING_MOVE = 0x00040000,
// masks (only for check) // masks (only for check)
@ -457,6 +458,12 @@ enum UnitState
UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
// AI disabled by some reason
UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLED,
// above 2 state cases
UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL = UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_LOST_CONTROL,
// masks (for check or reset) // masks (for check or reset)
// for real move using movegen check and stop (except unstoppable flight) // for real move using movegen check and stop (except unstoppable flight)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10052" #define REVISION_NR "10053"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__