diff options
| author | Chaouki Dhib <chaodhib@gmail.com> | 2021-05-16 13:16:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-16 13:16:08 +0200 |
| commit | 2d114ea560cd8716af2b0d12990fc3480ecaf2b7 (patch) | |
| tree | aaa711aa4d63e9b33d8e804d481425368ddcee18 /src/server/game/Entities/Unit | |
| parent | edcaac6c959e944dc6d6dc224666b832521412b4 (diff) | |
Core/Movement: Improve client control logic (#26348)
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 71 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 24 |
2 files changed, 46 insertions, 49 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0bb20566b21..888457c7cbc 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -33,6 +33,7 @@ #include "CreatureAIImpl.h" #include "CreatureGroups.h" #include "Formulas.h" +#include "GameClient.h" #include "GameObjectAI.h" #include "GameTime.h" #include "GridNotifiersImpl.h" @@ -295,7 +296,7 @@ bool DispelableAura::RollDispel() const Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_lastSanctuaryTime(0), LastCharmerGUID(), movespline(new Movement::MoveSpline()), m_ControlledByPlayer(false), m_AutoRepeatFirstCast(false), m_procDeep(0), m_transformSpell(0), - m_removedAurasCount(0), m_unitMovedByMe(nullptr), m_playerMovingMe(nullptr), m_charmer(nullptr), m_charmed(nullptr), + m_removedAurasCount(0), m_charmer(nullptr), m_charmed(nullptr), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_Diminishing(), m_combatManager(this), m_threatManager(this), m_aiLocked(false), m_comboTarget(nullptr), m_comboPoints(0), m_spellHistory(new SpellHistory(this)) @@ -367,7 +368,11 @@ Unit::Unit(bool isWorldObject) : for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) m_speed_rate[i] = 1.0f; + for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) + m_forced_speed_changes[i] = 0; + m_charmInfo = nullptr; + _gameClientMovingMe = nullptr; // remove aurastates allowing special moves for (uint8 i = 0; i < MAX_REACTIVE; ++i) @@ -417,8 +422,6 @@ Unit::~Unit() ASSERT(m_removedAuras.empty()); ASSERT(m_gameObj.empty()); ASSERT(m_dynObj.empty()); - ASSERT(!m_unitMovedByMe || (m_unitMovedByMe == this)); - ASSERT(!m_playerMovingMe || (m_playerMovingMe == this)); } void Unit::Update(uint32 p_time) @@ -5496,7 +5499,7 @@ Unit* Unit::getAttackerForHelper() const // If someone wants to return nullptr; if (Unit* victim = GetVictim()) - if ((!IsPet() && !GetPlayerMovingMe()) || IsInCombatWith(victim)) + if ((!IsPet() && !IsCharmerOrSelfPlayer()) || IsInCombatWith(victim)) return victim; CombatManager const& mgr = GetCombatManager(); @@ -6270,6 +6273,14 @@ bool Unit::isPossessing() const return false; } +Unit* Unit::GetCharmerOrSelf() const +{ + if (IsCharmed()) + return GetCharmer(); + else + return const_cast<Unit*>(this); +} + Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) { Player* player = nullptr; @@ -8627,15 +8638,17 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate) { // register forced speed changes for WorldSession::HandleForceSpeedChangeAck // and do it only for real sent packets and use run for run/mounted as client expected - ++ToPlayer()->m_forced_speed_changes[mtype]; + ++m_forced_speed_changes[mtype]; if (!IsInCombat()) if (Pet* pet = ToPlayer()->GetPet()) pet->SetSpeedRate(mtype, m_speed_rate[mtype]); } - if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved())) // unit controlled by a player. + if (IsMovedByClient()) // unit controlled by a player. { + Player* playerMover = GetGameClientMovingMe()->GetBasePlayer(); + // Send notification to self. this packet is only sent to one client (the client of the player concerned by the change). WorldPacket self; self.Initialize(moveTypeToOpcode[mtype][1], mtype != MOVE_RUN ? 8 + 4 + 4 : 8 + 4 + 1 + 4); @@ -9933,13 +9946,6 @@ void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state) } } -void Unit::SetMovedUnit(Unit* target) -{ - m_unitMovedByMe->m_playerMovingMe = nullptr; - m_unitMovedByMe = ASSERT_NOTNULL(target); - m_unitMovedByMe->m_playerMovingMe = ASSERT_NOTNULL(ToPlayer()); -} - uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition) { uint32 hitMask = PROC_HIT_NONE; @@ -10446,7 +10452,7 @@ void Unit::SendComboPoints() data << uint8(m_comboPoints); playerMe->SendDirectMessage(&data); } - Player* movingMe = GetPlayerMovingMe(); + Player* movingMe = GetCharmerOrSelfPlayer(); ObjectGuid ownerGuid = GetCharmerOrOwnerGUID(); Player* owner = nullptr; if (ownerGuid.IsPlayer()) @@ -11435,11 +11441,8 @@ void Unit::SetFeared(bool apply) } // block / allow control to real player in control (eg charmer) - if (GetTypeId() == TYPEID_PLAYER) - { - if (m_playerMovingMe) - m_playerMovingMe->SetClientControl(this, !apply); - } + if (GetCharmerOrSelfPlayer()) + GetCharmerOrSelfPlayer()->SetClientControl(this, !apply); } void Unit::SetConfused(bool apply) @@ -11460,11 +11463,8 @@ void Unit::SetConfused(bool apply) } // block / allow control to real player in control (eg charmer) - if (GetTypeId() == TYPEID_PLAYER) - { - if (m_playerMovingMe) - m_playerMovingMe->SetClientControl(this, !apply); - } + if (GetCharmerOrSelfPlayer()) + GetCharmerOrSelfPlayer()->SetClientControl(this, !apply); } bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* aurApp) @@ -12163,18 +12163,7 @@ void Unit::UpdateObjectVisibility(bool forced) void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) { - Player* player = ToPlayer(); - if (!player) - { - if (Unit* charmer = GetCharmer()) - { - player = charmer->ToPlayer(); - if (player && player->GetUnitBeingMoved() != this) - player = nullptr; - } - } - - if (!player) + if (IsMovedByServer()) { GetMotionMaster()->MoveKnockbackFrom(x, y, speedXY, speedZ); } @@ -12190,10 +12179,10 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) data << float(speedXY); // Horizontal speed data << float(-speedZ); // Z Movement speed (vertical) - player->SendDirectMessage(&data); + GetGameClientMovingMe()->SendDirectMessage(&data); - if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY)) - player->SetCanFly(true, true); + if (HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_FLY)) + SetCanFly(true, true); } } @@ -12853,9 +12842,9 @@ void Unit::SendTeleportPacket(Position const& pos, bool teleportingTransport /*= moveUpdateTeleport << GetPackGUID(); Unit* broadcastSource = this; - // should this really be the unit _being_ moved? not the unit doing the moving? - if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved())) + if (IsMovedByClient()) { + Player* playerMover = GetGameClientMovingMe()->GetBasePlayer(); WorldPacket moveTeleport(MSG_MOVE_TELEPORT_ACK, 41); moveTeleport << GetPackGUID(); moveTeleport << uint32(0); // this value increments every time diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a78c049d9f6..87c2e6d1e87 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -71,6 +71,7 @@ class AuraApplication; class AuraEffect; class Creature; class DynamicObject; +class GameClient; class GameObject; class Guardian; class Item; @@ -1184,6 +1185,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveAllControlled(); bool IsCharmed() const { return !GetCharmerGUID().IsEmpty(); } + bool IsCharming() const { return !GetCharmedGUID().IsEmpty(); } bool isPossessed() const { return HasUnitState(UNIT_STATE_POSSESSED); } bool isPossessedByPlayer() const; bool isPossessing() const; @@ -1193,12 +1195,17 @@ class TC_GAME_API Unit : public WorldObject CharmInfo* InitCharmInfo(); void DeleteCharmInfo(); - // all of these are for DIRECT CLIENT CONTROL only - void SetMovedUnit(Unit* target); - // returns the unit that this player IS CONTROLLING - Unit* GetUnitBeingMoved() const { return m_unitMovedByMe; } - // returns the player that this unit is BEING CONTROLLED BY - Player* GetPlayerMovingMe() const { return m_playerMovingMe; } + // base client control of this unit (possess effects, vehicles and similar). Not affected by temporary CC. + bool IsCharmerOrSelfPlayer() const { return GetCharmerOrSelf()->IsPlayer(); } + Unit* GetCharmerOrSelf() const; + Player* GetCharmerOrSelfPlayer() const { return ToPlayer(GetCharmerOrSelf());} + Unit* GetCharmedOrSelf() const { return IsCharming() ? GetCharmed() : const_cast<Unit*>(this); } + + // real time client control status of this unit (possess effects, vehicles and similar). For example, if this unit is a player temporarly under fear, it will return false. + bool IsMovedByClient() const { return _gameClientMovingMe != nullptr; } + bool IsMovedByServer() const { return !IsMovedByClient(); } + GameClient* GetGameClientMovingMe() const { return _gameClientMovingMe; } + void SetGameClientMovingMe(GameClient* gameClientMovingMe) { _gameClientMovingMe = gameClientMovingMe; } SharedVisionList const& GetSharedVisionList() { return m_sharedVision; } void AddPlayerToVision(Player* player); @@ -1673,6 +1680,8 @@ class TC_GAME_API Unit : public WorldObject // Movement info Movement::MoveSpline * movespline; + uint8 m_forced_speed_changes[MAX_MOVE_TYPE]; + int32 GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue = false, int32 miscValue = 0) const; bool IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications = false); bool IsHighestExclusiveAuraEffect(SpellInfo const* spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications = false); @@ -1751,12 +1760,11 @@ class TC_GAME_API Unit : public WorldObject float m_speed_rate[MAX_MOVE_TYPE]; - Unit* m_unitMovedByMe; // only ever set for players, and only for direct client control - Player* m_playerMovingMe; // only set for direct client control (possess effects, vehicles and similar) Unit* m_charmer; // Unit that is charming ME Unit* m_charmed; // Unit that is being charmed BY ME CharmInfo* m_charmInfo; SharedVisionList m_sharedVision; + GameClient* _gameClientMovingMe; MotionMaster* i_motionMaster; |
