Core/Maps
* Corrected liquid type extraction in maps - MCLQ chunk must be parsed together with MH2O (they stack) * Fixed liquid detection in WMO objects * Implemented LiquidType.dbc use, players will now get proper auras in special liquids * Turned off slime damage by default (Naxxramas uses periodic damage aura for this purpose) * Implemented liquid type overrides basing on area/zone * Renamed final temp_gameobject_models to GameObjectModels.dtree (the temporary one produced by vmap extractor remains unaffected) Note: Map and Vmap re-extraction is required
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
DELETE FROM `trinity_string` WHERE `entry`=175;
|
||||
INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
|
||||
(175, 'Liquid level: %f, ground: %f, type: %u, flags %u, status: %d.');
|
||||
@@ -233,7 +233,7 @@ namespace VMAP
|
||||
{
|
||||
floor = info.ground_Z;
|
||||
ASSERT(floor < std::numeric_limits<float>::max());
|
||||
type = info.hitModel->GetLiquidType();
|
||||
type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
|
||||
if (reqLiquidType && !(type & reqLiquidType))
|
||||
return false;
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info, level))
|
||||
|
||||
@@ -335,7 +335,7 @@ namespace VMAP
|
||||
|
||||
void TileAssembler::exportGameobjectModels()
|
||||
{
|
||||
FILE* model_list = fopen((iSrcDir + "/" + GAMEOBJECT_MODELS).c_str(), "rb");
|
||||
FILE* model_list = fopen((iSrcDir + "/" + "temp_gameobject_models").c_str(), "rb");
|
||||
FILE* model_list_copy = fopen((iDestDir + "/" + GAMEOBJECT_MODELS).c_str(), "wb");
|
||||
if (!model_list || !model_list_copy)
|
||||
return;
|
||||
|
||||
@@ -392,9 +392,8 @@ namespace VMAP
|
||||
|
||||
uint32 GroupModel::GetLiquidType() const
|
||||
{
|
||||
// convert to type mask, matching MAP_LIQUID_TYPE_* defines in Map.h
|
||||
if (iLiquid)
|
||||
return (1 << iLiquid->GetType());
|
||||
return iLiquid->GetType();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
const char VMAP_MAGIC[] = "VMAP_4.0";
|
||||
const char RAW_VMAP_MAGIC[] = "VMAP004"; // used in extracted vmap files with raw data
|
||||
const char GAMEOBJECT_MODELS[] = "temp_gameobject_models";
|
||||
const char VMAP_MAGIC[] = "VMAP_4.1";
|
||||
const char RAW_VMAP_MAGIC[] = "VMAP041"; // used in extracted vmap files with raw data
|
||||
const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree";
|
||||
|
||||
// defined in TileAssembler.cpp currently...
|
||||
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len);
|
||||
|
||||
@@ -119,7 +119,7 @@ DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
|
||||
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
|
||||
|
||||
DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt);
|
||||
//DBCStorage <LiquidTypeEntry> sLiquidTypeStore(LiquidTypeEntryfmt);
|
||||
DBCStorage <LiquidTypeEntry> sLiquidTypeStore(LiquidTypefmt);
|
||||
DBCStorage <LockEntry> sLockStore(LockEntryfmt);
|
||||
|
||||
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
|
||||
@@ -357,6 +357,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc");
|
||||
|
||||
@@ -119,7 +119,7 @@ extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
|
||||
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
|
||||
extern DBCStorage <ItemSetEntry> sItemSetStore;
|
||||
extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
|
||||
//extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
|
||||
extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
|
||||
extern DBCStorage <LockEntry> sLockStore;
|
||||
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
||||
extern DBCStorage <MapEntry> sMapStore;
|
||||
|
||||
@@ -527,6 +527,7 @@ struct AreaTableEntry
|
||||
char* area_name[16]; // 11-26
|
||||
// 27, string flags, unused
|
||||
uint32 team; // 28
|
||||
uint32 LiquidTypeOverride[4]; // 29-32 liquid override by type
|
||||
|
||||
// helpers
|
||||
bool IsSanctuary() const
|
||||
@@ -1214,30 +1215,29 @@ struct LFGDungeonEntry
|
||||
uint32 Entry() const { return ID + (type << 24); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
struct LiquidTypeEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
char* name; // 1
|
||||
uint32 flags; // 2 Water: 1|2|4|8, Magma: 8|16|32|64, Slime: 2|64|256, WMO Ocean: 1|2|4|8|512
|
||||
uint32 type; // 3 0: Water, 1: Ocean, 2: Magma, 3: Slime
|
||||
uint32 soundid; // 4 Reference to SoundEntries.dbc
|
||||
uint32 spellID; // 5 Reference to Spell.dbc
|
||||
float maxDarkenDepth // 6 Only Slime (6) and Magma (7)
|
||||
float fogDarkenIntensity // 7 Only oceans got values here!
|
||||
float ambDarkenIntensity // 8 Only oceans got values here!
|
||||
float dirDarkenIntensity // 9 Only oceans got values here!
|
||||
uint32 lightID // 10 Only Slime (6) and Magma (7)
|
||||
float particleScale // 11 0: Slime, 1: Water/Ocean, 4: Magma
|
||||
uint32 particleMovement // 12
|
||||
uint32 particleTexSlots // 13
|
||||
uint32 LiquidMaterialID // 14 Reference to LiquidMaterial.dbc
|
||||
char* texture[6]; // 15-20
|
||||
uint32 color[2] // 21-22
|
||||
float floats[18]; // 23-40 Most likely these are attributes for the shaders. Water: (23, TextureTilesPerBlock),(24, Rotation) Magma: (23, AnimationX),(24, AnimationY)
|
||||
uint32 ints[4] // 41-44
|
||||
uint32 Id;
|
||||
//char* Name;
|
||||
//uint32 Flags;
|
||||
uint32 Type;
|
||||
//uint32 SoundId;
|
||||
uint32 SpellId;
|
||||
//float MaxDarkenDepth;
|
||||
//float FogDarkenIntensity;
|
||||
//float AmbDarkenIntensity;
|
||||
//float DirDarkenIntensity;
|
||||
//uint32 LightID;
|
||||
//float ParticleScale;
|
||||
//uint32 ParticleMovement;
|
||||
//uint32 ParticleTexSlots;
|
||||
//uint32 LiquidMaterialID;
|
||||
//char* Texture[6];
|
||||
//uint32 Color[2];
|
||||
//float Unk1[18];
|
||||
//uint32 Unk2[4];
|
||||
};
|
||||
*/
|
||||
|
||||
#define MAX_LOCK_CASE 8
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxx
|
||||
const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp";
|
||||
const std::string CustomAchievementIndex = "ID";
|
||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx";
|
||||
const char AreaGroupEntryfmt[]="niiiiiii";
|
||||
const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
|
||||
const char AreaTriggerEntryfmt[]="niffffffff";
|
||||
@@ -78,7 +78,7 @@ const char ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx";
|
||||
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx";
|
||||
const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx";
|
||||
//const char LiquidTypeEntryfmt[]="nsiiiiffffifiiisssssiiffffffffffffffffffiiii";
|
||||
const char LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
|
||||
|
||||
@@ -724,6 +724,7 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep
|
||||
for (uint8 i=0; i<MAX_TIMERS; i++)
|
||||
m_MirrorTimer[i] = DISABLED_MIRROR_TIMER;
|
||||
|
||||
_lastLiquid = NULL;
|
||||
m_MirrorTimerFlags = UNDERWATER_NONE;
|
||||
m_MirrorTimerFlagsLast = UNDERWATER_NONE;
|
||||
m_isInWater = false;
|
||||
@@ -1416,7 +1417,7 @@ void Player::HandleDrowning(uint32 time_diff)
|
||||
SendMirrorTimer(FATIGUE_TIMER, DarkWaterTime, m_MirrorTimer[FATIGUE_TIMER], 10);
|
||||
}
|
||||
|
||||
if (m_MirrorTimerFlags & (UNDERWATER_INLAVA|UNDERWATER_INSLIME))
|
||||
if (m_MirrorTimerFlags & (UNDERWATER_INLAVA /*| UNDERWATER_INSLIME*/) && !(_lastLiquid && _lastLiquid->SpellId))
|
||||
{
|
||||
// Breath timer not activated - activate it
|
||||
if (m_MirrorTimer[FIRE_TIMER] == DISABLED_MIRROR_TIMER)
|
||||
@@ -1434,8 +1435,8 @@ void Player::HandleDrowning(uint32 time_diff)
|
||||
EnvironmentalDamage(DAMAGE_LAVA, damage);
|
||||
// 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);
|
||||
//else if (m_zoneUpdateId != 1497)
|
||||
// EnvironmentalDamage(DAMAGE_SLIME, damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23060,14 +23061,33 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
|
||||
if (!res)
|
||||
{
|
||||
m_MirrorTimerFlags &= ~(UNDERWATER_INWATER | UNDERWATER_INLAVA | UNDERWATER_INSLIME | UNDERWARER_INDARKWATER);
|
||||
// Small hack for enable breath in WMO
|
||||
/* if (IsInWater())
|
||||
m_MirrorTimerFlags|=UNDERWATER_INWATER; */
|
||||
if (_lastLiquid && _lastLiquid->SpellId)
|
||||
RemoveAurasDueToSpell(_lastLiquid->SpellId);
|
||||
|
||||
_lastLiquid = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uint32 liqEntry = liquid_status.entry)
|
||||
{
|
||||
LiquidTypeEntry const* liquid = sLiquidTypeStore.LookupEntry(liqEntry);
|
||||
if (_lastLiquid && _lastLiquid->SpellId && _lastLiquid->Id != liqEntry)
|
||||
RemoveAurasDueToSpell(_lastLiquid->SpellId);
|
||||
|
||||
if (liquid && liquid->SpellId)
|
||||
AddAura(liquid->SpellId, this);
|
||||
|
||||
_lastLiquid = liquid;
|
||||
}
|
||||
else if (_lastLiquid && _lastLiquid->SpellId)
|
||||
{
|
||||
RemoveAurasDueToSpell(_lastLiquid->SpellId);
|
||||
_lastLiquid = NULL;
|
||||
}
|
||||
|
||||
|
||||
// All liquids type - check under water position
|
||||
if (liquid_status.type&(MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN|MAP_LIQUID_TYPE_MAGMA|MAP_LIQUID_TYPE_SLIME))
|
||||
if (liquid_status.type_flags & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME))
|
||||
{
|
||||
if (res & LIQUID_MAP_UNDER_WATER)
|
||||
m_MirrorTimerFlags |= UNDERWATER_INWATER;
|
||||
@@ -23076,13 +23096,13 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
|
||||
}
|
||||
|
||||
// Allow travel in dark water on taxi or transport
|
||||
if ((liquid_status.type & MAP_LIQUID_TYPE_DARK_WATER) && !isInFlight() && !GetTransport())
|
||||
if ((liquid_status.type_flags & MAP_LIQUID_TYPE_DARK_WATER) && !isInFlight() && !GetTransport())
|
||||
m_MirrorTimerFlags |= UNDERWARER_INDARKWATER;
|
||||
else
|
||||
m_MirrorTimerFlags &= ~UNDERWARER_INDARKWATER;
|
||||
|
||||
// in lava check, anywhere in lava level
|
||||
if (liquid_status.type&MAP_LIQUID_TYPE_MAGMA)
|
||||
if (liquid_status.type_flags & MAP_LIQUID_TYPE_MAGMA)
|
||||
{
|
||||
if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK))
|
||||
m_MirrorTimerFlags |= UNDERWATER_INLAVA;
|
||||
@@ -23090,7 +23110,7 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
|
||||
m_MirrorTimerFlags &= ~UNDERWATER_INLAVA;
|
||||
}
|
||||
// in slime check, anywhere in slime level
|
||||
if (liquid_status.type&MAP_LIQUID_TYPE_SLIME)
|
||||
if (liquid_status.type_flags & MAP_LIQUID_TYPE_SLIME)
|
||||
{
|
||||
if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK))
|
||||
m_MirrorTimerFlags |= UNDERWATER_INSLIME;
|
||||
|
||||
@@ -2813,6 +2813,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
uint32 m_lastFallTime;
|
||||
float m_lastFallZ;
|
||||
|
||||
LiquidTypeEntry const* _lastLiquid;
|
||||
int32 m_MirrorTimer[MAX_TIMERS];
|
||||
uint8 m_MirrorTimerFlags;
|
||||
uint8 m_MirrorTimerFlagsLast;
|
||||
|
||||
@@ -41,7 +41,7 @@ union u_map_magic
|
||||
};
|
||||
|
||||
u_map_magic MapMagic = { {'M','A','P','S'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','1'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','2'} };
|
||||
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
|
||||
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
|
||||
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
|
||||
@@ -1044,7 +1044,8 @@ GridMap::GridMap()
|
||||
_liquidWidth = 0;
|
||||
_liquidHeight = 0;
|
||||
_liquidLevel = INVALID_HEIGHT;
|
||||
_liquidData = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
}
|
||||
|
||||
@@ -1106,12 +1107,14 @@ void GridMap::unloadData()
|
||||
delete[] _areaMap;
|
||||
delete[] m_V9;
|
||||
delete[] m_V8;
|
||||
delete[] _liquidData;
|
||||
delete[] _liquidEntry;
|
||||
delete[] _liquidFlags;
|
||||
delete[] _liquidMap;
|
||||
_areaMap = NULL;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
_liquidData = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
}
|
||||
@@ -1197,8 +1200,12 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
|
||||
|
||||
if (!(header.flags & MAP_LIQUID_NO_TYPE))
|
||||
{
|
||||
_liquidData = new uint8 [16*16];
|
||||
if (fread(_liquidData, sizeof(uint8), 16*16, in) != 16*16)
|
||||
_liquidEntry = new uint16[16*16];
|
||||
if (fread(_liquidEntry, sizeof(uint16), 16*16, in) != 16*16)
|
||||
return false;
|
||||
|
||||
_liquidFlags = new uint8[16*16];
|
||||
if (fread(_liquidFlags, sizeof(uint8), 16*16, in) != 16*16)
|
||||
return false;
|
||||
}
|
||||
if (!(header.flags & MAP_LIQUID_NO_HEIGHT))
|
||||
@@ -1462,23 +1469,24 @@ float GridMap::getLiquidLevel(float x, float y)
|
||||
return _liquidMap[cx_int*_liquidWidth + cy_int];
|
||||
}
|
||||
|
||||
// Why does this return LIQUID data?
|
||||
uint8 GridMap::getTerrainType(float x, float y)
|
||||
{
|
||||
if (!_liquidData)
|
||||
if (!_liquidFlags)
|
||||
return 0;
|
||||
|
||||
x = 16 * (32 - x/SIZE_OF_GRIDS);
|
||||
y = 16 * (32 - y/SIZE_OF_GRIDS);
|
||||
int lx = (int)x & 15;
|
||||
int ly = (int)y & 15;
|
||||
return _liquidData[lx*16 + ly];
|
||||
return _liquidFlags[lx*16 + ly];
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
|
||||
{
|
||||
// Check water type (if no water return)
|
||||
if (!_liquidType && !_liquidData)
|
||||
if (!_liquidType && !_liquidFlags)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Get cell
|
||||
@@ -1489,7 +1497,37 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
|
||||
int y_int = (int)cy & (MAP_RESOLUTION-1);
|
||||
|
||||
// Check water type in cell
|
||||
uint8 type = _liquidData ? _liquidData[(x_int>>3)*16 + (y_int>>3)] : _liquidType;
|
||||
int idx=(x_int>>3)*16 + (y_int>>3);
|
||||
uint8 type = _liquidFlags ? _liquidFlags[idx] : _liquidType;
|
||||
uint32 entry = 0;
|
||||
if (_liquidEntry)
|
||||
{
|
||||
if (LiquidTypeEntry const* liquidEntry = sLiquidTypeStore.LookupEntry(_liquidEntry[idx]))
|
||||
{
|
||||
entry = liquidEntry->Id;
|
||||
type &= MAP_LIQUID_TYPE_DARK_WATER;
|
||||
uint32 liqTypeIdx = liquidEntry->Type;
|
||||
if (entry < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(getArea(x, y), MAPID_INVALID))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
if (!overrideLiquid && area->zone)
|
||||
if (area = GetAreaEntryByAreaID(area->zone))
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
entry = overrideLiquid;
|
||||
liqTypeIdx = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type |= 1 << liqTypeIdx;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
@@ -1518,20 +1556,20 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
|
||||
// All ok in water -> store data
|
||||
if (data)
|
||||
{
|
||||
data->type = type;
|
||||
data->entry = entry;
|
||||
data->type_flags = type;
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
}
|
||||
|
||||
// For speed check as int values
|
||||
int delta = int((liquid_level - z) * 10);
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 20) // Under water
|
||||
if (delta > 2.0f) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0) // In water
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -1) // Walk on water
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
// Above water
|
||||
return LIQUID_MAP_ABOVE_WATER;
|
||||
@@ -1722,8 +1760,9 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
{
|
||||
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
|
||||
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
float liquid_level, ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type;
|
||||
float liquid_level = INVALID_HEIGHT;
|
||||
float ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type = 0;
|
||||
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_MAPS, "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
|
||||
@@ -1733,20 +1772,46 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
// All ok in water -> store data
|
||||
if (data)
|
||||
{
|
||||
data->type = liquid_type;
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
// hardcoded in client like this
|
||||
if (GetId() == 530 && liquid_type == 2)
|
||||
liquid_type = 15;
|
||||
|
||||
uint32 liquidFlagType = 0;
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
|
||||
liquidFlagType = liq->Type;
|
||||
|
||||
if (liquid_type && liquid_type < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetId()))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
if (!overrideLiquid && area->zone)
|
||||
if (area = GetAreaEntryByAreaID(area->zone))
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
liquid_type = overrideLiquid;
|
||||
liquidFlagType = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For speed check as int values
|
||||
int delta = int((liquid_level - z) * 10);
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
|
||||
data->entry = liquid_type;
|
||||
data->type_flags = 1 << liquidFlagType;
|
||||
}
|
||||
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 20) // Under water
|
||||
if (delta > 2.0f) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0 ) // In water
|
||||
if (delta > 0.0f) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -1) // Walk on water
|
||||
if (delta > -0.1f) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
result = LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
@@ -1760,7 +1825,13 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
||||
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
// hardcoded in client like this
|
||||
if (GetId() == 530 && map_data.entry == 2)
|
||||
map_data.entry = 15;
|
||||
|
||||
*data = map_data;
|
||||
}
|
||||
return map_result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ enum ZLiquidStatus
|
||||
|
||||
struct LiquidData
|
||||
{
|
||||
uint32 type;
|
||||
uint32 type_flags;
|
||||
uint32 entry;
|
||||
float level;
|
||||
float depth_level;
|
||||
};
|
||||
@@ -163,7 +164,8 @@ class GridMap
|
||||
|
||||
// Liquid data
|
||||
float _liquidLevel;
|
||||
uint8* _liquidData;
|
||||
uint16* _liquidEntry;
|
||||
uint8* _liquidFlags;
|
||||
float* _liquidMap;
|
||||
uint16 _gridArea;
|
||||
uint16 _liquidType;
|
||||
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
|
||||
|
||||
if (status)
|
||||
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.type, status);
|
||||
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ void ReadLiquidTypeTableDBC()
|
||||
|
||||
// Map file format data
|
||||
static char const* MAP_MAGIC = "MAPS";
|
||||
static char const* MAP_VERSION_MAGIC = "v1.1";
|
||||
static char const* MAP_VERSION_MAGIC = "v1.2";
|
||||
static char const* MAP_AREA_MAGIC = "AREA";
|
||||
static char const* MAP_HEIGHT_MAGIC = "MHGT";
|
||||
static char const* MAP_LIQUID_MAGIC = "MLIQ";
|
||||
@@ -359,7 +359,8 @@ uint16 uint16_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
uint8 uint8_V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
uint8 uint8_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
|
||||
uint8 liquid_type[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
|
||||
@@ -378,7 +379,8 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
}
|
||||
|
||||
memset(liquid_show, 0, sizeof(liquid_show));
|
||||
memset(liquid_type, 0, sizeof(liquid_type));
|
||||
memset(liquid_flags, 0, sizeof(liquid_flags));
|
||||
memset(liquid_entry, 0, sizeof(liquid_entry));
|
||||
|
||||
// Prepare map header
|
||||
map_fileheader map;
|
||||
@@ -612,6 +614,68 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
map.heightMapSize+= sizeof(V9) + sizeof(V8);
|
||||
}
|
||||
|
||||
// Get from MCLQ chunk (old)
|
||||
for (int i = 0; i < ADT_CELLS_PER_GRID; i++)
|
||||
{
|
||||
for(int j = 0; j < ADT_CELLS_PER_GRID; j++)
|
||||
{
|
||||
adt_MCNK *cell = cells->getMCNK(i, j);
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
adt_MCLQ *liquid = cell->getMCLQ();
|
||||
int count = 0;
|
||||
if (!liquid || cell->sizeMCLQ <= 8)
|
||||
continue;
|
||||
|
||||
for (int y = 0; y < ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i * ADT_CELL_SIZE + y;
|
||||
for (int x = 0; x < ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j * ADT_CELL_SIZE + x;
|
||||
if (liquid->flags[y][x] != 0x0F)
|
||||
{
|
||||
liquid_show[cy][cx] = true;
|
||||
if (liquid->flags[y][x] & (1<<7))
|
||||
liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 c_flag = cell->flags;
|
||||
if (c_flag & (1<<2))
|
||||
{
|
||||
liquid_entry[i][j] = 1;
|
||||
liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; // water
|
||||
}
|
||||
if (c_flag & (1<<3))
|
||||
{
|
||||
liquid_entry[i][j] = 2;
|
||||
liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; // ocean
|
||||
}
|
||||
if (c_flag & (1<<4))
|
||||
{
|
||||
liquid_entry[i][j] = 3;
|
||||
liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; // magma/slime
|
||||
}
|
||||
|
||||
if (!count && liquid_flags[i][j])
|
||||
fprintf(stderr, "Wrong liquid detect in MCLQ chunk");
|
||||
|
||||
for (int y = 0; y <= ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i * ADT_CELL_SIZE + y;
|
||||
for (int x = 0; x <= ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j * ADT_CELL_SIZE + x;
|
||||
liquid_height[cy][cx] = liquid->liquid[y][x].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get liquid map for grid (in WOTLK used MH2O chunk)
|
||||
adt_MH2O * h2o = adt.a_grid->getMH2O();
|
||||
if (h2o)
|
||||
@@ -641,26 +705,26 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
}
|
||||
}
|
||||
|
||||
uint32 type = LiqType[h->liquidType];
|
||||
switch (type)
|
||||
liquid_entry[i][j] = h->liquidType;
|
||||
switch (LiqType[h->liquidType])
|
||||
{
|
||||
case LIQUID_TYPE_WATER: liquid_type[i][j] |= MAP_LIQUID_TYPE_WATER; break;
|
||||
case LIQUID_TYPE_OCEAN: liquid_type[i][j] |= MAP_LIQUID_TYPE_OCEAN; break;
|
||||
case LIQUID_TYPE_MAGMA: liquid_type[i][j] |= MAP_LIQUID_TYPE_MAGMA; break;
|
||||
case LIQUID_TYPE_SLIME: liquid_type[i][j] |= MAP_LIQUID_TYPE_SLIME; break;
|
||||
case LIQUID_TYPE_WATER: liquid_flags[i][j] |= MAP_LIQUID_TYPE_WATER; break;
|
||||
case LIQUID_TYPE_OCEAN: liquid_flags[i][j] |= MAP_LIQUID_TYPE_OCEAN; break;
|
||||
case LIQUID_TYPE_MAGMA: liquid_flags[i][j] |= MAP_LIQUID_TYPE_MAGMA; break;
|
||||
case LIQUID_TYPE_SLIME: liquid_flags[i][j] |= MAP_LIQUID_TYPE_SLIME; break;
|
||||
default:
|
||||
printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j);
|
||||
break;
|
||||
}
|
||||
// Dark water detect
|
||||
if (type == LIQUID_TYPE_OCEAN)
|
||||
if (LiqType[h->liquidType] == LIQUID_TYPE_OCEAN)
|
||||
{
|
||||
uint8 *lm = h2o->getLiquidLightMap(h);
|
||||
if (!lm)
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
|
||||
liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER;
|
||||
}
|
||||
|
||||
if (!count && liquid_type[i][j])
|
||||
if (!count && liquid_flags[i][j])
|
||||
printf("Wrong liquid detect in MH2O chunk");
|
||||
|
||||
float *height = h2o->getLiquidHeightMap(h);
|
||||
@@ -681,72 +745,16 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get from MCLQ chunk (old)
|
||||
for (int i=0;i<ADT_CELLS_PER_GRID;i++)
|
||||
{
|
||||
for(int j=0;j<ADT_CELLS_PER_GRID;j++)
|
||||
{
|
||||
adt_MCNK *cell = cells->getMCNK(i, j);
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
adt_MCLQ *liquid = cell->getMCLQ();
|
||||
int count = 0;
|
||||
if (!liquid || cell->sizeMCLQ <= 8)
|
||||
continue;
|
||||
|
||||
for (int y=0; y < ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x < ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
if (liquid->flags[y][x] != 0x0F)
|
||||
{
|
||||
liquid_show[cy][cx] = true;
|
||||
if (liquid->flags[y][x]&(1<<7))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 c_flag = cell->flags;
|
||||
if(c_flag & (1<<2))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_WATER; // water
|
||||
if(c_flag & (1<<3))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_OCEAN; // ochean
|
||||
if(c_flag & (1<<4))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_MAGMA; // magma/slime
|
||||
|
||||
if (!count && liquid_type[i][j])
|
||||
printf("Wrong liquid detect in MCLQ chunk");
|
||||
|
||||
for (int y=0; y <= ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x<= ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
liquid_height[cy][cx] = liquid->liquid[y][x].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
// Pack liquid data
|
||||
//============================================
|
||||
uint8 type = liquid_type[0][0];
|
||||
uint8 type = liquid_flags[0][0];
|
||||
bool fullType = false;
|
||||
for (int y=0;y<ADT_CELLS_PER_GRID;y++)
|
||||
{
|
||||
for(int x=0;x<ADT_CELLS_PER_GRID;x++)
|
||||
{
|
||||
if (liquid_type[y][x]!=type)
|
||||
if (liquid_flags[y][x]!=type)
|
||||
{
|
||||
fullType = true;
|
||||
y = ADT_CELLS_PER_GRID;
|
||||
@@ -795,8 +803,8 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
liquidHeader.liquidType = 0;
|
||||
liquidHeader.offsetX = minX;
|
||||
liquidHeader.offsetY = minY;
|
||||
liquidHeader.width = maxX - minX + 1;
|
||||
liquidHeader.height = maxY - minY + 1;
|
||||
liquidHeader.width = maxX - minX + 1 + 1;
|
||||
liquidHeader.height = maxY - minY + 1 + 1;
|
||||
liquidHeader.liquidLevel = minHeight;
|
||||
|
||||
if (maxHeight == minHeight)
|
||||
@@ -812,7 +820,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
if (liquidHeader.flags & MAP_LIQUID_NO_TYPE)
|
||||
liquidHeader.liquidType = type;
|
||||
else
|
||||
map.liquidMapSize+=sizeof(liquid_type);
|
||||
map.liquidMapSize += sizeof(liquid_entry) + sizeof(liquid_flags);
|
||||
|
||||
if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
|
||||
map.liquidMapSize += sizeof(float)*liquidHeader.width*liquidHeader.height;
|
||||
@@ -857,7 +865,10 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
|
||||
{
|
||||
fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
|
||||
if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE))
|
||||
fwrite(liquid_type, sizeof(liquid_type), 1, output);
|
||||
{
|
||||
fwrite(liquid_entry, sizeof(liquid_entry), 1, output);
|
||||
fwrite(liquid_flags, sizeof(liquid_flags), 1, output);
|
||||
}
|
||||
if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT))
|
||||
{
|
||||
for (int y=0; y<liquidHeader.height;y++)
|
||||
|
||||
@@ -76,7 +76,7 @@ bool preciseVectorData = false;
|
||||
|
||||
//static const char * szWorkDirMaps = ".\\Maps";
|
||||
const char* szWorkDirWmo = "./Buildings";
|
||||
const char* szRawVMAPMagic = "VMAP004";
|
||||
const char* szRawVMAPMagic = "VMAP041";
|
||||
|
||||
// Local testing functions
|
||||
|
||||
|
||||
@@ -404,11 +404,53 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPrecis
|
||||
if (rootWMO->liquidType & 4)
|
||||
liquidEntry = liquidType;
|
||||
else if (liquidType == 15)
|
||||
liquidEntry = 1; // first entry, generic "Water"
|
||||
liquidEntry = 0;
|
||||
else
|
||||
liquidEntry = liquidType + 1;
|
||||
// overwrite material type in header...
|
||||
hlq->type = LiqType[liquidEntry];
|
||||
|
||||
if (!liquidEntry)
|
||||
{
|
||||
int v1; // edx@1
|
||||
int v2; // eax@1
|
||||
|
||||
v1 = hlq->xtiles * hlq->ytiles;
|
||||
v2 = 0;
|
||||
if (v1 > 0)
|
||||
{
|
||||
while ((LiquBytes[v2] & 0xF) == 15)
|
||||
{
|
||||
++v2;
|
||||
if (v2 >= v1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15)
|
||||
liquidEntry = (LiquBytes[v2] & 0xF) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (liquidEntry && liquidEntry < 21)
|
||||
{
|
||||
switch (((uint8)liquidEntry - 1) & 3)
|
||||
{
|
||||
case 0:
|
||||
liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
|
||||
break;
|
||||
case 1:
|
||||
liquidEntry = 14;
|
||||
break;
|
||||
case 2:
|
||||
liquidEntry = 19;
|
||||
break;
|
||||
case 3:
|
||||
liquidEntry = 20;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hlq->type = liquidEntry;
|
||||
|
||||
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
|
||||
llog << filename;
|
||||
|
||||
Reference in New Issue
Block a user