diff options
author | Trisjdc <trisjdc@gmail.com> | 2015-08-23 10:47:16 +0100 |
---|---|---|
committer | Carbenium <carbenium@outlook.com> | 2015-09-24 23:24:13 +0200 |
commit | 93e77bfc7b94d4e3505189d614a7da90877f166d (patch) | |
tree | f538e087f494505c3505081b22fd466abdca082d /src | |
parent | e5eea44e0afb038d9b04e61b93d69f25e37879af (diff) |
Core/Players: Improve rest state handling, allow several rest states to be active
Fixes https://github.com/TrinityCore/TrinityCore/issues/15325
(cherry picked from commit c14b66c24c3c0afe222a0401171e882d4a1f98d9)
Conflicts:
src/server/game/Entities/Player/Player.cpp
src/server/game/Handlers/MiscHandler.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 108 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 35 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 4 |
3 files changed, 60 insertions, 87 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e61dfc72a4f..4118b39f303 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -603,7 +603,6 @@ Player::Player(WorldSession* session) : Unit(true) m_MirrorTimerFlagsLast = UNDERWATER_NONE; m_isInWater = false; m_drunkTimer = 0; - m_restTime = 0; m_deathTimer = 0; m_deathExpireTime = 0; @@ -634,10 +633,10 @@ Player::Player(WorldSession* session) : Unit(true) m_lastpetnumber = 0; ////////////////////Rest System///////////////////// - time_inn_enter = 0; + _restTime = 0; inn_triggerId = 0; m_rest_bonus = 0; - rest_type = REST_TYPE_NO; + _restFlagMask = 0; ////////////////////Rest System///////////////////// m_mailsLoaded = false; @@ -1569,15 +1568,20 @@ void Player::Update(uint32 p_time) if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) { - if (roll_chance_i(3) && GetTimeInnEnter() > 0) // freeze update + if (roll_chance_i(3) && _restTime > 0) // freeze update { - time_t time_inn = time(NULL)-GetTimeInnEnter(); - if (time_inn >= 10) // freeze update + time_t currTime = time(nullptr); + time_t timeDiff = currTime - _restTime; + if (timeDiff >= 10) // freeze update { - float bubble = 0.125f*sWorld->getRate(RATE_REST_INGAME); - // speed collect rest bonus (section/in hour) - SetRestBonus(GetRestBonus()+ time_inn*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble); - UpdateInnerTime(time(NULL)); + _restTime = currTime; + + float bubble = 0.125f * sWorld->getRate(RATE_REST_INGAME); + float extraPerSec = ((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 72000.0f) * bubble; + + // speed collect rest bonus (section/in hour) + float currRestBonus = GetRestBonus(); + SetRestBonus(currRestBonus + timeDiff * extraPerSec); } } } @@ -1595,14 +1599,11 @@ void Player::Update(uint32 p_time) 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 (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) && GetRestType() == REST_TYPE_IN_TAVERN) + if (HasRestFlag(REST_FLAG_IN_TAVERN)) { AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(GetInnTriggerId()); if (!atEntry || !IsInAreaTriggerRadius(atEntry)) - { - RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_NO); - } + RemoveRestFlag(REST_FLAG_IN_TAVERN); } uint32 newzone, newarea; @@ -1795,12 +1796,6 @@ void Player::setDeathState(DeathState s) SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); } -void Player::InnEnter(time_t time, uint32 triggerId) -{ - inn_triggerId = triggerId; - time_inn_enter = time; -} - void Player::ToggleAFK() { ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); @@ -7216,7 +7211,7 @@ void Player::UpdateArea(uint32 newArea) { // FFA_PVP flags are area and not zone id dependent // so apply them accordingly - m_areaUpdateId = newArea; + m_areaUpdateId = newArea; AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); pvpInfo.IsInFFAPvPArea = area && (area->Flags[0] & AREA_FLAG_ARENA); @@ -7238,16 +7233,9 @@ void Player::UpdateArea(uint32 newArea) uint32 const areaRestFlag = (GetTeam() == ALLIANCE) ? AREA_FLAG_REST_ZONE_ALLIANCE : AREA_FLAG_REST_ZONE_HORDE; if (area && area->Flags[0] & areaRestFlag) - { - SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_IN_FACTION_AREA); - InnEnter(time(nullptr), 0); - } - else if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) && GetRestType() == REST_TYPE_IN_FACTION_AREA) - { - RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_NO); - } + SetRestFlag(REST_FLAG_IN_FACTION_AREA); + else + RemoveRestFlag(REST_FLAG_IN_FACTION_AREA); } void Player::UpdateZone(uint32 newZone, uint32 newArea) @@ -7317,36 +7305,11 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (zone->Flags[0] & AREA_FLAG_CAPITAL) // Is in a capital city { if (!pvpInfo.IsHostile || zone->IsSanctuary()) - { - SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_IN_CITY); - InnEnter(time(nullptr), 0); - } + SetRestFlag(REST_FLAG_IN_CITY); pvpInfo.IsInNoPvPArea = true; } else - { - if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) - { - if (GetRestType() == REST_TYPE_IN_TAVERN) // Still inside a tavern or has recently left - { - // check that we are still inside the tavern (in areatrigger radius) - - AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(GetInnTriggerId()); - if (!atEntry || !IsInAreaTriggerRadius(atEntry)) - { - RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_NO); - } - } - else if (GetRestType() != REST_TYPE_IN_FACTION_AREA) // handled in UpdateArea - { - // Recently left a capital city - RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - SetRestType(REST_TYPE_NO); - } - } - } + RemoveRestFlag(REST_FLAG_IN_CITY); UpdatePvPState(); @@ -26663,3 +26626,30 @@ void Player::SendRaidGroupOnlyMessage(RaidGroupReason reason, int32 delay) GetSession()->SendPacket(raidGroupOnly.Write()); } + +void Player::SetRestFlag(RestFlag restFlag, uint32 triggerId /*= 0*/) +{ + uint32 oldRestMask = _restFlagMask; + _restFlagMask |= restFlag; + + if (!oldRestMask && _restFlagMask) // only set flag/time on the first rest state + { + _restTime = time(nullptr); + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + } + + if (triggerId) + inn_triggerId = triggerId; +} + +void Player::RemoveRestFlag(RestFlag restFlag) +{ + uint32 oldRestMask = _restFlagMask; + _restFlagMask &= ~restFlag; + + if (oldRestMask && !_restFlagMask) // only remove flag/time on the last rest state remove + { + _restTime = 0; + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); + } +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index db8a6170e9b..0f481741369 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -907,12 +907,11 @@ enum ArenaTeamInfoType class InstanceSave; -enum RestType +enum RestFlag { - REST_TYPE_NO = 0, - REST_TYPE_IN_TAVERN = 1, - REST_TYPE_IN_CITY = 2, - REST_TYPE_IN_FACTION_AREA = 3 // used with AREA_FLAG_REST_ZONE_* + REST_FLAG_IN_TAVERN = 0x1, + REST_FLAG_IN_CITY = 0x2, + REST_FLAG_IN_FACTION_AREA = 0x4, // used with AREA_FLAG_REST_ZONE_* }; enum TeleportToOptions @@ -1368,19 +1367,16 @@ class Player : public Unit, public GridObject<Player> void setDeathState(DeathState s) override; // overwrite Unit::setDeathState - void InnEnter(time_t time, uint32 triggerId); - float GetRestBonus() const { return m_rest_bonus; } void SetRestBonus(float rest_bonus_new); - RestType GetRestType() const { return rest_type; } - void SetRestType(RestType n_r_type) { rest_type = n_r_type; } + bool HasRestFlag(RestFlag restFlag) const { return (_restFlagMask & restFlag) != 0; } + void SetRestFlag(RestFlag restFlag, uint32 triggerId = 0); + void RemoveRestFlag(RestFlag restFlag); + uint32 GetXPRestBonus(uint32 xp); uint32 GetInnTriggerId() const { return inn_triggerId; } - time_t GetTimeInnEnter() const { return time_inn_enter; } - void UpdateInnerTime (time_t time) { time_inn_enter = time; } - Pet* GetPet() const; Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime); void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); @@ -2317,15 +2313,6 @@ class Player : public Unit, public GridObject<Player> bool IsOutdoorPvPActive(); /*********************************************************/ - /*** REST SYSTEM ***/ - /*********************************************************/ - - bool isRested() const { return GetRestTime() >= 10*IN_MILLISECONDS; } - uint32 GetXPRestBonus(uint32 xp); - uint32 GetRestTime() const { return m_restTime;} - void SetRestTime(uint32 v) { m_restTime = v;} - - /*********************************************************/ /*** ENVIROMENTAL SYSTEM ***/ /*********************************************************/ @@ -2810,8 +2797,6 @@ class Player : public Unit, public GridObject<Player> uint32 m_deathTimer; time_t m_deathExpireTime; - uint32 m_restTime; - uint32 m_WeaponProficiency; uint32 m_ArmorProficiency; bool m_canParry; @@ -2820,10 +2805,10 @@ class Player : public Unit, public GridObject<Player> uint8 m_swingErrorMsg; ////////////////////Rest System///////////////////// - time_t time_inn_enter; + time_t _restTime; uint32 inn_triggerId; float m_rest_bonus; - RestType rest_type; + uint32 _restFlagMask; ////////////////////Rest System///////////////////// // Social diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 8151ff70248..1d98b85a441 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -509,9 +509,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::Misc::AreaTrigger& pack if (sObjectMgr->IsTavernAreaTrigger(packet.AreaTriggerID)) { // set resting flag we are in the inn - player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); - player->InnEnter(time(nullptr), atEntry->ID); - player->SetRestType(REST_TYPE_IN_TAVERN); + player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->ID); if (sWorld->IsFFAPvPRealm()) player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); |