aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlos Manuelda <stormbyte@gmail.com>2015-08-23 20:32:54 +0200
committerDavid Carlos Manuelda <stormbyte@gmail.com>2015-08-23 20:32:54 +0200
commit603f49a55134de21b6c02b3cfcd9cb32b44c5f7b (patch)
tree7e95af3030bbfa5442181329a9cdd8854ac4d195
parent3a4f54197c05ce4209c7e659acfd382896607265 (diff)
parentc14b66c24c3c0afe222a0401171e882d4a1f98d9 (diff)
Merge pull request #15327 from Trisjdc/fix_rest_state
Core/Players: Improve rest state handling, allow several rest states to be active
-rw-r--r--src/server/game/Entities/Player/Player.cpp109
-rw-r--r--src/server/game/Entities/Player/Player.h35
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp4
3 files changed, 61 insertions, 87 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 5e1d1d37950..88d7dfa6381 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -749,7 +749,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;
@@ -780,10 +779,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;
@@ -1723,15 +1722,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);
}
}
}
@@ -1749,14 +1753,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;
@@ -1949,12 +1950,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;
-}
-
bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
{
// 0 1 2 3 4 5 6 7
@@ -7341,7 +7336,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 & AREA_FLAG_ARENA);
@@ -7363,16 +7358,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 & 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)
@@ -7438,36 +7426,12 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
if (zone->flags & 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); // Recently left a capital city
UpdatePvPState();
@@ -26599,3 +26563,30 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha
return true;
}
+
+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 42fa6dc2ea3..a031840a1d8 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -737,12 +737,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
@@ -1187,19 +1186,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);
@@ -2072,15 +2068,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 ***/
/*********************************************************/
@@ -2515,8 +2502,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;
@@ -2526,10 +2511,10 @@ class Player : public Unit, public GridObject<Player>
float m_ammoDPS;
////////////////////Rest System/////////////////////
- time_t time_inn_enter;
+ time_t _restTime;
uint32 inn_triggerId;
float m_rest_bonus;
- RestType rest_type;
+ uint32 _restFlagMask;
////////////////////Rest System/////////////////////
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 683b77e7aa0..7a9760ecf80 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -844,9 +844,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
if (sObjectMgr->IsTavernAreaTrigger(triggerId))
{
// 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);