Skip to content

Commit

Permalink
Player/Movement: Implement pending collision height
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Jan 2, 2025
1 parent 4bb90e8 commit 40ad272
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/game/Anticheat/module/Movement/movement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ uint16 GetOrderResponse(uint16 opcode)
case SMSG_MOVE_WATER_WALK:
case SMSG_MOVE_LAND_WALK:
return CMSG_MOVE_WATER_WALK_ACK;
case SMSG_MOVE_SET_COLLISION_HGT:
return CMSG_MOVE_SET_COLLISION_HGT_ACK;
default:
return 0;
}
Expand Down
63 changes: 51 additions & 12 deletions src/game/Entities/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,12 @@ Player::Player(WorldSession* session): Unit(), m_taxiTracker(*this), m_mover(thi

m_lastDbGuid = 0;
m_lastGameObject = false;

m_pendingMountId = 0;
m_pendingMountAuraAmount = 0;
m_pendingMountAura = false;
m_pendingMountAuraFlying = false;
m_pendingDismount = false;
}

Player::~Player()
Expand Down Expand Up @@ -1972,20 +1978,57 @@ bool Player::BuildEnumData(QueryResult* result, WorldPacket& p_data)
return true;
}

bool Player::Mount(uint32 displayid, const Aura* aura/* = nullptr*/)
bool Player::Mount(uint32 displayid, bool auraExists, int32 auraAmount, bool isFlyingAura)
{
if (!Unit::Mount(displayid, aura))
float height = GetCollisionHeight();
uint32 newMountId = GetOverridenMountId() ? GetOverridenMountId() : displayid;
float newHeight = CalculateCollisionHeight(newMountId);

m_pendingMountId = newMountId;
m_pendingMountAura = auraExists;
m_pendingMountAuraAmount = auraAmount;
m_pendingMountAuraFlying = isFlyingAura;
m_pendingDismount = false;

if (height != newHeight)
SendCollisionHeightUpdate(newHeight);
else
ResolvePendingMount();

return true;
}

bool Player::Unmount(bool auraExists, int32 auraAmount)
{
float height = GetCollisionHeight();
float newHeight = CalculateCollisionHeight(0);

m_pendingMountAura = auraExists;
m_pendingMountAuraAmount = auraAmount;
m_pendingDismount = true;

if (height != newHeight)
SendCollisionHeightUpdate(newHeight);
else
ResolvePendingUnmount();

return true;
}

bool Player::ResolvePendingMount()
{
if (!Unit::Mount(m_pendingMountId, m_pendingMountAura, m_pendingMountAuraAmount))
return false;

bool keepPetOnMount = !sWorld.getConfig(CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT);
bool keepPetOnFlyingMount = !keepPetOnMount ? false : sWorld.getConfig(CONFIG_BOOL_KEEP_PET_ON_FLYING_MOUNT);
// Custom mount (non-aura such as taxi or command) or in flight: unsummon any pet
if (!aura || (!keepPetOnFlyingMount && (IsFreeFlying() || IsSpellHaveAura(aura->GetSpellProto(), SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED))))
if (!m_pendingMountAura || (!keepPetOnFlyingMount && (IsFreeFlying() || m_pendingMountAuraFlying)))
{
UnsummonPetTemporaryIfAny();
}
// Land mount aura: unsummon only permanent pet
else if (aura)
else if (m_pendingMountAura)
{
if (Pet* pet = GetPet())
{
Expand All @@ -1996,16 +2039,14 @@ bool Player::Mount(uint32 displayid, const Aura* aura/* = nullptr*/)
}
}

float height = GetCollisionHeight();
if (height)
SendCollisionHeightUpdate(height);
UpdateSpeed(MOVE_RUN, true); // update speed

return true;
}

bool Player::Unmount(const Aura* aura/* = nullptr*/)
bool Player::ResolvePendingUnmount()
{
if (!Unit::Unmount(aura))
if (!Unit::Unmount(m_pendingMountAura, m_pendingMountAuraAmount))
return false;

// only resummon old pet if the player is already added to a map
Expand All @@ -2020,9 +2061,7 @@ bool Player::Unmount(const Aura* aura/* = nullptr*/)
else
ResummonPetTemporaryUnSummonedIfAny();

float height = GetCollisionHeight();
if (height)
SendCollisionHeightUpdate(height);
UpdateSpeed(MOVE_RUN, true); // update speed

return true;
}
Expand Down
14 changes: 12 additions & 2 deletions src/game/Entities/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,12 @@ class Player : public Unit
ReputationRank GetReactionTo(Corpse const* corpse) const override;
bool IsInGroup(Unit const* other, bool party = false, bool ignoreCharms = false) const override;

bool Mount(uint32 displayid, const Aura* aura = nullptr) override;
bool Unmount(const Aura* aura = nullptr) override;
bool Mount(uint32 displayid, bool auraExists = false, int32 auraAmount = 0, bool isFlyingAura = false) override;
bool Unmount(bool auraExists = false, int32 auraAmount = 0) override;

bool ResolvePendingMount();
bool ResolvePendingUnmount();
bool IsPendingDismount() const { return m_pendingDismount; }

void ToggleAFK();
void ToggleDND();
Expand Down Expand Up @@ -2984,6 +2988,12 @@ class Player : public Unit
uint32 m_lastDbGuid; bool m_lastGameObject;

std::set<uint32> m_serversideDailyQuests;

uint32 m_pendingMountId;
bool m_pendingMountAura;
int32 m_pendingMountAuraAmount;
bool m_pendingMountAuraFlying;
bool m_pendingDismount;
};

void AddItemsSetItem(Player* player, Item* item);
Expand Down
31 changes: 20 additions & 11 deletions src/game/Entities/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8809,10 +8809,10 @@ bool Unit::UnmountEntry(const Aura* aura)
return Unmount(aura);
}

bool Unit::Mount(uint32 displayid, const Aura* aura/* = nullptr*/)
bool Unit::Mount(uint32 displayid, bool auraExists, int32 auraAmount, bool /*isFlyingAura*/)
{
// Custom mount (non-aura such as taxi or command) overwrites aura mounts
if (!displayid || (IsMounted() && aura && uint32(aura->GetAmount()) != GetMountID()))
if (!displayid || (IsMounted() && auraExists && uint32(auraAmount) != GetMountID()))
return false;

RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING);
Expand All @@ -8821,7 +8821,7 @@ bool Unit::Mount(uint32 displayid, const Aura* aura/* = nullptr*/)
else
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, m_overridenMountId);

if (aura)
if (auraExists)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT);

if (GetMountInfo())
Expand All @@ -8832,23 +8832,23 @@ bool Unit::Mount(uint32 displayid, const Aura* aura/* = nullptr*/)
return true;
}

bool Unit::Unmount(const Aura* aura/* = nullptr*/)
bool Unit::Unmount(bool auraExists, int32 auraAmount)
{
if (!GetMountID())
return false;

if (aura)
if (auraExists)
{
// Custom mount (non-aura such as taxi or command) overwrites aura mounts, do not dismount on aura removal
if (uint32(aura->GetAmount()) != GetMountID() && !m_isMountOverriden)
if (uint32(auraAmount) != GetMountID() && !m_isMountOverriden)
return false;
}

RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DISMOUNT);
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); // always remove even if aura for safety

if (aura)
if (auraExists)
{
WorldPacket data(SMSG_DISMOUNT, 8);
data << GetPackGUID();
Expand Down Expand Up @@ -12570,11 +12570,15 @@ void Unit::SendCollisionHeightUpdate(float height)
{
if (Player const* player = GetControllingPlayer())
{
auto const counter = player->GetSession()->GetOrderCounter();

WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
data << GetPackGUID();
data << uint32(sWorld.GetGameTime());
data << counter;
data << height;
player->GetSession()->SendPacket(data);
player->GetSession()->GetAnticheat()->OrderSent(data.GetOpcode(), counter);
player->GetSession()->IncrementOrderCounter();
}
}
}
Expand Down Expand Up @@ -13383,13 +13387,13 @@ float Unit::OCTRegenMPPerSpirit() const
return regen;
}

float Unit::GetCollisionHeight() const
float Unit::CalculateCollisionHeight(uint32 mountId) const
{
float scaleMod = GetObjectScale(); // 99% sure about this

if (GetMountID())
if (mountId)
{
if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)))
if (CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(mountId))
{
if (CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId))
{
Expand All @@ -13413,6 +13417,11 @@ float Unit::GetCollisionHeight() const
return collisionHeight == 0.0f ? DEFAULT_COLLISION_HEIGHT : collisionHeight;
}

float Unit::GetCollisionHeight() const
{
return CalculateCollisionHeight(GetMountID());
}

float Unit::GetCollisionWidth() const
{
float scaleMod = GetObjectScale(); // 99% sure about this
Expand Down
7 changes: 5 additions & 2 deletions src/game/Entities/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ class Unit : public WorldObject

void CleanupsBeforeDelete() override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)

float CalculateCollisionHeight(uint32 mountId) const;
float GetCollisionHeight() const override;
float GetCollisionWidth() const override;
float GetObjectBoundingRadius() const override { return m_floatValues[UNIT_FIELD_BOUNDINGRADIUS]; } // overwrite WorldObject version
Expand Down Expand Up @@ -1538,8 +1539,8 @@ class Unit : public WorldObject
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
bool MountEntry(uint32 templateEntry, const Aura* aura = nullptr);
bool UnmountEntry(const Aura* aura = nullptr);
virtual bool Mount(uint32 displayid, const Aura* aura = nullptr);
virtual bool Unmount(const Aura* aura = nullptr);
virtual bool Mount(uint32 displayid, bool auraExists = false, int32 auraAmount = 0, bool isFlyingAura = false);
virtual bool Unmount(bool auraExists = false, int32 auraAmount = 0);

VehicleInfo* GetVehicleInfo() const { return m_vehicleInfo.get(); }
MaNGOS::unique_weak_ptr<VehicleInfo> GetVehicleInfoWeakPtr() const { return m_vehicleInfo; }
Expand Down Expand Up @@ -2796,6 +2797,8 @@ class Unit : public WorldObject

FormationSlotDataSPtr m_formationSlot;

uint32 GetOverridenMountId() const { return m_overridenMountId; }

private:
void CleanupDeletedAuras();
void UpdateSplineMovement(uint32 t_diff);
Expand Down
5 changes: 5 additions & 0 deletions src/game/MotionGenerators/MovementHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ void WorldSession::HandleForceSpeedChangeAckOpcodes(WorldPacket& recv_data)
data << movementInfo;
data << newspeed; // new collision height
mover->SendMessageToSetExcept(data, _player);

if (_player->IsPendingDismount())
_player->ResolvePendingUnmount();
else
_player->ResolvePendingMount();
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/game/Server/Opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x514*/ { "SMSG_SEND_ALL_COMBAT_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x515*/ { "SMSG_OPEN_LFG_DUNGEON_FINDER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x516*/ { "SMSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleForceSpeedChangeAckOpcodes},
/*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleForceSpeedChangeAckOpcodes},
/*0x518*/ { "MSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x519*/ { "CMSG_CLEAR_RANDOM_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x51A*/ { "CMSG_CLEAR_HOLIDAY_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
Expand Down
4 changes: 2 additions & 2 deletions src/game/Spells/SpellAuras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3834,7 +3834,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)

m_modifier.m_amount = display_id;

target->Mount(display_id, this);
target->Mount(display_id, this, this->GetAmount(), IsSpellHaveAura(GetSpellProto(), SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED));

if (ci->VehicleTemplateId)
{
Expand All @@ -3846,7 +3846,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
}
else
{
target->Unmount(this);
target->Unmount(this, this->GetAmount());

CreatureInfo const* ci = ObjectMgr::GetCreatureTemplate(m_modifier.m_miscvalue);
if (ci && target->IsVehicle() && ci->VehicleTemplateId == target->GetVehicleInfo()->GetVehicleEntry()->m_ID)
Expand Down

0 comments on commit 40ad272

Please sign in to comment.