TrinityCore
RestMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "RestMgr.h"
19#include "GameTime.h"
20#include "Log.h"
21#include "Player.h"
22#include "Random.h"
23#include "World.h"
24#include "WorldSession.h"
25
26RestMgr::RestMgr(Player* player) : _player(player), _restTime(0), _innAreaTriggerId(0), _restFlagMask(0)
27{
28 for (uint8 i = REST_TYPE_XP; i < REST_TYPE_MAX; i++)
29 _restBonus[i] = 0;
30}
31
32void RestMgr::SetRestBonus(RestTypes restType, float restBonus)
33{
34 int32 next_level_xp;
35 bool affectedByRaF = false;
36
37 switch (restType)
38 {
39 case REST_TYPE_XP:
40 // Reset restBonus (XP only) for max level players
41 if (_player->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
42 restBonus = 0;
43
44 next_level_xp = _player->m_activePlayerData->NextLevelXP;
45 affectedByRaF = true;
46 break;
47 case REST_TYPE_HONOR:
48 // Reset restBonus (Honor only) for players with max honor level.
50 restBonus = 0;
51
52 next_level_xp = _player->m_activePlayerData->HonorNextLevel;
53 break;
54 default:
55 return;
56 }
57
58 float rest_bonus_max = float(next_level_xp) * 1.5f / 2;
59
60 if (restBonus < 0)
61 restBonus = 0;
62
63 if (restBonus > rest_bonus_max)
64 restBonus = rest_bonus_max;
65
66 uint32 oldBonus = uint32(_restBonus[restType]);
67 _restBonus[restType] = restBonus;
68
69 PlayerRestState oldRestState = static_cast<PlayerRestState>(*_player->m_activePlayerData->RestInfo[restType].StateID);
71
72 if (affectedByRaF && _player->GetsRecruitAFriendBonus(true) && (_player->GetSession()->IsARecruiter() || _player->GetSession()->GetRecruiterId() != 0))
73 newRestState = REST_STATE_RAF_LINKED;
74 else if (_restBonus[restType] >= 1)
75 newRestState = REST_STATE_RESTED;
76
77 if (oldBonus == uint32(restBonus) && oldRestState == newRestState)
78 return;
79
80 // update data for client
81 _player->SetRestThreshold(restType, uint32(_restBonus[restType]));
82 _player->SetRestState(restType, newRestState);
83}
84
85void RestMgr::AddRestBonus(RestTypes restType, float restBonus)
86{
87 // Don't add extra rest bonus to max level players. Note: Might need different condition in next expansion for honor XP (PLAYER_LEVEL_MIN_HONOR perhaps).
88 if (_player->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
89 restBonus = 0;
90
91 float totalRestBonus = GetRestBonus(restType) + restBonus;
92 SetRestBonus(restType, totalRestBonus);
93}
94
95void RestMgr::SetRestFlag(RestFlag restFlag, uint32 triggerID)
96{
97 uint32 oldRestMask = _restFlagMask;
98 _restFlagMask |= restFlag;
99
100 if (!oldRestMask && _restFlagMask) // only set flag/time on the first rest state
101 {
104 }
105
106 if (triggerID)
107 _innAreaTriggerId = triggerID;
108}
109
111{
112 uint32 oldRestMask = _restFlagMask;
113 _restFlagMask &= ~restFlag;
114
115 if (oldRestMask && !_restFlagMask) // only remove flag/time on the last rest state remove
116 {
117 _restTime = 0;
119 }
120}
121
123{
124 uint32 rested_bonus = uint32(GetRestBonus(restType)); // xp for each rested bonus
125
126 if (rested_bonus > xp) // max rested_bonus == xp or (r+x) = 200% xp
127 rested_bonus = xp;
128
129 uint32 rested_loss = rested_bonus;
130 if (restType == REST_TYPE_XP)
132
133 SetRestBonus(restType, GetRestBonus(restType) - rested_loss);
134
135 TC_LOG_DEBUG("entities.player", "RestMgr::GetRestBonus: Player '{}' ({}) gain {} xp (+{} Rested Bonus). Rested points={}", _player->GetGUID().ToString(), _player->GetName(), xp + rested_bonus, rested_bonus, GetRestBonus(restType));
136 return rested_bonus;
137}
138
139void RestMgr::Update(time_t now)
140{
141 if (roll_chance_i(3) && _restTime > 0) // freeze update
142 {
143 time_t timeDiff = now - _restTime;
144 if (timeDiff >= 10)
145 {
146 _restTime = now;
147
148 float bubble = 0.125f * sWorld->getRate(RATE_REST_INGAME);
150 }
151 }
152}
153
154void RestMgr::LoadRestBonus(RestTypes restType, PlayerRestState state, float restBonus)
155{
156 _restBonus[restType] = restBonus;
157 _player->SetRestState(restType, state);
158 _player->SetRestThreshold(restType, uint32(restBonus));
159}
160
161float RestMgr::CalcExtraPerSec(RestTypes restType, float bubble) const
162{
163 switch (restType)
164 {
165 case REST_TYPE_HONOR:
166 return float(_player->m_activePlayerData->HonorNextLevel) / 72000.0f * bubble;
167 case REST_TYPE_XP:
168 return float(_player->m_activePlayerData->NextLevelXP) / 72000.0f * bubble;
169 default:
170 return 0.0f;
171 }
172}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
@ PLAYER_FLAGS_RESTING
Definition: Player.h:433
bool roll_chance_i(int chance)
Definition: Random.h:59
PlayerRestState
Definition: RestMgr.h:45
@ REST_STATE_NORMAL
Definition: RestMgr.h:47
@ REST_STATE_RESTED
Definition: RestMgr.h:46
@ REST_STATE_RAF_LINKED
Definition: RestMgr.h:48
RestFlag
Definition: RestMgr.h:52
RestTypes
Definition: RestMgr.h:27
@ REST_TYPE_MAX
Definition: RestMgr.h:30
@ REST_TYPE_XP
Definition: RestMgr.h:28
@ REST_TYPE_HONOR
Definition: RestMgr.h:29
@ SPELL_AURA_MOD_RESTED_XP_CONSUMPTION
T AddPct(T &base, U pct)
Definition: Util.h:85
std::string ToString() const
Definition: ObjectGuid.cpp:554
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void SetPlayerFlag(PlayerFlags flags)
Definition: Player.h:2738
void RemovePlayerFlag(PlayerFlags flags)
Definition: Player.h:2739
void SetRestThreshold(RestTypes type, uint32 threshold)
Definition: Player.h:2725
WorldSession * GetSession() const
Definition: Player.h:2101
bool GetsRecruitAFriendBonus(bool forXP)
Definition: Player.cpp:25604
bool IsMaxHonorLevel() const
Definition: Player.h:2279
UF::UpdateField< UF::ActivePlayerData, 0, TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition: Player.h:2864
void SetRestState(RestTypes type, PlayerRestState state)
Definition: Player.h:2718
float _restBonus[REST_TYPE_MAX]
Definition: RestMgr.h:88
uint32 GetRestBonusFor(RestTypes restType, uint32 xp)
Definition: RestMgr.cpp:122
time_t _restTime
Definition: RestMgr.h:86
void Update(time_t now)
Definition: RestMgr.cpp:139
Player * _player
Definition: RestMgr.h:85
void AddRestBonus(RestTypes restType, float restBonus)
Definition: RestMgr.cpp:85
void SetRestBonus(RestTypes restType, float restBonus)
Definition: RestMgr.cpp:32
void LoadRestBonus(RestTypes restType, PlayerRestState state, float restBonus)
Definition: RestMgr.cpp:154
uint32 _restFlagMask
Definition: RestMgr.h:89
float GetRestBonus(RestTypes restType) const
Definition: RestMgr.h:65
RestMgr(Player *player)
Definition: RestMgr.cpp:26
float CalcExtraPerSec(RestTypes restType, float bubble) const
Definition: RestMgr.cpp:161
void SetRestFlag(RestFlag restFlag, uint32 triggerId=0)
Definition: RestMgr.cpp:95
void RemoveRestFlag(RestFlag restFlag)
Definition: RestMgr.cpp:110
uint32 _innAreaTriggerId
Definition: RestMgr.h:87
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4929
uint8 GetLevel() const
Definition: Unit.h:746
std::string const & GetName() const
Definition: Object.h:555
uint32 GetRecruiterId() const
bool IsARecruiter() const
#define sWorld
Definition: World.h:931
@ CONFIG_MAX_PLAYER_LEVEL
Definition: World.h:259
@ RATE_REST_INGAME
Definition: World.h:515
time_t GetGameTime()
Definition: GameTime.cpp:44