aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CreatureAI.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp30
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
4 files changed, 24 insertions, 11 deletions
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index b23a7284da1..e1d53238c89 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -159,7 +159,7 @@ void CreatureAI::TriggerAlert(Unit const* who) const
me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS, me->GetAbsoluteAngle(who));
}
-// adapted from logic in Spell:EffectSummonType
+// adapted from logic in Spell:EffectSummonType before commit 8499434
static bool ShouldFollowOnSpawn(SummonPropertiesEntry const* properties)
{
// Summons without SummonProperties are generally scripted summons that don't belong to any owner
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 04555e758f9..153ee80e18d 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25750,24 +25750,38 @@ void Player::ResurrectUsingRequestDataImpl()
void Player::SetClientControl(Unit* target, bool allowMove)
{
- // still affected by some aura that shouldn't allow control, only allow on last such aura to be removed
- if (allowMove && target->HasUnitState(UNIT_STATE_CANT_CLIENT_CONTROL))
+ // a player can never client control nothing
+ ASSERT(target);
+
+ // don't allow possession to be overridden
+ if (target->HasUnitState(UNIT_STATE_CHARMED) && (GetGUID() != target->GetCharmerGUID()))
{
- // this should never happen, otherwise m_unitBeingMoved might be left dangling!
- ASSERT(GetUnitBeingMoved() == target);
+ TC_LOG_ERROR("entities.player", "Player '%s' attempt to client control '%s', which is charmed by GUID %s",
+ GetName().c_str(), target->GetName().c_str(), target->GetCharmerGUID().ToString().c_str());
return;
}
+ // still affected by some aura that shouldn't allow control, only allow on last such aura to be removed
+ if (target->HasUnitState(UNIT_STATE_CONTROLLED))
+ allowMove = false;
+
WorldPackets::Movement::ControlUpdate data;
data.Guid = target->GetGUID();
data.On = allowMove;
SendDirectMessage(data.Write());
- if (this != target)
- SetViewpoint(target, allowMove);
+ WorldObject* viewpoint = GetViewpoint();
+ if (!viewpoint)
+ viewpoint = this;
+ if (target != viewpoint)
+ {
+ if (viewpoint != this)
+ SetViewpoint(viewpoint, false);
+ if (target != this)
+ SetViewpoint(target, true);
+ }
- if (allowMove)
- SetMovedUnit(target);
+ SetMovedUnit(target);
}
void Player::UpdateZoneDependentAuras(uint32 newZone)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 78f0fad657c..8d6ec5c493f 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -478,7 +478,7 @@ void Unit::Update(uint32 p_time)
UpdateSplineMovement(p_time);
i_motionMaster->Update(p_time);
- if (!GetAI() && (GetTypeId() != TYPEID_PLAYER || IsCharmed()))
+ if (!GetAI() && (GetTypeId() != TYPEID_PLAYER || (IsCharmed() && GetCharmerGUID().IsCreature())))
UpdateCharmAI();
RefreshAI();
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 91d9884547e..641db7d7d17 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -274,7 +274,6 @@ enum UnitState : uint32
UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT,
UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE,
UNIT_STATE_CONTROLLED = UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING,
- UNIT_STATE_CANT_CLIENT_CONTROL = UNIT_STATE_CHARMED | UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_POSSESSED,
UNIT_STATE_LOST_CONTROL = UNIT_STATE_CONTROLLED | UNIT_STATE_POSSESSED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING,
UNIT_STATE_CANNOT_AUTOATTACK = UNIT_STATE_CONTROLLED | UNIT_STATE_CHARGING | UNIT_STATE_CASTING,
UNIT_STATE_SIGHTLESS = UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE,