mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 04:37:00 +00:00
[7088] Cleaned up Player::m_isunderwater, fixed a bug which caused SPELL_AURA_WATER_BREATHING to prevent lava damage
This commit is contained in:
parent
022e7ad2b5
commit
b19c0da601
4 changed files with 47 additions and 32 deletions
|
|
@ -348,7 +348,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
|
||||||
m_regenTimer = 0;
|
m_regenTimer = 0;
|
||||||
m_weaponChangeTimer = 0;
|
m_weaponChangeTimer = 0;
|
||||||
m_breathTimer = 0;
|
m_breathTimer = 0;
|
||||||
m_isunderwater = 0;
|
m_isunderwater = UNDERWATER_NONE;
|
||||||
m_isInWater = false;
|
m_isInWater = false;
|
||||||
m_drunkTimer = 0;
|
m_drunkTimer = 0;
|
||||||
m_drunk = 0;
|
m_drunk = 0;
|
||||||
|
|
@ -868,14 +868,15 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da
|
||||||
|
|
||||||
void Player::HandleDrowning()
|
void Player::HandleDrowning()
|
||||||
{
|
{
|
||||||
if(!m_isunderwater)
|
if(!(m_isunderwater&~UNDERWATER_INLAVA))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if player is GM, have waterbreath, is dead or if breathing is disabled then return
|
//if player is GM, have waterbreath, is dead or if breathing is disabled then return
|
||||||
if(HasAuraType(SPELL_AURA_WATER_BREATHING) || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
|
if(isGameMaster() || !isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
|
||||||
{
|
{
|
||||||
StopMirrorTimer(BREATH_TIMER);
|
StopMirrorTimer(BREATH_TIMER);
|
||||||
m_isunderwater = 0;
|
// drop every flag _except_ LAVA - otherwise waterbreathing will prevent lava damage
|
||||||
|
m_isunderwater &= UNDERWATER_INLAVA;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -885,22 +886,22 @@ void Player::HandleDrowning()
|
||||||
for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
|
for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
|
||||||
UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f);
|
UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f);
|
||||||
|
|
||||||
if ((m_isunderwater & 0x01) && !(m_isunderwater & 0x80) && isAlive())
|
if ((m_isunderwater & UNDERWATER_INWATER) && !(m_isunderwater & UNDERWATER_INLAVA) && isAlive())
|
||||||
{
|
{
|
||||||
//single trigger timer
|
//single trigger timer
|
||||||
if (!(m_isunderwater & 0x02))
|
if (!(m_isunderwater & UNDERWATER_WATER_TRIGGER))
|
||||||
{
|
{
|
||||||
m_isunderwater|= 0x02;
|
m_isunderwater|= UNDERWATER_WATER_TRIGGER;
|
||||||
m_breathTimer = UnderWaterTime + 1000;
|
m_breathTimer = UnderWaterTime + 1000;
|
||||||
}
|
}
|
||||||
//single trigger "Breathbar"
|
//single trigger "show Breathbar"
|
||||||
if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & 0x04))
|
if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & UNDERWATER_WATER_BREATHB))
|
||||||
{
|
{
|
||||||
m_isunderwater|= 0x04;
|
m_isunderwater|= UNDERWATER_WATER_BREATHB;
|
||||||
StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
|
StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
|
||||||
}
|
}
|
||||||
//continuous trigger drowning "Damage"
|
//continuous trigger drowning "Damage"
|
||||||
if ((m_breathTimer == 0) && (m_isunderwater & 0x01))
|
if ((m_breathTimer == 0) && (m_isunderwater & UNDERWATER_INWATER))
|
||||||
{
|
{
|
||||||
//TODO: Check this formula
|
//TODO: Check this formula
|
||||||
uint64 guid = GetGUID();
|
uint64 guid = GetGUID();
|
||||||
|
|
@ -911,33 +912,34 @@ void Player::HandleDrowning()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//single trigger retract bar
|
//single trigger retract bar
|
||||||
else if (!(m_isunderwater & 0x01) && !(m_isunderwater & 0x08) && (m_isunderwater & 0x02) && (m_breathTimer > 0) && isAlive())
|
else if (!(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater & UNDERWATER_WATER_TRIGGER) && (m_breathTimer > 0) && isAlive())
|
||||||
{
|
{
|
||||||
m_isunderwater = 0x08;
|
|
||||||
|
|
||||||
uint32 BreathRegen = 10;
|
uint32 BreathRegen = 10;
|
||||||
|
// m_breathTimer will be reduced in ModifyMirrorTimer
|
||||||
ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen);
|
ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen);
|
||||||
m_isunderwater = 0x10;
|
m_isunderwater = UNDERWATER_WATER_BREATHB_RETRACTING;
|
||||||
}
|
}
|
||||||
//remove bar
|
//remove bar
|
||||||
else if ((m_breathTimer < 50) && !(m_isunderwater & 0x01) && (m_isunderwater == 0x10))
|
else if ((m_breathTimer < 50) && !(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater == UNDERWATER_WATER_BREATHB_RETRACTING))
|
||||||
{
|
{
|
||||||
StopMirrorTimer(BREATH_TIMER);
|
StopMirrorTimer(BREATH_TIMER);
|
||||||
m_isunderwater = 0;
|
m_isunderwater = UNDERWATER_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::HandleLava()
|
void Player::HandleLava()
|
||||||
{
|
{
|
||||||
if ((m_isunderwater & 0x80) && isAlive())
|
if ((m_isunderwater & UNDERWATER_INLAVA) && isAlive())
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* arrai: how is this supposed to work? UNDERWATER_INLAVA is always set in this scope!
|
||||||
// Single trigger Set BreathTimer
|
// Single trigger Set BreathTimer
|
||||||
if (!(m_isunderwater & 0x80))
|
if (!(m_isunderwater & UNDERWATER_INLAVA))
|
||||||
{
|
{
|
||||||
m_isunderwater|= 0x04;
|
m_isunderwater|= UNDERWATER_WATER_BREATHB;
|
||||||
m_breathTimer = 1000;
|
m_breathTimer = 1000;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Reset BreathTimer and still in the lava
|
// Reset BreathTimer and still in the lava
|
||||||
if (!m_breathTimer)
|
if (!m_breathTimer)
|
||||||
{
|
{
|
||||||
|
|
@ -951,10 +953,10 @@ void Player::HandleLava()
|
||||||
m_breathTimer = 1000;
|
m_breathTimer = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_deathState == DEAD) // Disable breath timer and reset underwater flags
|
else if (!isAlive()) // Disable breath timer and reset underwater flags
|
||||||
{
|
{
|
||||||
m_breathTimer = 0;
|
m_breathTimer = 0;
|
||||||
m_isunderwater = 0;
|
m_isunderwater = UNDERWATER_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18846,18 +18848,20 @@ PartyResult Player::CanUninviteFromGroup() const
|
||||||
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
|
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
|
||||||
{
|
{
|
||||||
float water_z = m->GetWaterLevel(x,y);
|
float water_z = m->GetWaterLevel(x,y);
|
||||||
float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
|
float terrain_z = m->GetHeight(x,y,z, false); // use .map base surface height
|
||||||
uint8 flag1 = m->GetTerrainType(x,y);
|
uint8 flag1 = m->GetTerrainType(x,y);
|
||||||
|
|
||||||
//!Underwater check, not in water if underground or above water level
|
//!Underwater check, not in water if underground or above water level - take UC royal quater for example
|
||||||
if (height_z <= INVALID_HEIGHT || z < (height_z-2) || z > (water_z - 2) )
|
if (terrain_z <= INVALID_HEIGHT || z < (terrain_z-2) || z > (water_z - 2) )
|
||||||
m_isunderwater &= 0x7A;
|
m_isunderwater &= ~UNDERWATER_INWATER;
|
||||||
else if ((z < (water_z - 2)) && (flag1 & 0x01))
|
else if ((z < (water_z - 2)) && (flag1 & 0x01))
|
||||||
m_isunderwater |= 0x01;
|
m_isunderwater |= UNDERWATER_INWATER;
|
||||||
|
|
||||||
//!in lava check, anywhere under lava level
|
//!in lava check, anywhere under lava level
|
||||||
if ((height_z <= INVALID_HEIGHT || z < (height_z - 0)) && (flag1 == 0x00) && IsInWater())
|
if ((terrain_z <= INVALID_HEIGHT || z < (terrain_z - 0)) && (flag1 == 0x00) && IsInWater())
|
||||||
m_isunderwater |= 0x80;
|
m_isunderwater |= UNDERWATER_INLAVA;
|
||||||
|
else
|
||||||
|
m_isunderwater &= ~UNDERWATER_INLAVA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SetCanParry( bool value )
|
void Player::SetCanParry( bool value )
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,17 @@ enum SpellModType
|
||||||
SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER
|
SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 2^n values, Player::m_isunderwater is a bitmask. These are mangos internal values, they are never send to any client
|
||||||
|
enum PlayerUnderwaterState
|
||||||
|
{
|
||||||
|
UNDERWATER_NONE = 0x00,
|
||||||
|
UNDERWATER_INWATER = 0x01, // terrain type is water and player is afflicted by it
|
||||||
|
UNDERWATER_WATER_TRIGGER = 0x02, // m_breathTimer has been initialized
|
||||||
|
UNDERWATER_WATER_BREATHB = 0x04, // breathbar has been send to client
|
||||||
|
UNDERWATER_WATER_BREATHB_RETRACTING = 0x10, // breathbar is currently refilling - the player is above water level
|
||||||
|
UNDERWATER_INLAVA = 0x80 // terrain type is lava and player is afflicted by it
|
||||||
|
};
|
||||||
|
|
||||||
enum PlayerSpellState
|
enum PlayerSpellState
|
||||||
{
|
{
|
||||||
PLAYERSPELL_UNCHANGED = 0,
|
PLAYERSPELL_UNCHANGED = 0,
|
||||||
|
|
|
||||||
|
|
@ -2499,7 +2499,7 @@ void Aura::HandleAuraHover(bool apply, bool Real)
|
||||||
|
|
||||||
void Aura::HandleWaterBreathing(bool apply, bool Real)
|
void Aura::HandleWaterBreathing(bool apply, bool Real)
|
||||||
{
|
{
|
||||||
if(!apply && m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
|
if(!apply && !m_target->HasAuraType(SPELL_AURA_WATER_BREATHING))
|
||||||
{
|
{
|
||||||
// update for enable timer in case not moving target
|
// update for enable timer in case not moving target
|
||||||
if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
|
if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7087"
|
#define REVISION_NR "7088"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue