[10165] New collission system (vmap) implementation

Important:
* You have to re-extract and assemble vmaps
* Update your config file, new option 'vmap.enableIndoorCheck' added

New features:
* Include WMO+DBC area information for correct subarea identification and indoor check
* Support for WMO liquid (fishing/swimming in cities, instances and oterh WMO based environments)

Technical changes:
* New Bounding Interval Hierarchy (BIH) data structure for better performance
* Referenced model data for reduced memory usage,
  needs more files, but reduces overall file size from ~1.9GB to ~550MB

Additional Authors:
arrai (DBC handling and indoor detection)
faramir118 (windows support and bug investigation)
And of course thanks Vladimir for a lot of patience and support!
This commit is contained in:
Lynx3d 2010-07-08 23:17:18 +02:00
parent c2bcfd0f18
commit 5e89098a61
57 changed files with 3472 additions and 5694 deletions

View file

@ -1117,7 +1117,9 @@ void Player::HandleDrowning(uint32 time_diff)
uint32 damage = urand(600, 700);
if (m_MirrorTimerFlags&UNDERWATER_INLAVA)
EnvironmentalDamage(DAMAGE_LAVA, damage);
else
// need to skip Slime damage in Undercity,
// maybe someone can find better way to handle environmental damage
else if (m_zoneUpdateId != 1497)
EnvironmentalDamage(DAMAGE_SLIME, damage);
}
}
@ -6050,7 +6052,7 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
// code block for underwater state update
UpdateUnderwaterState(m, x, y, z);
CheckExploreSystem();
CheckAreaExploreAndOutdoor();
return true;
}
@ -6112,7 +6114,7 @@ void Player::SendMovieStart(uint32 MovieId)
SendDirectMessage(&data);
}
void Player::CheckExploreSystem()
void Player::CheckAreaExploreAndOutdoor()
{
if (!isAlive())
return;
@ -6120,12 +6122,17 @@ void Player::CheckExploreSystem()
if (isInFlight())
return;
uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ());
if(areaFlag==0xffff)
bool isOutdoor;
uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ(), &isOutdoor);
if (sWorld.getConfig(CONFIG_BOOL_VMAP_INDOOR_CHECK) && !isOutdoor)
RemoveAurasWithAttribute(SPELL_ATTR_OUTDOORS_ONLY);
if (areaFlag==0xffff)
return;
int offset = areaFlag / 32;
if(offset >= PLAYER_EXPLORED_ZONES_SIZE)
if (offset >= PLAYER_EXPLORED_ZONES_SIZE)
{
sLog.outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset, PLAYER_EXPLORED_ZONES_SIZE);
return;
@ -6134,7 +6141,7 @@ void Player::CheckExploreSystem()
uint32 val = (uint32)(1 << (areaFlag % 32));
uint32 currFields = GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
if( !(currFields & val) )
if (!(currFields & val))
{
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
@ -20565,8 +20572,8 @@ void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
m_MirrorTimerFlags &= ~(UNDERWATER_INWATER|UNDERWATER_INLAVA|UNDERWATER_INSLIME|UNDERWATER_INDARKWATER);
// Small hack for enable breath in WMO
if (IsInWater())
m_MirrorTimerFlags|=UNDERWATER_INWATER;
/* if (IsInWater())
m_MirrorTimerFlags|=UNDERWATER_INWATER; */
return;
}