Files
CypherCore/Source/Game/Entities/Player/RestMgr.cs
T

176 lines
6.4 KiB
C#

using Framework.Constants;
namespace Game.Entities
{
public class RestMgr
{
Player _player;
long _restTime;
InnAreaTrigger _innAreaTrigger;
float[] _restBonus = new float[(int)RestTypes.Max];
RestFlag _restFlagMask;
public RestMgr(Player player)
{
_player = player;
}
public void SetRestBonus(RestTypes restType, float restBonus)
{
uint next_level_xp;
bool affectedByRaF = false;
switch (restType)
{
case RestTypes.XP:
// Reset restBonus (XP only) for max level players
if (_player.GetLevel() >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
restBonus = 0;
next_level_xp = _player.m_activePlayerData.NextLevelXP;
affectedByRaF = true;
break;
case RestTypes.Honor:
// Reset restBonus (Honor only) for players with max honor level.
if (_player.IsMaxHonorLevel())
restBonus = 0;
next_level_xp = _player.m_activePlayerData.HonorNextLevel;
break;
default:
return;
}
float rest_bonus_max = next_level_xp * 1.5f / 2;
if (restBonus < 0)
restBonus = 0;
if (restBonus > rest_bonus_max)
restBonus = rest_bonus_max;
uint oldBonus = (uint)(_restBonus[(int)restType]);
_restBonus[(int)restType] = restBonus;
PlayerRestState oldRestState = (PlayerRestState)(int)_player.m_activePlayerData.RestInfo[(int)restType].StateID;
PlayerRestState newRestState = PlayerRestState.Normal;
if (affectedByRaF && _player.GetsRecruitAFriendBonus(true) && (_player.GetSession().IsARecruiter() || _player.GetSession().GetRecruiterId() != 0))
newRestState = PlayerRestState.RAFLinked;
else if (_restBonus[(int)restType] >= 1)
newRestState = PlayerRestState.Rested;
if (oldBonus == restBonus && oldRestState == newRestState)
return;
// update data for client
_player.SetRestThreshold(restType, (uint)_restBonus[(int)restType]);
_player.SetRestState(restType, newRestState);
}
public void AddRestBonus(RestTypes restType, float restBonus)
{
// 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).
if (_player.GetLevel() >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
restBonus = 0;
float totalRestBonus = GetRestBonus(restType) + restBonus;
SetRestBonus(restType, totalRestBonus);
}
public void SetRestFlag(RestFlag restFlag)
{
RestFlag oldRestMask = _restFlagMask;
_restFlagMask |= restFlag;
if (oldRestMask == 0 && _restFlagMask != 0) // only set flag/time on the first rest state
{
_restTime = GameTime.GetGameTime();
_player.SetPlayerFlag(PlayerFlags.Resting);
}
}
public void RemoveRestFlag(RestFlag restFlag)
{
RestFlag oldRestMask = _restFlagMask;
_restFlagMask &= ~restFlag;
if (oldRestMask != 0 && _restFlagMask == 0) // only remove flag/time on the last rest state remove
{
_restTime = 0;
_player.RemovePlayerFlag(PlayerFlags.Resting);
}
}
public uint GetRestBonusFor(RestTypes restType, uint xp)
{
uint rested_bonus = (uint)GetRestBonus(restType); // xp for each rested bonus
if (rested_bonus > xp) // max rested_bonus == xp or (r+x) = 200% xp
rested_bonus = xp;
uint rested_loss = rested_bonus;
if (restType == RestTypes.XP)
MathFunctions.AddPct(ref rested_loss, _player.GetTotalAuraModifier(AuraType.ModRestedXpConsumption));
SetRestBonus(restType, GetRestBonus(restType) - rested_loss);
Log.outDebug(LogFilter.Player, "RestMgr.GetRestBonus: Player '{0}' ({1}) gain {2} xp (+{3} Rested Bonus). Rested points={4}",
_player.GetGUID().ToString(), _player.GetName(), xp + rested_bonus, rested_bonus, GetRestBonus(restType));
return rested_bonus;
}
public void Update(uint now)
{
if (RandomHelper.randChance(3) && _restTime > 0) // freeze update
{
long timeDiff = now - _restTime;
if (timeDiff >= 10)
{
_restTime = now;
float bubble = 0.125f * WorldConfig.GetFloatValue(WorldCfg.RateRestIngame);
AddRestBonus(RestTypes.XP, timeDiff * CalcExtraPerSec(RestTypes.XP, bubble));
}
}
}
public void LoadRestBonus(RestTypes restType, PlayerRestState state, float restBonus)
{
_restBonus[(int)restType] = restBonus;
_player.SetRestState(restType, state);
_player.SetRestThreshold(restType, (uint)restBonus);
}
public float CalcExtraPerSec(RestTypes restType, float bubble)
{
switch (restType)
{
case RestTypes.Honor:
return _player.m_activePlayerData.HonorNextLevel / 72000.0f * bubble;
case RestTypes.XP:
return _player.m_activePlayerData.NextLevelXP / 72000.0f * bubble;
default:
return 0.0f;
}
}
public float GetRestBonus(RestTypes restType) { return _restBonus[(int)restType]; }
public bool HasRestFlag(RestFlag restFlag) { return (_restFlagMask & restFlag) != 0; }
public InnAreaTrigger GetInnTrigger() { return _innAreaTrigger; }
public void SetInnTrigger(InnAreaTrigger trigger) { _innAreaTrigger = trigger; }
}
public class InnAreaTrigger
{
public bool IsDBC = true;
public uint AreaTriggerEntryId;
public InnAreaTrigger(bool isDBC, uint areaTriggerEntryId = 0)
{
IsDBC = isDBC;
AreaTriggerEntryId = areaTriggerEntryId;
}
}
}