From 28c3de50932278fec75cf6b1fb7c0fbe13dd601a Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Fri, 28 May 2010 13:33:04 +0200 Subject: [PATCH] [9995] Move GridMap class (and related structs/enums) to separate cpp/h. Also rename some structs/enums and fix some code style. --- src/game/GridMap.cpp | 616 +++++++++++++++++++++++++++++++++ src/game/GridMap.h | 183 ++++++++++ src/game/Level1.cpp | 8 +- src/game/Makefile.am | 2 + src/game/Map.cpp | 567 +----------------------------- src/game/Map.h | 150 +------- src/game/MapManager.cpp | 2 +- src/game/Player.cpp | 4 +- src/shared/revision_nr.h | 2 +- win/VC100/game.vcxproj | 2 + win/VC100/game.vcxproj.filters | 6 + win/VC80/game.vcproj | 8 + win/VC90/game.vcproj | 8 + 13 files changed, 838 insertions(+), 720 deletions(-) create mode 100644 src/game/GridMap.cpp create mode 100644 src/game/GridMap.h diff --git a/src/game/GridMap.cpp b/src/game/GridMap.cpp new file mode 100644 index 000000000..17e5c26a4 --- /dev/null +++ b/src/game/GridMap.cpp @@ -0,0 +1,616 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "MapManager.h" +#include "Log.h" +#include "GridStates.h" +#include "CellImpl.h" +#include "Map.h" +#include "Config/ConfigEnv.h" +#include "DBCEnums.h" +#include "GridMap.h" +#include "VMapFactory.h" +#include "World.h" + +char const* MAP_MAGIC = "MAPS"; +char const* MAP_VERSION_MAGIC = "v1.1"; +char const* MAP_AREA_MAGIC = "AREA"; +char const* MAP_HEIGHT_MAGIC = "MHGT"; +char const* MAP_LIQUID_MAGIC = "MLIQ"; + +GridMap::GridMap() +{ + m_flags = 0; + + // Area data + m_gridArea = 0; + m_area_map = NULL; + + // Height level data + m_gridHeight = INVALID_HEIGHT; + m_gridGetHeight = &GridMap::getHeightFromFlat; + m_V9 = NULL; + m_V8 = NULL; + + // Liquid data + m_liquidType = 0; + m_liquid_offX = 0; + m_liquid_offY = 0; + m_liquid_width = 0; + m_liquid_height = 0; + m_liquidLevel = INVALID_HEIGHT; + m_liquid_type = NULL; + m_liquid_map = NULL; +} + +GridMap::~GridMap() +{ + unloadData(); +} + +bool GridMap::loadData(char *filename) +{ + // Unload old data if exist + unloadData(); + + GridMapFileHeader header; + // Not return error if file not found + FILE *in = fopen(filename, "rb"); + if (!in) + return true; + + fread(&header, sizeof(header),1,in); + if (header.mapMagic == *((uint32 const*)(MAP_MAGIC)) && + header.versionMagic == *((uint32 const*)(MAP_VERSION_MAGIC)) || + !IsAcceptableClientBuild(header.buildMagic)) + { + // loadup area data + if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize)) + { + sLog.outError("Error loading map area data\n"); + fclose(in); + return false; + } + + // loadup height data + if (header.heightMapOffset && !loadHeightData(in, header.heightMapOffset, header.heightMapSize)) + { + sLog.outError("Error loading map height data\n"); + fclose(in); + return false; + } + + // loadup liquid data + if (header.liquidMapOffset && !loadGridMapLiquidData(in, header.liquidMapOffset, header.liquidMapSize)) + { + sLog.outError("Error loading map liquids data\n"); + fclose(in); + return false; + } + + fclose(in); + return true; + } + + sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.", filename); + fclose(in); + return false; +} + +void GridMap::unloadData() +{ + if (m_area_map) + delete[] m_area_map; + + if (m_V9) + delete[] m_V9; + + if (m_V8) + delete[] m_V8; + + if (m_liquid_type) + delete[] m_liquid_type; + + if (m_liquid_map) + delete[] m_liquid_map; + + m_area_map = NULL; + m_V9 = NULL; + m_V8 = NULL; + m_liquid_type = NULL; + m_liquid_map = NULL; + m_gridGetHeight = &GridMap::getHeightFromFlat; +} + +bool GridMap::loadAreaData(FILE *in, uint32 offset, uint32 /*size*/) +{ + GridMapAreaHeader header; + fseek(in, offset, SEEK_SET); + fread(&header, sizeof(header), 1, in); + if (header.fourcc != *((uint32 const*)(MAP_AREA_MAGIC))) + return false; + + m_gridArea = header.gridArea; + if (!(header.flags & MAP_AREA_NO_AREA)) + { + m_area_map = new uint16 [16*16]; + fread(m_area_map, sizeof(uint16), 16*16, in); + } + + return true; +} + +bool GridMap::loadHeightData(FILE *in, uint32 offset, uint32 /*size*/) +{ + GridMapHeightHeader header; + fseek(in, offset, SEEK_SET); + fread(&header, sizeof(header), 1, in); + if (header.fourcc != *((uint32 const*)(MAP_HEIGHT_MAGIC))) + return false; + + m_gridHeight = header.gridHeight; + if (!(header.flags & MAP_HEIGHT_NO_HEIGHT)) + { + if ((header.flags & MAP_HEIGHT_AS_INT16)) + { + m_uint16_V9 = new uint16 [129*129]; + m_uint16_V8 = new uint16 [128*128]; + fread(m_uint16_V9, sizeof(uint16), 129*129, in); + fread(m_uint16_V8, sizeof(uint16), 128*128, in); + m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 65535; + m_gridGetHeight = &GridMap::getHeightFromUint16; + } + else if ((header.flags & MAP_HEIGHT_AS_INT8)) + { + m_uint8_V9 = new uint8 [129*129]; + m_uint8_V8 = new uint8 [128*128]; + fread(m_uint8_V9, sizeof(uint8), 129*129, in); + fread(m_uint8_V8, sizeof(uint8), 128*128, in); + m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 255; + m_gridGetHeight = &GridMap::getHeightFromUint8; + } + else + { + m_V9 = new float [129*129]; + m_V8 = new float [128*128]; + fread(m_V9, sizeof(float), 129*129, in); + fread(m_V8, sizeof(float), 128*128, in); + m_gridGetHeight = &GridMap::getHeightFromFloat; + } + } + else + m_gridGetHeight = &GridMap::getHeightFromFlat; + + return true; +} + +bool GridMap::loadGridMapLiquidData(FILE *in, uint32 offset, uint32 /*size*/) +{ + GridMapLiquidHeader header; + fseek(in, offset, SEEK_SET); + fread(&header, sizeof(header), 1, in); + if (header.fourcc != *((uint32 const*)(MAP_LIQUID_MAGIC))) + return false; + + m_liquidType = header.liquidType; + m_liquid_offX = header.offsetX; + m_liquid_offY = header.offsetY; + m_liquid_width = header.width; + m_liquid_height = header.height; + m_liquidLevel = header.liquidLevel; + + if (!(header.flags & MAP_LIQUID_NO_TYPE)) + { + m_liquid_type = new uint8 [16*16]; + fread(m_liquid_type, sizeof(uint8), 16*16, in); + } + + if (!(header.flags & MAP_LIQUID_NO_HEIGHT)) + { + m_liquid_map = new float [m_liquid_width*m_liquid_height]; + fread(m_liquid_map, sizeof(float), m_liquid_width*m_liquid_height, in); + } + + return true; +} + +uint16 GridMap::getArea(float x, float y) +{ + if (!m_area_map) + return m_gridArea; + + 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 m_area_map[lx*16 + ly]; +} + +float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const +{ + return m_gridHeight; +} + +float GridMap::getHeightFromFloat(float x, float y) const +{ + if (!m_V8 || !m_V9) + return m_gridHeight; + + x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); + y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); + + int x_int = (int)x; + int y_int = (int)y; + x -= x_int; + y -= y_int; + x_int &= (MAP_RESOLUTION - 1); + y_int &= (MAP_RESOLUTION - 1); + + // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid + // +--------------> X + // | h1-------h2 Coordinates is: + // | | \ 1 / | h1 0,0 + // | | \ / | h2 0,1 + // | | 2 h5 3 | h3 1,0 + // | | / \ | h4 1,1 + // | | / 4 \ | h5 1/2,1/2 + // | h3-------h4 + // V Y + // For find height need + // 1 - detect triangle + // 2 - solve linear equation from triangle points + // Calculate coefficients for solve h = a*x + b*y + c + + float a,b,c; + // Select triangle: + if (x+y < 1) + { + if (x > y) + { + // 1 triangle (h1, h2, h5 points) + float h1 = m_V9[(x_int )*129 + y_int]; + float h2 = m_V9[(x_int+1)*129 + y_int]; + float h5 = 2 * m_V8[x_int*128 + y_int]; + a = h2-h1; + b = h5-h1-h2; + c = h1; + } + else + { + // 2 triangle (h1, h3, h5 points) + float h1 = m_V9[x_int*129 + y_int ]; + float h3 = m_V9[x_int*129 + y_int+1]; + float h5 = 2 * m_V8[x_int*128 + y_int]; + a = h5 - h1 - h3; + b = h3 - h1; + c = h1; + } + } + else + { + if (x > y) + { + // 3 triangle (h2, h4, h5 points) + float h2 = m_V9[(x_int+1)*129 + y_int ]; + float h4 = m_V9[(x_int+1)*129 + y_int+1]; + float h5 = 2 * m_V8[x_int*128 + y_int]; + a = h2 + h4 - h5; + b = h4 - h2; + c = h5 - h4; + } + else + { + // 4 triangle (h3, h4, h5 points) + float h3 = m_V9[(x_int )*129 + y_int+1]; + float h4 = m_V9[(x_int+1)*129 + y_int+1]; + float h5 = 2 * m_V8[x_int*128 + y_int]; + a = h4 - h3; + b = h3 + h4 - h5; + c = h5 - h4; + } + } + // Calculate height + return a * x + b * y + c; +} + +float GridMap::getHeightFromUint8(float x, float y) const +{ + if (!m_uint8_V8 || !m_uint8_V9) + return m_gridHeight; + + x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); + y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); + + int x_int = (int)x; + int y_int = (int)y; + x -= x_int; + y -= y_int; + x_int &= (MAP_RESOLUTION - 1); + y_int &= (MAP_RESOLUTION - 1); + + int32 a, b, c; + uint8 *V9_h1_ptr = &m_uint8_V9[x_int*128 + x_int + y_int]; + if (x+y < 1) + { + if (x > y) + { + // 1 triangle (h1, h2, h5 points) + int32 h1 = V9_h1_ptr[ 0]; + int32 h2 = V9_h1_ptr[129]; + int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; + a = h2-h1; + b = h5-h1-h2; + c = h1; + } + else + { + // 2 triangle (h1, h3, h5 points) + int32 h1 = V9_h1_ptr[0]; + int32 h3 = V9_h1_ptr[1]; + int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; + a = h5 - h1 - h3; + b = h3 - h1; + c = h1; + } + } + else + { + if (x > y) + { + // 3 triangle (h2, h4, h5 points) + int32 h2 = V9_h1_ptr[129]; + int32 h4 = V9_h1_ptr[130]; + int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; + a = h2 + h4 - h5; + b = h4 - h2; + c = h5 - h4; + } + else + { + // 4 triangle (h3, h4, h5 points) + int32 h3 = V9_h1_ptr[ 1]; + int32 h4 = V9_h1_ptr[130]; + int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; + a = h4 - h3; + b = h3 + h4 - h5; + c = h5 - h4; + } + } + + // Calculate height + return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight; +} + +float GridMap::getHeightFromUint16(float x, float y) const +{ + if (!m_uint16_V8 || !m_uint16_V9) + return m_gridHeight; + + x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); + y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); + + int x_int = (int)x; + int y_int = (int)y; + x -= x_int; + y -= y_int; + x_int &= (MAP_RESOLUTION - 1); + y_int &= (MAP_RESOLUTION - 1); + + int32 a, b, c; + uint16 *V9_h1_ptr = &m_uint16_V9[x_int*128 + x_int + y_int]; + if (x+y < 1) + { + if (x > y) + { + // 1 triangle (h1, h2, h5 points) + int32 h1 = V9_h1_ptr[ 0]; + int32 h2 = V9_h1_ptr[129]; + int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; + a = h2-h1; + b = h5-h1-h2; + c = h1; + } + else + { + // 2 triangle (h1, h3, h5 points) + int32 h1 = V9_h1_ptr[0]; + int32 h3 = V9_h1_ptr[1]; + int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; + a = h5 - h1 - h3; + b = h3 - h1; + c = h1; + } + } + else + { + if (x > y) + { + // 3 triangle (h2, h4, h5 points) + int32 h2 = V9_h1_ptr[129]; + int32 h4 = V9_h1_ptr[130]; + int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; + a = h2 + h4 - h5; + b = h4 - h2; + c = h5 - h4; + } + else + { + // 4 triangle (h3, h4, h5 points) + int32 h3 = V9_h1_ptr[ 1]; + int32 h4 = V9_h1_ptr[130]; + int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; + a = h4 - h3; + b = h3 + h4 - h5; + c = h5 - h4; + } + } + + // Calculate height + return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight; +} + +float GridMap::getLiquidLevel(float x, float y) +{ + if (!m_liquid_map) + return m_liquidLevel; + + x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); + y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); + + int cx_int = ((int)x & (MAP_RESOLUTION-1)) - m_liquid_offY; + int cy_int = ((int)y & (MAP_RESOLUTION-1)) - m_liquid_offX; + + if (cx_int < 0 || cx_int >=m_liquid_height) + return INVALID_HEIGHT; + + if (cy_int < 0 || cy_int >=m_liquid_width ) + return INVALID_HEIGHT; + + return m_liquid_map[cx_int*m_liquid_width + cy_int]; +} + +uint8 GridMap::getTerrainType(float x, float y) +{ + if (!m_liquid_type) + return (uint8)m_liquidType; + + 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 m_liquid_type[lx*16 + ly]; +} + +// Get water state on map +GridMapLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data) +{ + // Check water type (if no water return) + if (!m_liquid_type && !m_liquidType) + return LIQUID_MAP_NO_WATER; + + // Get cell + float cx = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); + float cy = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); + + int x_int = (int)cx & (MAP_RESOLUTION-1); + int y_int = (int)cy & (MAP_RESOLUTION-1); + + // Check water type in cell + uint8 type = m_liquid_type ? m_liquid_type[(x_int>>3)*16 + (y_int>>3)] : m_liquidType; + if (type == 0) + return LIQUID_MAP_NO_WATER; + + // Check req liquid type mask + if (ReqLiquidType && !(ReqLiquidType&type)) + return LIQUID_MAP_NO_WATER; + + // Check water level: + // Check water height map + int lx_int = x_int - m_liquid_offY; + if (lx_int < 0 || lx_int >=m_liquid_height) + return LIQUID_MAP_NO_WATER; + + int ly_int = y_int - m_liquid_offX; + if (ly_int < 0 || ly_int >=m_liquid_width ) + return LIQUID_MAP_NO_WATER; + + // Get water level + float liquid_level = m_liquid_map ? m_liquid_map[lx_int*m_liquid_width + ly_int] : m_liquidLevel; + + // Get ground level (sub 0.2 for fix some errors) + float ground_level = getHeight(x, y); + + // Check water level and ground level + if (liquid_level < ground_level || z < ground_level - 2) + return LIQUID_MAP_NO_WATER; + + // All ok in water -> store data + if (data) + { + data->type = type; + data->level = liquid_level; + data->depth_level = ground_level; + } + + // For speed check as int values + int delta = int((liquid_level - z) * 10); + + // Get position delta + if (delta > 20) // Under water + return LIQUID_MAP_UNDER_WATER; + + if (delta > 0 ) // In water + return LIQUID_MAP_IN_WATER; + + if (delta > -1) // Walk on water + return LIQUID_MAP_WATER_WALK; + // Above water + return LIQUID_MAP_ABOVE_WATER; +} + +bool GridMap::ExistMap(uint32 mapid,int gx,int gy) +{ + int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; + char* tmp = new char[len]; + snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,gx,gy); + + FILE *pf=fopen(tmp,"rb"); + + if(!pf) + { + sLog.outError("Check existing of map file '%s': not exist!",tmp); + delete[] tmp; + return false; + } + + GridMapFileHeader header; + fread(&header, sizeof(header), 1, pf); + if (header.mapMagic != *((uint32 const*)(MAP_MAGIC)) || + header.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC)) || + !IsAcceptableClientBuild(header.buildMagic)) + { + sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); + delete [] tmp; + fclose(pf); //close file before return + return false; + } + + delete [] tmp; + fclose(pf); + return true; +} + +bool GridMap::ExistVMap(uint32 mapid,int gx,int gy) +{ + if(VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager()) + { + if(vmgr->isMapLoadingEnabled()) + { + // x and y are swapped !! => fixed now + bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, gx,gy); + if(!exists) + { + std::string name = vmgr->getDirFileName(mapid,gx,gy); + sLog.outError("VMap file '%s' is missing or point to wrong version vmap file, redo vmaps with latest vmap_assembler.exe program", (sWorld.GetDataPath()+"vmaps/"+name).c_str()); + return false; + } + } + } + + return true; +} diff --git a/src/game/GridMap.h b/src/game/GridMap.h new file mode 100644 index 000000000..adc3421fd --- /dev/null +++ b/src/game/GridMap.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOS_GRIDMAP_H +#define MANGOS_GRIDMAP_H + +#include "Platform/Define.h" +#include "DBCStructure.h" +#include "GridDefines.h" +#include "Object.h" +#include "SharedDefines.h" + +#include +#include + +class Creature; +class Unit; +class WorldPacket; +class InstanceData; +class Group; +class InstanceSave; +struct ScriptInfo; +struct ScriptAction; +class BattleGround; + +struct GridMapFileHeader +{ + uint32 mapMagic; + uint32 versionMagic; + uint32 buildMagic; + uint32 areaMapOffset; + uint32 areaMapSize; + uint32 heightMapOffset; + uint32 heightMapSize; + uint32 liquidMapOffset; + uint32 liquidMapSize; +}; + +#define MAP_AREA_NO_AREA 0x0001 + +struct GridMapAreaHeader +{ + uint32 fourcc; + uint16 flags; + uint16 gridArea; +}; + +#define MAP_HEIGHT_NO_HEIGHT 0x0001 +#define MAP_HEIGHT_AS_INT16 0x0002 +#define MAP_HEIGHT_AS_INT8 0x0004 + +struct GridMapHeightHeader +{ + uint32 fourcc; + uint32 flags; + float gridHeight; + float gridMaxHeight; +}; + +#define MAP_LIQUID_NO_TYPE 0x0001 +#define MAP_LIQUID_NO_HEIGHT 0x0002 + +struct GridMapLiquidHeader +{ + uint32 fourcc; + uint16 flags; + uint16 liquidType; + uint8 offsetX; + uint8 offsetY; + uint8 width; + uint8 height; + float liquidLevel; +}; + +enum GridMapLiquidStatus +{ + LIQUID_MAP_NO_WATER = 0x00000000, + LIQUID_MAP_ABOVE_WATER = 0x00000001, + LIQUID_MAP_WATER_WALK = 0x00000002, + LIQUID_MAP_IN_WATER = 0x00000004, + LIQUID_MAP_UNDER_WATER = 0x00000008 +}; + +#define MAP_LIQUID_TYPE_NO_WATER 0x00 +#define MAP_LIQUID_TYPE_WATER 0x01 +#define MAP_LIQUID_TYPE_OCEAN 0x02 +#define MAP_LIQUID_TYPE_MAGMA 0x04 +#define MAP_LIQUID_TYPE_SLIME 0x08 + +#define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME) + +#define MAP_LIQUID_TYPE_DARK_WATER 0x10 +#define MAP_LIQUID_TYPE_WMO_WATER 0x20 + +struct GridMapLiquidData +{ + uint32 type; + float level; + float depth_level; +}; + +class GridMap +{ + private: + + uint32 m_flags; + + // Area data + uint16 m_gridArea; + uint16 *m_area_map; + + // Height level data + float m_gridHeight; + float m_gridIntHeightMultiplier; + union + { + float *m_V9; + uint16 *m_uint16_V9; + uint8 *m_uint8_V9; + }; + union + { + float *m_V8; + uint16 *m_uint16_V8; + uint8 *m_uint8_V8; + }; + + // Liquid data + uint16 m_liquidType; + uint8 m_liquid_offX; + uint8 m_liquid_offY; + uint8 m_liquid_width; + uint8 m_liquid_height; + float m_liquidLevel; + uint8 *m_liquid_type; + float *m_liquid_map; + + bool loadAreaData(FILE *in, uint32 offset, uint32 size); + bool loadHeightData(FILE *in, uint32 offset, uint32 size); + bool loadGridMapLiquidData(FILE *in, uint32 offset, uint32 size); + + // Get height functions and pointers + typedef float (GridMap::*pGetHeightPtr) (float x, float y) const; + pGetHeightPtr m_gridGetHeight; + float getHeightFromFloat(float x, float y) const; + float getHeightFromUint16(float x, float y) const; + float getHeightFromUint8(float x, float y) const; + float getHeightFromFlat(float x, float y) const; + + public: + + GridMap(); + ~GridMap(); + + bool loadData(char *filaname); + void unloadData(); + + static bool ExistMap(uint32 mapid, int gx, int gy); + static bool ExistVMap(uint32 mapid, int gx, int gy); + + uint16 getArea(float x, float y); + float getHeight(float x, float y) { return (this->*m_gridGetHeight)(x, y); } + float getLiquidLevel(float x, float y); + uint8 getTerrainType(float x, float y); + GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data = 0); +}; + +#endif diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index cebb448a0..603032f13 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -310,8 +310,8 @@ bool ChatHandler::HandleGPSCommand(const char* args) int gx=63-p.x_coord; int gy=63-p.y_coord; - uint32 have_map = Map::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0; - uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; + uint32 have_map = GridMap::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0; + uint32 have_vmap = GridMap::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; PSendSysMessage(LANG_MAP_POSITION, obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : "" ), @@ -336,8 +336,8 @@ bool ChatHandler::HandleGPSCommand(const char* args) cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), zone_x, zone_y, ground_z, floor_z, have_map, have_vmap ); - LiquidData liquid_status; - ZLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status); + GridMapLiquidData liquid_status; + GridMapLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status); if (res) { PSendSysMessage(LANG_LIQUID_STATUS, liquid_status.level, liquid_status.depth_level, liquid_status.type, res); diff --git a/src/game/Makefile.am b/src/game/Makefile.am index b9022daf0..f4ef7892f 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -132,6 +132,8 @@ libmangosgame_a_SOURCES = \ GossipDef.cpp \ GossipDef.h \ GridDefines.h \ + GridMap.cpp \ + GridMap.h \ GridNotifiers.cpp \ GridNotifiers.h \ GridNotifiersImpl.h \ diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 206af48f3..15ff06b36 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -35,7 +35,6 @@ #include "Group.h" #include "MapRefManager.h" #include "DBCEnums.h" - #include "MapInstanced.h" #include "InstanceSaveMgr.h" #include "VMapFactory.h" @@ -43,12 +42,6 @@ GridState* si_GridStates[MAX_GRID_STATE]; -static char const* MAP_MAGIC = "MAPS"; -static char const* MAP_VERSION_MAGIC = "v1.1"; -static char const* MAP_AREA_MAGIC = "AREA"; -static char const* MAP_HEIGHT_MAGIC = "MHGT"; -static char const* MAP_LIQUID_MAGIC = "MLIQ"; - struct ScriptAction { uint64 sourceGUID; @@ -66,58 +59,6 @@ Map::~Map() sWorld.DecreaseScheduledScriptCount(m_scriptSchedule.size()); } -bool Map::ExistMap(uint32 mapid,int gx,int gy) -{ - int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; - char* tmp = new char[len]; - snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,gx,gy); - - FILE *pf=fopen(tmp,"rb"); - - if(!pf) - { - sLog.outError("Check existing of map file '%s': not exist!",tmp); - delete[] tmp; - return false; - } - - map_fileheader header; - fread(&header, sizeof(header), 1, pf); - if (header.mapMagic != *((uint32 const*)(MAP_MAGIC)) || - header.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC)) || - !IsAcceptableClientBuild(header.buildMagic)) - { - sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); - delete [] tmp; - fclose(pf); //close file before return - return false; - } - - delete [] tmp; - fclose(pf); - return true; -} - -bool Map::ExistVMap(uint32 mapid,int gx,int gy) -{ - if(VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager()) - { - if(vmgr->isMapLoadingEnabled()) - { - // x and y are swapped !! => fixed now - bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, gx,gy); - if(!exists) - { - std::string name = vmgr->getDirFileName(mapid,gx,gy); - sLog.outError("VMap file '%s' is missing or point to wrong version vmap file, redo vmaps with latest vmap_assembler.exe program", (sWorld.GetDataPath()+"vmaps/"+name).c_str()); - return false; - } - } - } - - return true; -} - void Map::LoadVMap(int gx,int gy) { // x and y are swapped !! @@ -1066,510 +1007,6 @@ uint32 Map::GetMaxResetDelay() const return mapDiff ? mapDiff->resetTime : 0; } -//***************************** -// Grid function -//***************************** -GridMap::GridMap() -{ - m_flags = 0; - // Area data - m_gridArea = 0; - m_area_map = NULL; - // Height level data - m_gridHeight = INVALID_HEIGHT; - m_gridGetHeight = &GridMap::getHeightFromFlat; - m_V9 = NULL; - m_V8 = NULL; - // Liquid data - m_liquidType = 0; - m_liquid_offX = 0; - m_liquid_offY = 0; - m_liquid_width = 0; - m_liquid_height = 0; - m_liquidLevel = INVALID_HEIGHT; - m_liquid_type = NULL; - m_liquid_map = NULL; -} - -GridMap::~GridMap() -{ - unloadData(); -} - -bool GridMap::loadData(char *filename) -{ - // Unload old data if exist - unloadData(); - - map_fileheader header; - // Not return error if file not found - FILE *in = fopen(filename, "rb"); - if (!in) - return true; - fread(&header, sizeof(header),1,in); - if (header.mapMagic == *((uint32 const*)(MAP_MAGIC)) && - header.versionMagic == *((uint32 const*)(MAP_VERSION_MAGIC)) || - !IsAcceptableClientBuild(header.buildMagic)) - { - // loadup area data - if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize)) - { - sLog.outError("Error loading map area data\n"); - fclose(in); - return false; - } - // loadup height data - if (header.heightMapOffset && !loadHeightData(in, header.heightMapOffset, header.heightMapSize)) - { - sLog.outError("Error loading map height data\n"); - fclose(in); - return false; - } - // loadup liquid data - if (header.liquidMapOffset && !loadLiquidData(in, header.liquidMapOffset, header.liquidMapSize)) - { - sLog.outError("Error loading map liquids data\n"); - fclose(in); - return false; - } - fclose(in); - return true; - } - sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.", filename); - fclose(in); - return false; -} - -void GridMap::unloadData() -{ - if (m_area_map) delete[] m_area_map; - if (m_V9) delete[] m_V9; - if (m_V8) delete[] m_V8; - if (m_liquid_type) delete[] m_liquid_type; - if (m_liquid_map) delete[] m_liquid_map; - m_area_map = NULL; - m_V9 = NULL; - m_V8 = NULL; - m_liquid_type = NULL; - m_liquid_map = NULL; - m_gridGetHeight = &GridMap::getHeightFromFlat; -} - -bool GridMap::loadAreaData(FILE *in, uint32 offset, uint32 /*size*/) -{ - map_areaHeader header; - fseek(in, offset, SEEK_SET); - fread(&header, sizeof(header), 1, in); - if (header.fourcc != *((uint32 const*)(MAP_AREA_MAGIC))) - return false; - - m_gridArea = header.gridArea; - if (!(header.flags & MAP_AREA_NO_AREA)) - { - m_area_map = new uint16 [16*16]; - fread(m_area_map, sizeof(uint16), 16*16, in); - } - return true; -} - -bool GridMap::loadHeightData(FILE *in, uint32 offset, uint32 /*size*/) -{ - map_heightHeader header; - fseek(in, offset, SEEK_SET); - fread(&header, sizeof(header), 1, in); - if (header.fourcc != *((uint32 const*)(MAP_HEIGHT_MAGIC))) - return false; - - m_gridHeight = header.gridHeight; - if (!(header.flags & MAP_HEIGHT_NO_HEIGHT)) - { - if ((header.flags & MAP_HEIGHT_AS_INT16)) - { - m_uint16_V9 = new uint16 [129*129]; - m_uint16_V8 = new uint16 [128*128]; - fread(m_uint16_V9, sizeof(uint16), 129*129, in); - fread(m_uint16_V8, sizeof(uint16), 128*128, in); - m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 65535; - m_gridGetHeight = &GridMap::getHeightFromUint16; - } - else if ((header.flags & MAP_HEIGHT_AS_INT8)) - { - m_uint8_V9 = new uint8 [129*129]; - m_uint8_V8 = new uint8 [128*128]; - fread(m_uint8_V9, sizeof(uint8), 129*129, in); - fread(m_uint8_V8, sizeof(uint8), 128*128, in); - m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 255; - m_gridGetHeight = &GridMap::getHeightFromUint8; - } - else - { - m_V9 = new float [129*129]; - m_V8 = new float [128*128]; - fread(m_V9, sizeof(float), 129*129, in); - fread(m_V8, sizeof(float), 128*128, in); - m_gridGetHeight = &GridMap::getHeightFromFloat; - } - } - else - m_gridGetHeight = &GridMap::getHeightFromFlat; - return true; -} - -bool GridMap::loadLiquidData(FILE *in, uint32 offset, uint32 /*size*/) -{ - map_liquidHeader header; - fseek(in, offset, SEEK_SET); - fread(&header, sizeof(header), 1, in); - if (header.fourcc != *((uint32 const*)(MAP_LIQUID_MAGIC))) - return false; - - m_liquidType = header.liquidType; - m_liquid_offX = header.offsetX; - m_liquid_offY = header.offsetY; - m_liquid_width = header.width; - m_liquid_height= header.height; - m_liquidLevel = header.liquidLevel; - - if (!(header.flags & MAP_LIQUID_NO_TYPE)) - { - m_liquid_type = new uint8 [16*16]; - fread(m_liquid_type, sizeof(uint8), 16*16, in); - } - if (!(header.flags & MAP_LIQUID_NO_HEIGHT)) - { - m_liquid_map = new float [m_liquid_width*m_liquid_height]; - fread(m_liquid_map, sizeof(float), m_liquid_width*m_liquid_height, in); - } - return true; -} - -uint16 GridMap::getArea(float x, float y) -{ - if (!m_area_map) - return m_gridArea; - - 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 m_area_map[lx*16 + ly]; -} - -float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const -{ - return m_gridHeight; -} - -float GridMap::getHeightFromFloat(float x, float y) const -{ - if (!m_V8 || !m_V9) - return m_gridHeight; - - x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); - y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); - - int x_int = (int)x; - int y_int = (int)y; - x -= x_int; - y -= y_int; - x_int&=(MAP_RESOLUTION - 1); - y_int&=(MAP_RESOLUTION - 1); - - // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid - // +--------------> X - // | h1-------h2 Coordinates is: - // | | \ 1 / | h1 0,0 - // | | \ / | h2 0,1 - // | | 2 h5 3 | h3 1,0 - // | | / \ | h4 1,1 - // | | / 4 \ | h5 1/2,1/2 - // | h3-------h4 - // V Y - // For find height need - // 1 - detect triangle - // 2 - solve linear equation from triangle points - // Calculate coefficients for solve h = a*x + b*y + c - - float a,b,c; - // Select triangle: - if (x+y < 1) - { - if (x > y) - { - // 1 triangle (h1, h2, h5 points) - float h1 = m_V9[(x_int )*129 + y_int]; - float h2 = m_V9[(x_int+1)*129 + y_int]; - float h5 = 2 * m_V8[x_int*128 + y_int]; - a = h2-h1; - b = h5-h1-h2; - c = h1; - } - else - { - // 2 triangle (h1, h3, h5 points) - float h1 = m_V9[x_int*129 + y_int ]; - float h3 = m_V9[x_int*129 + y_int+1]; - float h5 = 2 * m_V8[x_int*128 + y_int]; - a = h5 - h1 - h3; - b = h3 - h1; - c = h1; - } - } - else - { - if (x > y) - { - // 3 triangle (h2, h4, h5 points) - float h2 = m_V9[(x_int+1)*129 + y_int ]; - float h4 = m_V9[(x_int+1)*129 + y_int+1]; - float h5 = 2 * m_V8[x_int*128 + y_int]; - a = h2 + h4 - h5; - b = h4 - h2; - c = h5 - h4; - } - else - { - // 4 triangle (h3, h4, h5 points) - float h3 = m_V9[(x_int )*129 + y_int+1]; - float h4 = m_V9[(x_int+1)*129 + y_int+1]; - float h5 = 2 * m_V8[x_int*128 + y_int]; - a = h4 - h3; - b = h3 + h4 - h5; - c = h5 - h4; - } - } - // Calculate height - return a * x + b * y + c; -} - -float GridMap::getHeightFromUint8(float x, float y) const -{ - if (!m_uint8_V8 || !m_uint8_V9) - return m_gridHeight; - - x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); - y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); - - int x_int = (int)x; - int y_int = (int)y; - x -= x_int; - y -= y_int; - x_int&=(MAP_RESOLUTION - 1); - y_int&=(MAP_RESOLUTION - 1); - - int32 a, b, c; - uint8 *V9_h1_ptr = &m_uint8_V9[x_int*128 + x_int + y_int]; - if (x+y < 1) - { - if (x > y) - { - // 1 triangle (h1, h2, h5 points) - int32 h1 = V9_h1_ptr[ 0]; - int32 h2 = V9_h1_ptr[129]; - int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; - a = h2-h1; - b = h5-h1-h2; - c = h1; - } - else - { - // 2 triangle (h1, h3, h5 points) - int32 h1 = V9_h1_ptr[0]; - int32 h3 = V9_h1_ptr[1]; - int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; - a = h5 - h1 - h3; - b = h3 - h1; - c = h1; - } - } - else - { - if (x > y) - { - // 3 triangle (h2, h4, h5 points) - int32 h2 = V9_h1_ptr[129]; - int32 h4 = V9_h1_ptr[130]; - int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; - a = h2 + h4 - h5; - b = h4 - h2; - c = h5 - h4; - } - else - { - // 4 triangle (h3, h4, h5 points) - int32 h3 = V9_h1_ptr[ 1]; - int32 h4 = V9_h1_ptr[130]; - int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int]; - a = h4 - h3; - b = h3 + h4 - h5; - c = h5 - h4; - } - } - // Calculate height - return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight; -} - -float GridMap::getHeightFromUint16(float x, float y) const -{ - if (!m_uint16_V8 || !m_uint16_V9) - return m_gridHeight; - - x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); - y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); - - int x_int = (int)x; - int y_int = (int)y; - x -= x_int; - y -= y_int; - x_int&=(MAP_RESOLUTION - 1); - y_int&=(MAP_RESOLUTION - 1); - - int32 a, b, c; - uint16 *V9_h1_ptr = &m_uint16_V9[x_int*128 + x_int + y_int]; - if (x+y < 1) - { - if (x > y) - { - // 1 triangle (h1, h2, h5 points) - int32 h1 = V9_h1_ptr[ 0]; - int32 h2 = V9_h1_ptr[129]; - int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; - a = h2-h1; - b = h5-h1-h2; - c = h1; - } - else - { - // 2 triangle (h1, h3, h5 points) - int32 h1 = V9_h1_ptr[0]; - int32 h3 = V9_h1_ptr[1]; - int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; - a = h5 - h1 - h3; - b = h3 - h1; - c = h1; - } - } - else - { - if (x > y) - { - // 3 triangle (h2, h4, h5 points) - int32 h2 = V9_h1_ptr[129]; - int32 h4 = V9_h1_ptr[130]; - int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; - a = h2 + h4 - h5; - b = h4 - h2; - c = h5 - h4; - } - else - { - // 4 triangle (h3, h4, h5 points) - int32 h3 = V9_h1_ptr[ 1]; - int32 h4 = V9_h1_ptr[130]; - int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int]; - a = h4 - h3; - b = h3 + h4 - h5; - c = h5 - h4; - } - } - // Calculate height - return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight; -} - -float GridMap::getLiquidLevel(float x, float y) -{ - if (!m_liquid_map) - return m_liquidLevel; - - x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); - y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); - - int cx_int = ((int)x & (MAP_RESOLUTION-1)) - m_liquid_offY; - int cy_int = ((int)y & (MAP_RESOLUTION-1)) - m_liquid_offX; - - if (cx_int < 0 || cx_int >=m_liquid_height) - return INVALID_HEIGHT; - if (cy_int < 0 || cy_int >=m_liquid_width ) - return INVALID_HEIGHT; - - return m_liquid_map[cx_int*m_liquid_width + cy_int]; -} - -uint8 GridMap::getTerrainType(float x, float y) -{ - if (!m_liquid_type) - return (uint8)m_liquidType; - - 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 m_liquid_type[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 (!m_liquid_type && !m_liquidType) - return LIQUID_MAP_NO_WATER; - - // Get cell - float cx = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS); - float cy = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS); - - int x_int = (int)cx & (MAP_RESOLUTION-1); - int y_int = (int)cy & (MAP_RESOLUTION-1); - - // Check water type in cell - uint8 type = m_liquid_type ? m_liquid_type[(x_int>>3)*16 + (y_int>>3)] : m_liquidType; - if (type == 0) - return LIQUID_MAP_NO_WATER; - - // Check req liquid type mask - if (ReqLiquidType && !(ReqLiquidType&type)) - return LIQUID_MAP_NO_WATER; - - // Check water level: - // Check water height map - int lx_int = x_int - m_liquid_offY; - int ly_int = y_int - m_liquid_offX; - if (lx_int < 0 || lx_int >=m_liquid_height) - return LIQUID_MAP_NO_WATER; - if (ly_int < 0 || ly_int >=m_liquid_width ) - return LIQUID_MAP_NO_WATER; - - // Get water level - float liquid_level = m_liquid_map ? m_liquid_map[lx_int*m_liquid_width + ly_int] : m_liquidLevel; - // Get ground level (sub 0.2 for fix some errors) - float ground_level = getHeight(x, y); - - // Check water level and ground level - if (liquid_level < ground_level || z < ground_level - 2) - return LIQUID_MAP_NO_WATER; - - // All ok in water -> store data - if (data) - { - data->type = type; - data->level = liquid_level; - data->depth_level = ground_level; - } - - // For speed check as int values - int delta = int((liquid_level - z) * 10); - - // Get position delta - if (delta > 20) // Under water - return LIQUID_MAP_UNDER_WATER; - if (delta > 0 ) // In water - return LIQUID_MAP_IN_WATER; - if (delta > -1) // Walk on water - return LIQUID_MAP_WATER_WALK; - // Above water - return LIQUID_MAP_ABOVE_WATER; -} - inline GridMap *Map::GetGrid(float x, float y) { // half opt method @@ -1899,7 +1336,7 @@ uint8 Map::GetTerrainType(float x, float y ) const return 0; } -ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data) const +GridMapLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data) const { if(GridMap* gmap = const_cast(this)->GetGrid(x, y)) return gmap->getLiquidStatus(x, y, z, ReqLiquidType, data); @@ -1948,7 +1385,7 @@ bool Map::IsInWater(float x, float y, float pZ) const // Check surface in x, y point for liquid if (const_cast(this)->GetGrid(x, y)) { - LiquidData liquid_status; + GridMapLiquidData liquid_status; if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, &liquid_status)) { if (liquid_status.level - liquid_status.depth_level > 2) diff --git a/src/game/Map.h b/src/game/Map.h index 3acb8813f..7607b49da 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -30,6 +30,7 @@ #include "Object.h" #include "Timer.h" #include "SharedDefines.h" +#include "GridMap.h" #include "GameSystem/GridRefManager.h" #include "MapRefManager.h" #include "Utilities/TypeList.h" @@ -46,139 +47,7 @@ class InstanceSave; struct ScriptInfo; struct ScriptAction; class BattleGround; - -//****************************************** -// Map file format defines -//****************************************** -struct map_fileheader -{ - uint32 mapMagic; - uint32 versionMagic; - uint32 buildMagic; - uint32 areaMapOffset; - uint32 areaMapSize; - uint32 heightMapOffset; - uint32 heightMapSize; - uint32 liquidMapOffset; - uint32 liquidMapSize; -}; - -#define MAP_AREA_NO_AREA 0x0001 - -struct map_areaHeader -{ - uint32 fourcc; - uint16 flags; - uint16 gridArea; -}; - -#define MAP_HEIGHT_NO_HEIGHT 0x0001 -#define MAP_HEIGHT_AS_INT16 0x0002 -#define MAP_HEIGHT_AS_INT8 0x0004 - -struct map_heightHeader -{ - uint32 fourcc; - uint32 flags; - float gridHeight; - float gridMaxHeight; -}; - -#define MAP_LIQUID_NO_TYPE 0x0001 -#define MAP_LIQUID_NO_HEIGHT 0x0002 - -struct map_liquidHeader -{ - uint32 fourcc; - uint16 flags; - uint16 liquidType; - uint8 offsetX; - uint8 offsetY; - uint8 width; - uint8 height; - float liquidLevel; -}; - -enum ZLiquidStatus -{ - LIQUID_MAP_NO_WATER = 0x00000000, - LIQUID_MAP_ABOVE_WATER = 0x00000001, - LIQUID_MAP_WATER_WALK = 0x00000002, - LIQUID_MAP_IN_WATER = 0x00000004, - LIQUID_MAP_UNDER_WATER = 0x00000008 -}; - -#define MAP_LIQUID_TYPE_NO_WATER 0x00 -#define MAP_LIQUID_TYPE_WATER 0x01 -#define MAP_LIQUID_TYPE_OCEAN 0x02 -#define MAP_LIQUID_TYPE_MAGMA 0x04 -#define MAP_LIQUID_TYPE_SLIME 0x08 - -#define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME) - -#define MAP_LIQUID_TYPE_DARK_WATER 0x10 -#define MAP_LIQUID_TYPE_WMO_WATER 0x20 - -struct LiquidData -{ - uint32 type; - float level; - float depth_level; -}; - -class GridMap -{ - uint32 m_flags; - // Area data - uint16 m_gridArea; - uint16 *m_area_map; - // Height level data - float m_gridHeight; - float m_gridIntHeightMultiplier; - union{ - float *m_V9; - uint16 *m_uint16_V9; - uint8 *m_uint8_V9; - }; - union{ - float *m_V8; - uint16 *m_uint16_V8; - uint8 *m_uint8_V8; - }; - // Liquid data - uint16 m_liquidType; - uint8 m_liquid_offX; - uint8 m_liquid_offY; - uint8 m_liquid_width; - uint8 m_liquid_height; - float m_liquidLevel; - uint8 *m_liquid_type; - float *m_liquid_map; - - bool loadAreaData(FILE *in, uint32 offset, uint32 size); - bool loadHeightData(FILE *in, uint32 offset, uint32 size); - bool loadLiquidData(FILE *in, uint32 offset, uint32 size); - - // Get height functions and pointers - typedef float (GridMap::*pGetHeightPtr) (float x, float y) const; - pGetHeightPtr m_gridGetHeight; - float getHeightFromFloat(float x, float y) const; - float getHeightFromUint16(float x, float y) const; - float getHeightFromUint8(float x, float y) const; - float getHeightFromFlat(float x, float y) const; - -public: - GridMap(); - ~GridMap(); - bool loadData(char *filaname); - void unloadData(); - - uint16 getArea(float x, float y); - inline float getHeight(float x, float y) {return (this->*m_gridGetHeight)(x, y);} - float getLiquidLevel(float x, float y); - uint8 getTerrainType(float x, float y); - ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0); -}; +class GridMap; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined( __GNUC__ ) @@ -275,9 +144,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj time_t GetGridExpiry(void) const { return i_gridExpiry; } uint32 GetId(void) const { return i_id; } - static bool ExistMap(uint32 mapid, int gx, int gy); - static bool ExistVMap(uint32 mapid, int gx, int gy); - static void InitStateMachine(); static void DeleteStateMachine(); @@ -288,7 +154,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj float GetHeight(float x, float y, float z, bool pCheckVMap=true) const; bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use - ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0) const; + GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData *data = 0) const; uint16 GetAreaFlag(float x, float y, float z) const; uint8 GetTerrainType(float x, float y ) const; @@ -573,16 +439,6 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map BattleGround* m_bg; }; -/*inline -uint64 -Map::CalculateGridMask(const uint32 &y) const -{ - uint64 mask = 1; - mask <<= y; - return mask; -} -*/ - template inline void Map::Visit(const Cell& cell, TypeContainerVisitor &visitor) diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 379aee55a..7feb5ece6 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -283,7 +283,7 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y) int gx=63-p.x_coord; int gy=63-p.y_coord; - return Map::ExistMap(mapid,gx,gy) && Map::ExistVMap(mapid,gx,gy); + return GridMap::ExistMap(mapid,gx,gy) && GridMap::ExistVMap(mapid,gx,gy); } bool MapManager::IsValidMAP(uint32 mapid) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fadd58cd8..7513657d7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -20427,8 +20427,8 @@ void Player::SetOriginalGroup(Group *group, int8 subgroup) void Player::UpdateUnderwaterState( Map* m, float x, float y, float z ) { - LiquidData liquid_status; - ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + GridMapLiquidData liquid_status; + GridMapLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); if (!res) { m_MirrorTimerFlags &= ~(UNDERWATER_INWATER|UNDERWATER_INLAVA|UNDERWATER_INSLIME|UNDERWATER_INDARKWATER); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d84e0e677..f50169e36 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9994" + #define REVISION_NR "9995" #endif // __REVISION_NR_H__ diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index 4be936d3e..575fef41e 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -398,6 +398,7 @@ + @@ -547,6 +548,7 @@ + diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters index 0e1ae5581..44940f527 100644 --- a/win/VC100/game.vcxproj.filters +++ b/win/VC100/game.vcxproj.filters @@ -120,6 +120,9 @@ World/Handlers + + World/Handlers + World/Handlers @@ -516,6 +519,9 @@ World/Handlers + + World/Handlers + World/Handlers diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index dff181fcc..409c26ffa 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -745,6 +745,14 @@ RelativePath="..\..\src\game\GridDefines.h" > + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index 4003b3dba..b8d61586e 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -746,6 +746,14 @@ RelativePath="..\..\src\game\GridDefines.h" > + + + +