mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[7373] Implement expansion check at character loading (for homebind, transport and plain coordinates).
Also move fall damage calucaltion in new function.
This commit is contained in:
parent
9983286280
commit
02dd431846
4 changed files with 75 additions and 50 deletions
|
|
@ -231,52 +231,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||||
|
|
||||||
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
||||||
if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
|
if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
|
||||||
{
|
GetPlayer()->HandleFall(movementInfo);
|
||||||
// calculate total z distance of the fall
|
|
||||||
float z_diff = GetPlayer()->m_lastFallZ - movementInfo.z;
|
|
||||||
sLog.outDebug("zDiff = %f", z_diff);
|
|
||||||
Player *target = GetPlayer();
|
|
||||||
|
|
||||||
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
|
|
||||||
// 14.57 can be calculated by resolving damageperc formular below to 0
|
|
||||||
if (z_diff >= 14.57f && !target->isDead() && !target->isGameMaster() &&
|
|
||||||
!target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) &&
|
|
||||||
!target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL) )
|
|
||||||
{
|
|
||||||
//Safe fall, fall height reduction
|
|
||||||
int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
|
|
||||||
|
|
||||||
float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
|
|
||||||
|
|
||||||
if(damageperc >0 )
|
|
||||||
{
|
|
||||||
uint32 damage = (uint32)(damageperc * target->GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
|
|
||||||
|
|
||||||
float height = movementInfo.z;
|
|
||||||
target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
|
|
||||||
|
|
||||||
if (damage > 0)
|
|
||||||
{
|
|
||||||
//Prevent fall damage from being more than the player maximum health
|
|
||||||
if (damage > target->GetMaxHealth())
|
|
||||||
damage = target->GetMaxHealth();
|
|
||||||
|
|
||||||
// Gust of Wind
|
|
||||||
if (target->GetDummyAura(43621))
|
|
||||||
damage = target->GetMaxHealth()/2;
|
|
||||||
|
|
||||||
target->EnvironmentalDamage(target->GetGUID(), DAMAGE_FALL, damage);
|
|
||||||
|
|
||||||
// recheck alive, might have died of EnvironmentalDamage
|
|
||||||
if (target->isAlive())
|
|
||||||
target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
|
|
||||||
DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, target->GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
|
if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1567,6 +1567,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
else
|
else
|
||||||
// this will be used instead of the current location in SaveToDB
|
// this will be used instead of the current location in SaveToDB
|
||||||
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
|
m_teleport_dest = WorldLocation(mapid, x, y, z, orientation);
|
||||||
|
|
||||||
SetFallInformation(0, z);
|
SetFallInformation(0, z);
|
||||||
|
|
||||||
//BuildHeartBeatMsg(&data);
|
//BuildHeartBeatMsg(&data);
|
||||||
|
|
@ -14338,6 +14339,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
{
|
{
|
||||||
if( (*iter)->GetGUIDLow() == transGUID)
|
if( (*iter)->GetGUIDLow() == transGUID)
|
||||||
{
|
{
|
||||||
|
MapEntry const* transMapEntry = sMapStore.LookupEntry((*iter)->GetMapId());
|
||||||
|
// client without expansion support
|
||||||
|
if(GetSession()->Expansion() < transMapEntry->Expansion())
|
||||||
|
{
|
||||||
|
sLog.outDebug("Player %s using client without required expansion tried login at transport at non accessible map %u", GetName(), (*iter)->GetMapId());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_transport = *iter;
|
m_transport = *iter;
|
||||||
m_transport->AddPassenger(this);
|
m_transport->AddPassenger(this);
|
||||||
SetMapId(m_transport->GetMapId());
|
SetMapId(m_transport->GetMapId());
|
||||||
|
|
@ -14347,7 +14356,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
|
|
||||||
if(!m_transport)
|
if(!m_transport)
|
||||||
{
|
{
|
||||||
sLog.outError("ERROR: Player (guidlow %d) have invalid transport guid (%u). Teleport to default race/class locations.",
|
sLog.outError("ERROR: Player (guidlow %d) have problems with transport guid (%u). Teleport to default race/class locations.",
|
||||||
guid,transGUID);
|
guid,transGUID);
|
||||||
|
|
||||||
RelocateToHomebind();
|
RelocateToHomebind();
|
||||||
|
|
@ -14360,6 +14369,16 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
transGUID = 0;
|
transGUID = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // not transport case
|
||||||
|
{
|
||||||
|
MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||||
|
// client without expansion support
|
||||||
|
if(GetSession()->Expansion() < mapEntry->Expansion())
|
||||||
|
{
|
||||||
|
sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), GetMapId());
|
||||||
|
RelocateToHomebind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOW player must have valid map
|
// NOW player must have valid map
|
||||||
// load the player's map here if it's not already loaded
|
// load the player's map here if it's not already loaded
|
||||||
|
|
@ -15592,9 +15611,11 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
||||||
m_homebindZ = fields[4].GetFloat();
|
m_homebindZ = fields[4].GetFloat();
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
// accept saved data only for valid position (and non instanceable)
|
MapEntry const* bindMapEntry = sMapStore.LookupEntry(m_homebindMapId);
|
||||||
|
|
||||||
|
// accept saved data only for valid position (and non instanceable), and accessable
|
||||||
if( MapManager::IsValidMapCoord(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ) &&
|
if( MapManager::IsValidMapCoord(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ) &&
|
||||||
!sMapStore.LookupEntry(m_homebindMapId)->Instanceable() )
|
!bindMapEntry->Instanceable() && GetSession()->Expansion() >= bindMapEntry->Expansion())
|
||||||
{
|
{
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
@ -19776,3 +19797,50 @@ uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_s
|
||||||
|
|
||||||
return EQUIP_ERR_OK;
|
return EQUIP_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::HandleFall(MovementInfo const& movementInfo)
|
||||||
|
{
|
||||||
|
// calculate total z distance of the fall
|
||||||
|
float z_diff = m_lastFallZ - movementInfo.z;
|
||||||
|
sLog.outDebug("zDiff = %f", z_diff);
|
||||||
|
|
||||||
|
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
|
||||||
|
// 14.57 can be calculated by resolving damageperc formular below to 0
|
||||||
|
if (z_diff >= 14.57f && !isDead() && !isGameMaster() &&
|
||||||
|
!HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
|
||||||
|
!HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL) )
|
||||||
|
{
|
||||||
|
//Safe fall, fall height reduction
|
||||||
|
int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
|
||||||
|
|
||||||
|
float damageperc = 0.018f*(z_diff-safe_fall)-0.2426f;
|
||||||
|
|
||||||
|
if(damageperc >0 )
|
||||||
|
{
|
||||||
|
uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld.getRate(RATE_DAMAGE_FALL));
|
||||||
|
|
||||||
|
float height = movementInfo.z;
|
||||||
|
UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
|
||||||
|
|
||||||
|
if (damage > 0)
|
||||||
|
{
|
||||||
|
//Prevent fall damage from being more than the player maximum health
|
||||||
|
if (damage > GetMaxHealth())
|
||||||
|
damage = GetMaxHealth();
|
||||||
|
|
||||||
|
// Gust of Wind
|
||||||
|
if (GetDummyAura(43621))
|
||||||
|
damage = GetMaxHealth()/2;
|
||||||
|
|
||||||
|
EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
|
||||||
|
|
||||||
|
// recheck alive, might have died of EnvironmentalDamage
|
||||||
|
if (isAlive())
|
||||||
|
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
|
||||||
|
DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2010,6 +2010,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
m_lastFallTime = time;
|
m_lastFallTime = time;
|
||||||
m_lastFallZ = z;
|
m_lastFallZ = z;
|
||||||
}
|
}
|
||||||
|
void HandleFall(MovementInfo const& movementInfo);
|
||||||
|
|
||||||
bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); }
|
bool isMoving() const { return HasUnitMovementFlag(movementFlagsMask); }
|
||||||
bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); }
|
bool isMovingOrTurning() const { return HasUnitMovementFlag(movementOrTurningFlagsMask); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7372"
|
#define REVISION_NR "7373"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue