Fatigue For ArcEmu
This is my way of implementing fatigue on ArcEmu
It is not perfect and I still haven't figured out how to do it using water type information but this works 95% as it should.
Implementation
Check water height and if it is 0 (Errorous map) start fatigue mirror timer
What is fatigue?
That orange bar you get when you swim too far away from the land on the retail.
Note : Comment out or change CastSpell(this,35341,0); to remove/replace the spell which is casted on you once the fatigue bar gets full if you want to (I set it to Explosion Visual by default)
Installation
MovementHandler.cpp
Find :
Code:
void _HandleBreathing(MovementInfo &movement_info, Player * _player, WorldSession * pSession)
{
Add after :
Code:
float px = _player->GetPositionX();
float py = _player->GetPositionY();
float pz = _player->GetPositionZ();
float orient = _player->GetOrientation();
float posx = px;// = px + r * co;
float posy = py;// = py + r * si;
uint32 mapid = _player->GetMapId();
if(mapid == 0 || mapid == 1)
{
float mgr_t = _player->GetMapMgr()->GetLandHeight(posx,posy);
uint8 mgr_wt = _player->GetMapMgr()->GetWaterType(posx,posy);
float mgr_wh = _player->GetMapMgr()->GetWaterHeight(posx,posy);
if(mgr_wh == 0.0f)
{
_player->m_FatigueState = 1;
}
else
{
_player->m_FatigueState = 0;
}
}
Player.cpp
Find
Code:
m_SwimmingTime(0),
m_BreathDamageTimer(0),
Add after
Code:
//Fatigue
m_FatigueState(0),
m_FatigueTime(0),
m_FatigueMaxTime(10000),
Find
Code:
else
{
// check if we're not on a full breath timer
if(m_UnderwaterTime < m_UnderwaterMaxTime)
{
// regenning
m_UnderwaterTime += (p_time * 10);
if(m_UnderwaterTime >= m_UnderwaterMaxTime)
{
m_UnderwaterTime = m_UnderwaterMaxTime;
StopMirrorTimer(1);
}
}
}
Add after
Code:
// Fatigue
if( m_FatigueState == 1 )
{
//BroadcastMessage("Fatigue ON");
// keep subtracting timer
if( m_FatigueTime < m_FatigueMaxTime )
{
m_FatigueTime += (p_time * 2);
}
WorldPacket data(SMSG_START_MIRROR_TIMER, 20);
data << uint32( 0 ) << m_FatigueTime << m_FatigueMaxTime << int32(0) << uint32(0);
GetSession()->SendPacket(&data);
if( m_FatigueTime >= m_FatigueMaxTime )
{
// check last damage dealt timestamp, and if enough time has elapsed deal damage
//if( mstime >= m_FatigueLastDmg )
//{
//BroadcastMessage("Timer damage");
uint32 damage = m_uint32Values[UNIT_FIELD_MAXHEALTH] / 10;
DealDamage(this, damage, 0, 0, 0);
CastSpell(this,35341,0);
//}
}
}
else
{
//BroadcastMessage("Fatigue OFF");
//Full fatigue bar?
if(m_FatigueTime <= 0)
{
StopMirrorTimer(0);
m_FatigueTime = 0;
}
else
{
//BroadcastMessage("Regen Fatigue : %i" , m_FatigueTime);
//Restoring
m_FatigueTime -= (p_time * 2);
WorldPacket data(SMSG_START_MIRROR_TIMER, 20);
data << uint32( 0 ) << m_FatigueTime << m_FatigueMaxTime << int32(0) << uint32(0);
GetSession()->SendPacket(&data);
if(m_FatigueTime <= 0)
{
StopMirrorTimer(0);
m_FatigueTime = 0;
}
if(m_FatigueTime * -1 >= 0)
{
StopMirrorTimer(0);
m_FatigueTime = 0;
}
}
}