diff options
author | Shauren <shauren.trinity@gmail.com> | 2012-03-07 13:09:35 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2012-03-07 13:09:35 +0100 |
commit | e5d23103f37c40d2e946fa0e2db66d2f527ad9af (patch) | |
tree | 4970c3f8fcb3e39bd433084113e7653739e3f5b9 | |
parent | 9f93681625f16b4a118df755eccb8ac80f713c16 (diff) |
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
-rw-r--r-- | sql/updates/world/2012_03_07_00_world_trinity_string.sql | 3 | ||||
-rw-r--r-- | src/server/collision/Management/VMapManager2.cpp | 2 | ||||
-rw-r--r-- | src/server/collision/Maps/TileAssembler.cpp | 2 | ||||
-rw-r--r-- | src/server/collision/Models/WorldModel.cpp | 3 | ||||
-rw-r--r-- | src/server/collision/VMapDefinitions.h | 6 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.cpp | 3 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.h | 2 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStructure.h | 42 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 4 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 48 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 1 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.cpp | 123 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.h | 6 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_gps.cpp | 2 | ||||
-rw-r--r-- | src/tools/map_extractor/System.cpp | 173 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vmapexport.cpp | 2 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/wmo.cpp | 48 |
17 files changed, 310 insertions, 160 deletions
diff --git a/sql/updates/world/2012_03_07_00_world_trinity_string.sql b/sql/updates/world/2012_03_07_00_world_trinity_string.sql new file mode 100644 index 00000000000..96344520236 --- /dev/null +++ b/sql/updates/world/2012_03_07_00_world_trinity_string.sql @@ -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.');
\ No newline at end of file diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 62abc31831a..6139a27fb52 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -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)) diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp index 68ea3ec80cd..e7693a70de4 100644 --- a/src/server/collision/Maps/TileAssembler.cpp +++ b/src/server/collision/Maps/TileAssembler.cpp @@ -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; diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp index d4b08dde5dd..b818232fb32 100644 --- a/src/server/collision/Models/WorldModel.cpp +++ b/src/server/collision/Models/WorldModel.cpp @@ -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; } diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index 72a62807b4c..cc796d96dd5 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -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); diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index b6c18103f1e..4fa8e09cead 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -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"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 58c85adc11b..0bbf06c5311 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -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; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 0d721e3f832..1e52866539a 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -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 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 54be02a619e..ce887cac09b 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -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"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 870b6f683b8..729a2fe0b00 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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,14 +1417,14 @@ 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) m_MirrorTimer[FIRE_TIMER] = getMaxTimer(FIRE_TIMER); else { - m_MirrorTimer[FIRE_TIMER]-=time_diff; + m_MirrorTimer[FIRE_TIMER] -= time_diff; if (m_MirrorTimer[FIRE_TIMER] < 0) { m_MirrorTimer[FIRE_TIMER]+= 1*IN_MILLISECONDS; @@ -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); } } } @@ -23059,15 +23060,34 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z) ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); 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; */ + m_MirrorTimerFlags &= ~(UNDERWATER_INWATER | UNDERWATER_INLAVA | UNDERWATER_INSLIME | UNDERWARER_INDARKWATER); + 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,23 +23096,23 @@ 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)) + if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK)) m_MirrorTimerFlags |= UNDERWATER_INLAVA; else 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)) + if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK)) m_MirrorTimerFlags |= UNDERWATER_INSLIME; else m_MirrorTimerFlags &= ~UNDERWATER_INSLIME; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 3d510148aa4..362fd8a9016 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -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; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 00b52bf746b..7f27a474534 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -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; } @@ -1192,18 +1195,22 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/) _liquidOffX = header.offsetX; _liquidOffY = header.offsetY; _liquidWidth = header.width; - _liquidHeight= header.height; + _liquidHeight = header.height; _liquidLevel = header.liquidLevel; 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)) { - _liquidMap = new float [_liquidWidth*_liquidHeight]; + _liquidMap = new float[_liquidWidth*_liquidHeight]; if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != _liquidWidth*_liquidHeight) return false; } @@ -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; + // 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; + } + } + } + data->level = liquid_level; data->depth_level = ground_level; + + data->entry = liquid_type; + data->type_flags = 1 << liquidFlagType; } - // 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; 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; } } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index d8db4c947a3..d0f99610262 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -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; diff --git a/src/server/scripts/Commands/cs_gps.cpp b/src/server/scripts/Commands/cs_gps.cpp index 589ed4af3b8..59e2ec90905 100644 --- a/src/server/scripts/Commands/cs_gps.cpp +++ b/src/server/scripts/Commands/cs_gps.cpp @@ -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; } diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 335fd924be8..bbde9f4675e 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -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,13 +614,75 @@ 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) { - for (int i=0;i<ADT_CELLS_PER_GRID;i++) + for (int i = 0; i < ADT_CELLS_PER_GRID; i++) { - for(int j=0;j<ADT_CELLS_PER_GRID;j++) + for(int j = 0; j < ADT_CELLS_PER_GRID; j++) { adt_liquid_header *h = h2o->getLiquidData(i,j); if (!h) @@ -626,41 +690,41 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 int count = 0; uint64 show = h2o->getLiquidShowMap(h); - for (int y=0; y < h->height;y++) + for (int y = 0; y < h->height; y++) { - int cy = i*ADT_CELL_SIZE + y + h->yOffset; - for (int x=0; x < h->width; x++) + int cy = i * ADT_CELL_SIZE + y + h->yOffset; + for (int x = 0; x < h->width; x++) { - int cx = j*ADT_CELL_SIZE + x + h->xOffset; + int cx = j * ADT_CELL_SIZE + x + h->xOffset; if (show & 1) { liquid_show[cy][cx] = true; ++count; } - show>>=1; + show >>= 1; } } - 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++) diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 599290a9254..68de8d653ba 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -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 diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 58957e007c1..6703872111b 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -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; |