Core/Player: moved zone/area updating and tavern resting checks into Heartbeat and movement updates

(cherry picked from commit cb4c9009b3)

# Conflicts:
#	src/server/game/Entities/Player/Player.cpp
This commit is contained in:
Ovahlord
2024-10-23 19:29:42 +02:00
parent 78e4fe2e9f
commit e14648eaba
6 changed files with 47 additions and 48 deletions

View File

@@ -142,8 +142,6 @@
#include <G3D/g3dmath.h>
#include <sstream>
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
// corpse reclaim times
#define DEATH_EXPIRE_STEP (5*MINUTE)
#define MAX_DEATH_COUNT 3
@@ -187,7 +185,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this)
m_weaponChangeTimer = 0;
m_zoneUpdateId = uint32(-1);
m_zoneUpdateTimer = 0;
m_areaUpdateId = 0;
m_team = TEAM_OTHER;
@@ -1024,37 +1021,6 @@ void Player::Update(uint32 p_time)
m_weaponChangeTimer -= p_time;
}
if (m_zoneUpdateTimer > 0)
{
if (p_time >= m_zoneUpdateTimer)
{
// On zone update tick check if we are still in an inn if we are supposed to be in one
if (_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN))
{
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(_restMgr->GetInnTriggerID());
if (!atEntry || !IsInAreaTrigger(atEntry))
_restMgr->RemoveRestFlag(REST_FLAG_IN_TAVERN);
}
uint32 newzone, newarea;
GetZoneAndAreaId(newzone, newarea);
if (m_zoneUpdateId != newzone)
UpdateZone(newzone, newarea); // also update area
else
{
// use area updates as well
// needed for free far all arenas for example
if (m_areaUpdateId != newarea)
UpdateArea(newarea);
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
}
}
else
m_zoneUpdateTimer -= p_time;
}
if (IsAlive())
{
m_regenTimer += p_time;
@@ -1165,8 +1131,14 @@ void Player::Heartbeat()
// Group update
SendUpdateToOutOfRangeGroupMembers();
// Indoor/Outdoor aura requirements
CheckOutdoorsAuraRequirements();
// Updating Zone and AreaId. This will also trigger spell_area and phasing related updates
UpdateZoneAndAreaId();
// Updating auras which can only be used inside or outside (such as Mounts)
UpdateIndoorsOutdoorsAuras();
// Updating the resting state when entering resting places
UpdateTavernRestingState();
}
void Player::setDeathState(DeathState s)
@@ -6472,12 +6444,38 @@ bool Player::HasExploredZone(uint32 areaId) const
return (m_activePlayerData->BitVectors->Values[PLAYER_DATA_FLAG_EXPLORED_ZONES_INDEX][playerIndexOffset] & mask) != 0;
}
void Player::CheckOutdoorsAuraRequirements()
void Player::UpdateZoneAndAreaId()
{
uint32 newzone = 0, newarea = 0;
GetZoneAndAreaId(newzone, newarea);
if (m_zoneUpdateId != newzone)
UpdateZone(newzone, newarea); // also update area
else
{
// use area updates as well
// needed for free far all arenas for example
if (m_areaUpdateId != newarea)
UpdateArea(newarea);
}
}
void Player::UpdateIndoorsOutdoorsAuras()
{
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK))
RemoveAurasWithAttribute(IsOutdoors() ? SPELL_ATTR0_ONLY_INDOORS : SPELL_ATTR0_ONLY_OUTDOORS);
}
void Player::UpdateTavernRestingState()
{
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(_restMgr->GetInnTriggerID());
if (_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && (!atEntry || !IsInAreaTrigger(atEntry)))
_restMgr->RemoveRestFlag(REST_FLAG_IN_TAVERN);
else if (!_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && IsInAreaTrigger(atEntry))
_restMgr->SetRestFlag(REST_FLAG_IN_TAVERN);
}
Team Player::TeamForRace(uint8 race)
{
if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race))
@@ -7610,7 +7608,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
uint32 const oldZone = m_zoneUpdateId;
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
GetMap()->UpdatePlayerZoneStats(oldZone, newZone);

View File

@@ -2314,7 +2314,10 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void RemoveExploredZones(uint32 pos, uint64 mask);
bool HasExploredZone(uint32 areaId) const;
void CheckOutdoorsAuraRequirements();
// These methods are used to periodically update certain area and aura based mechanics used in Heartbeat and Movement
void UpdateZoneAndAreaId();
void UpdateIndoorsOutdoorsAuras();
void UpdateTavernRestingState();
static Team TeamForRace(uint8 race);
static TeamId TeamIdForRace(uint8 race);
@@ -3177,7 +3180,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
uint32 m_weaponChangeTimer;
uint32 m_zoneUpdateId;
uint32 m_zoneUpdateTimer;
uint32 m_areaUpdateId;
uint32 m_deathTimer;

View File

@@ -92,7 +92,7 @@ void RestMgr::AddRestBonus(RestTypes restType, float restBonus)
SetRestBonus(restType, totalRestBonus);
}
void RestMgr::SetRestFlag(RestFlag restFlag, uint32 triggerID)
void RestMgr::SetRestFlag(RestFlag restFlag)
{
uint32 oldRestMask = _restFlagMask;
_restFlagMask |= restFlag;
@@ -102,9 +102,6 @@ void RestMgr::SetRestFlag(RestFlag restFlag, uint32 triggerID)
_restTime = GameTime::GetGameTime();
_player->SetPlayerFlag(PLAYER_FLAGS_RESTING);
}
if (triggerID)
_innAreaTriggerId = triggerID;
}
void RestMgr::RemoveRestFlag(RestFlag restFlag)

View File

@@ -68,11 +68,12 @@ public:
void AddRestBonus(RestTypes restType, float restBonus);
bool HasRestFlag(RestFlag restFlag) const { return (_restFlagMask & restFlag) != 0; }
void SetRestFlag(RestFlag restFlag, uint32 triggerId = 0);
void SetRestFlag(RestFlag restFlag);
void RemoveRestFlag(RestFlag restFlag);
uint32 GetRestBonusFor(RestTypes restType, uint32 xp);
uint32 GetInnTriggerID() const { return _innAreaTriggerId; }
void SetInnTriggerID(uint32 id) { _innAreaTriggerId = id; }
void Update(time_t now);

View File

@@ -566,7 +566,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge
{
// set resting flag we are in the inn
if (packet.Entered)
player->GetRestMgr().SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->ID);
player->GetRestMgr().SetInnTriggerID(atEntry->ID);
else
player->GetRestMgr().RemoveRestFlag(REST_FLAG_IN_TAVERN);

View File

@@ -492,7 +492,7 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
Unit::ProcSkillsAndAuras(plrMover, nullptr, PROC_FLAG_JUMP, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
}
// Whenever a player stops a movement action, an indoor/outdoor check is being performed
// Whenever a player stops a movement action, several position based checks and updates are being performed
switch (opcode)
{
case CMSG_MOVE_SET_FLY:
@@ -503,7 +503,9 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
case CMSG_MOVE_STOP_SWIM:
case CMSG_MOVE_STOP_PITCH:
case CMSG_MOVE_STOP_ASCEND:
plrMover->CheckOutdoorsAuraRequirements();
plrMover->UpdateZoneAndAreaId();
plrMover->UpdateIndoorsOutdoorsAuras();
plrMover->UpdateTavernRestingState();
break;
default:
break;