diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a57c06478..ff26ef061 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -12843,9 +12843,21 @@ void Player::ResurectUsingRequestData() void Player::SetClientControl(Unit* target, bool allowMove, bool packetOnly /*= false*/) { + ASSERT(target); + // refuse to grant control if target has UNIT_STATE_CHARMED + if (target->HasUnitState(UNIT_STATE_CHARMED) && (GetGUID() != target->GetCharmerGUID())) + { + LOG_ERROR("entities.player", "Player '{}' attempt to client control '{}', which is charmed by GUID {}", GetName(), target->GetName(), target->GetCharmerGUID().ToString()); + 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_FLEEING | UNIT_STATE_CONFUSED)) + allowMove = false; + WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, target->GetPackGUID().size() + 1); data << target->GetPackGUID(); - data << uint8((allowMove && !target->HasUnitState(UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED)) ? 1 : 0); + data << uint8(allowMove ? 1 : 0); SendDirectMessage(&data); // We want to set the packet only diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 591488e89..f87548d18 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11125,6 +11125,8 @@ void Unit::SetCharm(Unit* charm, bool apply) } else { + charm->ClearUnitState(UNIT_STATE_CHARMED); + if (IsPlayer()) { if (!RemoveGuidValue(UNIT_FIELD_CHARM, charm->GetGUID())) @@ -18798,6 +18800,8 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au else if (IsPlayer()) RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); + AddUnitState(UNIT_STATE_CHARMED); + if (Creature* creature = ToCreature()) creature->RefreshSwimmingFlag(); diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h index af52a9891..dc80e1fba 100644 --- a/src/server/game/Entities/Unit/UnitDefines.h +++ b/src/server/game/Entities/Unit/UnitDefines.h @@ -169,7 +169,7 @@ enum UnitState { UNIT_STATE_DIED = 0x00000001, // player has fake death aura UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone - //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone + UNIT_STATE_CHARMED = 0x00000004, // having any kind of charm aura on self UNIT_STATE_STUNNED = 0x00000008, UNIT_STATE_ROAMING = 0x00000010, UNIT_STATE_CHASE = 0x00000020, @@ -201,7 +201,7 @@ enum UnitState UNIT_STATE_NO_COMBAT_MOVEMENT = 0x40000000, // should not be changed outside the core and should be placed at the end UNIT_STATE_LOGOUT_TIMER = 0x80000000, // Unit is logging out - UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE + UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_CHARMED | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING