From 204b846fe695768ad56f8f8c832d6deaa6dc2e1c Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 14:45:05 +0200 Subject: Core/Tools: Implemented mmaps_generator. --- src/tools/CMakeLists.txt | 1 + src/tools/mmap_extractor/CMakeLists.txt | 68 ++ src/tools/mmap_extractor/Info/readme.txt | 66 ++ src/tools/mmap_extractor/IntermediateValues.cpp | 277 ++++++++ src/tools/mmap_extractor/IntermediateValues.h | 53 ++ src/tools/mmap_extractor/MapBuilder.cpp | 894 ++++++++++++++++++++++++ src/tools/mmap_extractor/MapBuilder.h | 129 ++++ src/tools/mmap_extractor/PathCommon.h | 128 ++++ src/tools/mmap_extractor/PathGenerator.cpp | 273 ++++++++ src/tools/mmap_extractor/TerrainBuilder.cpp | 854 ++++++++++++++++++++++ src/tools/mmap_extractor/TerrainBuilder.h | 138 ++++ src/tools/mmap_extractor/VMapExtensions.cpp | 72 ++ 12 files changed, 2953 insertions(+) create mode 100644 src/tools/mmap_extractor/CMakeLists.txt create mode 100644 src/tools/mmap_extractor/Info/readme.txt create mode 100644 src/tools/mmap_extractor/IntermediateValues.cpp create mode 100644 src/tools/mmap_extractor/IntermediateValues.h create mode 100644 src/tools/mmap_extractor/MapBuilder.cpp create mode 100644 src/tools/mmap_extractor/MapBuilder.h create mode 100644 src/tools/mmap_extractor/PathCommon.h create mode 100644 src/tools/mmap_extractor/PathGenerator.cpp create mode 100644 src/tools/mmap_extractor/TerrainBuilder.cpp create mode 100644 src/tools/mmap_extractor/TerrainBuilder.h create mode 100644 src/tools/mmap_extractor/VMapExtensions.cpp (limited to 'src') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index a956655ffaa..f4c5f695b26 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -11,3 +11,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) +add_subdirectory(mmaps_extractor) diff --git a/src/tools/mmap_extractor/CMakeLists.txt b/src/tools/mmap_extractor/CMakeLists.txt new file mode 100644 index 00000000000..c7c1a954371 --- /dev/null +++ b/src/tools/mmap_extractor/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (C) 2008-2011 Trinity +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +# definitions +add_definitions(-DNO_CORE_FUNCS) +add_definitions(-DDEBUG) +add_definitions(-DNO_vsnprintf) + +include_directories( + ${CMAKE_BINARY_DIR} + ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/zlib + ${CMAKE_SOURCE_DIR}/dep/bzip2 + ${CMAKE_SOURCE_DIR}/dep/acelite + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/src/server/game/Maps + ${CMAKE_SOURCE_DIR}/src/server/game/DataStores + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints + ${CMAKE_SOURCE_DIR}/src/server/game/Grids + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells + ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous + ${CMAKE_SOURCE_DIR}/src/server/game/Conditions + ${CMAKE_SOURCE_DIR}/src/server/collision + ${CMAKE_SOURCE_DIR}/src/server/collision/Management + ${CMAKE_SOURCE_DIR}/src/server/collision/Maps + ${CMAKE_SOURCE_DIR}/src/server/collision/Models +) + +add_executable(movements_extractor ${sources}) + +target_link_libraries(movements_extractor + ${MYSQL_LIBRARY} + ${ACE_LIBRARY} + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + Recast + Detour + collision + g3dlib + shared +) + +if( UNIX ) + install(TARGETS movements_extractor DESTINATION bin) +elseif( WIN32 ) + install(TARGETS movements_extractor DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() diff --git a/src/tools/mmap_extractor/Info/readme.txt b/src/tools/mmap_extractor/Info/readme.txt new file mode 100644 index 00000000000..8d7c4f9d2e0 --- /dev/null +++ b/src/tools/mmap_extractor/Info/readme.txt @@ -0,0 +1,66 @@ +Generator command line args + +--offMeshInput [file.*] Path to file containing off mesh connections data. + Format must be: (see offmesh_example.txt) + "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" + Single mesh connection per line. + +--silent Make us script friendly. Do not wait for user input + on error or completion. + +--bigBaseUnit [true|false] Generate tile/map using bigger basic unit. + Use this option only if you have unexpected gaps. + + false: use normal metrics (default) + +--maxAngle [#] Max walkable inclination angle + + float between 45 and 90 degrees (default 60) + +--skipLiquid liquid data for maps + + false: include liquid data (default) + +--skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), + 1 (Kalimdor), 530 (Outlands), 571 (Northrend) + + false: build continents (default) + +--skipJunkMaps [true|false] junk maps include some unused + maps, transport maps, and some other + + true: skip junk maps (default) + +--skipBattlegrounds [true|false] does not include PVP arenas + + false: skip battlegrounds (default) + +--debugOutput [true|false] create debugging files for use with RecastDemo + if you are only creating mmaps for use with MaNGOS, + you don't want debugging files + + false: don't create debugging files (default) + +--tile [#,#] Build the specified tile + seperate number with a comma ',' + must specify a map number (see below) + if this option is not used, all tiles are built + + [#] Build only the map specified by # + this command will build the map regardless of --skip* option settings + if you do not specify a map number, builds all maps that pass the filters specified by --skip* options + + +examples: + +movement_extractor +builds maps using the default settings (see above for defaults) + +movement_extractor --skipContinents true +builds the default maps, except continents + +movement_extractor 0 +builds all tiles of map 0 + +movement_extractor 0 --tile 34,46 +builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmap_extractor/IntermediateValues.cpp b/src/tools/mmap_extractor/IntermediateValues.cpp new file mode 100644 index 00000000000..9eefb1e65f0 --- /dev/null +++ b/src/tools/mmap_extractor/IntermediateValues.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "IntermediateValues.h" + +namespace MMAP +{ + IntermediateValues::~IntermediateValues() + { + rcFreeCompactHeightfield(compactHeightfield); + rcFreeHeightField(heightfield); + rcFreeContourSet(contours); + rcFreePolyMesh(polyMesh); + rcFreePolyMeshDetail(polyMeshDetail); + } + + void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); + + printf("%sWriting debug output... \r", tileString); + + string name("meshes/%03u%02i%02i."); + +#define DEBUG_WRITE(fileExtension,data) \ + do { \ + sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ + FILE* file = fopen(fileName, "wb"); \ + if (!file) \ + { \ + char message[1024]; \ + sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ + perror(message); \ + } \ + else \ + debugWrite(file, data); \ + if (file) fclose(file); \ + printf("%sWriting debug output... \r", tileString); \ + } while (false) + + if (heightfield) + DEBUG_WRITE("hf", heightfield); + if (compactHeightfield) + DEBUG_WRITE("chf", compactHeightfield); + if (contours) + DEBUG_WRITE("cs", contours); + if (polyMesh) + DEBUG_WRITE("pmesh", polyMesh); + if (polyMeshDetail) + DEBUG_WRITE("dmesh", polyMeshDetail); + +#undef DEBUG_WRITE + } + + void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->width), sizeof(int), 1, file); + fwrite(&(mesh->height), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + + for (int y = 0; y < mesh->height; ++y) + for (int x = 0; x < mesh->width; ++x) + { + rcSpan* span = mesh->spans[x+y*mesh->width]; + + // first, count the number of spans + int spanCount = 0; + while (span) + { + spanCount++; + span = span->next; + } + + // write the span count + fwrite(&spanCount, sizeof(int), 1, file); + + // write the spans + span = mesh->spans[x+y*mesh->width]; + while (span) + { + fwrite(span, sizeof(rcSpan), 1, file); + span = span->next; + } + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) + { + if (!file | !chf) + return; + + fwrite(&(chf->width), sizeof(chf->width), 1, file); + fwrite(&(chf->height), sizeof(chf->height), 1, file); + fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); + + fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); + fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); + + fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); + fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); + + fwrite(chf->bmin, sizeof(chf->bmin), 1, file); + fwrite(chf->bmax, sizeof(chf->bmax), 1, file); + + fwrite(&(chf->cs), sizeof(chf->cs), 1, file); + fwrite(&(chf->ch), sizeof(chf->ch), 1, file); + + int tmp = 0; + if (chf->cells) tmp |= 1; + if (chf->spans) tmp |= 2; + if (chf->dist) tmp |= 4; + if (chf->areas) tmp |= 8; + + fwrite(&tmp, sizeof(tmp), 1, file); + + if (chf->cells) + fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); + if (chf->spans) + fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); + if (chf->dist) + fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); + if (chf->areas) + fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) + { + if (!file || !cs) + return; + + fwrite(&(cs->cs), sizeof(float), 1, file); + fwrite(&(cs->ch), sizeof(float), 1, file); + fwrite(cs->bmin, sizeof(float), 3, file); + fwrite(cs->bmax, sizeof(float), 3, file); + fwrite(&(cs->nconts), sizeof(int), 1, file); + for (int i = 0; i < cs->nconts; ++i) + { + fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); + fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); + fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); + fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); + fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); + fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->nvp), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); + fwrite(&(mesh->npolys), sizeof(int), 1, file); + fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); + fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); + fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); + fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); + fwrite(&(mesh->ntris), sizeof(int), 1, file); + fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); + fwrite(&(mesh->nmeshes), sizeof(int), 1, file); + fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); + } + + void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + char objFileName[255]; + sprintf(objFileName, "meshes/map%03u.obj", mapID); + + FILE* objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + G3D::Array allVerts; + G3D::Array allTris; + + allTris.append(meshData.liquidTris); + allVerts.append(meshData.liquidVerts); + TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); + allVerts.append(meshData.solidVerts); + + float* verts = allVerts.getCArray(); + int vertCount = allVerts.size() / 3; + int* tris = allTris.getCArray(); + int triCount = allTris.size() / 3; + + for (int i = 0; i < allVerts.size() / 3; i++) + fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); + + for (int i = 0; i < allTris.size() / 3; i++) + fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); + + fclose(objFile); + + + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); + printf("%sWriting debug output... \r", tileString); + + sprintf(objFileName, "meshes/%03u.map", mapID); + + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + char b = '\0'; + fwrite(&b, sizeof(char), 1, objFile); + fclose(objFile); + + sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + fwrite(&vertCount, sizeof(int), 1, objFile); + fwrite(verts, sizeof(float), vertCount*3, objFile); + fflush(objFile); + + fwrite(&triCount, sizeof(int), 1, objFile); + fwrite(tris, sizeof(int), triCount*3, objFile); + fflush(objFile); + + fclose(objFile); + } +} diff --git a/src/tools/mmap_extractor/IntermediateValues.h b/src/tools/mmap_extractor/IntermediateValues.h new file mode 100644 index 00000000000..a267a0f6412 --- /dev/null +++ b/src/tools/mmap_extractor/IntermediateValues.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _INTERMEDIATE_VALUES_H +#define _INTERMEDIATE_VALUES_H + +#include "PathCommon.h" +#include "TerrainBuilder.h" +#include "Recast.h" +#include "DetourNavMesh.h" + +namespace MMAP +{ + // this class gathers all debug info holding and output + struct IntermediateValues + { + rcHeightfield* heightfield; + rcCompactHeightfield* compactHeightfield; + rcContourSet* contours; + rcPolyMesh* polyMesh; + rcPolyMeshDetail* polyMeshDetail; + + IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} + ~IntermediateValues(); + + void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); + + void debugWrite(FILE* file, const rcHeightfield* mesh); + void debugWrite(FILE* file, const rcCompactHeightfield* chf); + void debugWrite(FILE* file, const rcContourSet* cs); + void debugWrite(FILE* file, const rcPolyMesh* mesh); + void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); + + void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + }; +} +#endif diff --git a/src/tools/mmap_extractor/MapBuilder.cpp b/src/tools/mmap_extractor/MapBuilder.cpp new file mode 100644 index 00000000000..3ca158f0127 --- /dev/null +++ b/src/tools/mmap_extractor/MapBuilder.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "MapTree.h" +#include "ModelInstance.h" +#include "LoginDatabase.h" + +#include "DetourNavMeshBuilder.h" +#include "DetourCommon.h" + +// These make the linker happy. +LoginDatabaseWorkerPool LoginDatabase; +#include "DisableMgr.h" +namespace DisableMgr +{ + bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + { + return 0; + } +} + +using namespace VMAP; + +namespace MMAP +{ + MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, + bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, + bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : + m_terrainBuilder(NULL), + m_debugOutput (debugOutput), + m_skipContinents (skipContinents), + m_skipJunkMaps (skipJunkMaps), + m_skipBattlegrounds (skipBattlegrounds), + m_maxWalkableAngle (maxWalkableAngle), + m_bigBaseUnit (bigBaseUnit), + m_rcContext (NULL), + m_offMeshFilePath (offMeshFilePath) + { + m_terrainBuilder = new TerrainBuilder(skipLiquid); + + m_rcContext = new rcContext(false); + + discoverTiles(); + } + + /**************************************************************************/ + MapBuilder::~MapBuilder() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + (*it).second->clear(); + delete (*it).second; + } + + delete m_terrainBuilder; + delete m_rcContext; + } + + /**************************************************************************/ + void MapBuilder::discoverTiles() + { + vector files; + uint32 mapID, tileX, tileY, tileID, count = 0; + char filter[12]; + + printf("Discovering maps... "); + getDirContents(files, "maps"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + if (m_tiles.find(mapID) == m_tiles.end()) + { + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + } + + files.clear(); + getDirContents(files, "vmaps", "*.vmtree"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + printf("found %u.\n", count); + + count = 0; + printf("Discovering tiles... "); + for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) + { + set* tiles = (*itr).second; + mapID = (*itr).first; + + sprintf(filter, "%03u*.vmtile", mapID); + files.clear(); + getDirContents(files, "vmaps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileX = uint32(atoi(files[i].substr(7,2).c_str())); + tileY = uint32(atoi(files[i].substr(4,2).c_str())); + tileID = StaticMapTree::packTileID(tileY, tileX); + + tiles->insert(tileID); + count++; + } + + sprintf(filter, "%03u*", mapID); + files.clear(); + getDirContents(files, "maps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileY = uint32(atoi(files[i].substr(3,2).c_str())); + tileX = uint32(atoi(files[i].substr(5,2).c_str())); + tileID = StaticMapTree::packTileID(tileX, tileY); + + if (tiles->insert(tileID).second) + count++; + } + } + printf("found %u.\n\n", count); + } + + /**************************************************************************/ + set* MapBuilder::getTileList(uint32 mapID) + { + TileList::iterator itr = m_tiles.find(mapID); + if (itr != m_tiles.end()) + return (*itr).second; + + set* tiles = new set(); + m_tiles.insert(pair*>(mapID, tiles)); + return tiles; + } + + /**************************************************************************/ + void MapBuilder::buildAllMaps() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + uint32 mapID = (*it).first; + if (!shouldSkipMap(mapID)) + buildMap(mapID); + } + } + + /**************************************************************************/ + void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) + { + maxX = INT_MAX; + maxY = INT_MAX; + minX = INT_MIN; + minY = INT_MIN; + + float bmin[3], bmax[3], lmin[3], lmax[3]; + MeshData meshData; + + // make sure we process maps which don't have tiles + // initialize the static tree, which loads WDT models + if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() && meshData.liquidVerts.size()) + { + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + rcVmin(bmin, lmin); + rcVmax(bmax, lmax); + } + else if (meshData.solidVerts.size()) + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + else + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + + // convert coord bounds to grid bounds + maxX = 32 - bmin[0] / GRID_SIZE; + maxY = 32 - bmin[2] / GRID_SIZE; + minX = 32 - bmax[0] / GRID_SIZE; + minY = 32 - bmax[2] / GRID_SIZE; + } + + /**************************************************************************/ + void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + buildTile(mapID, tileX, tileY, navMesh); + dtFreeNavMesh(navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildMap(uint32 mapID) + { + printf("Building map %03u:\n", mapID); + + set* tiles = getTileList(mapID); + + // make sure we process maps which don't have tiles + if (!tiles->size()) + { + // convert coord bounds to grid bounds + uint32 minX, minY, maxX, maxY; + getGridBounds(mapID, minX, minY, maxX, maxY); + + // add all tiles within bounds to tile list. + for (uint32 i = minX; i <= maxX; ++i) + for (uint32 j = minY; j <= maxY; ++j) + tiles->insert(StaticMapTree::packTileID(i, j)); + } + + if (!tiles->size()) + return; + + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + // now start building mmtiles for each tile + printf("We have %u tiles. \n", (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; + + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (shouldSkipTile(mapID, tileX, tileY)) + continue; + + buildTile(mapID, tileX, tileY, navMesh); + } + + dtFreeNavMesh(navMesh); + + printf("Complete! \n\n"); + } + + /**************************************************************************/ + void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) + { + printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + + MeshData meshData; + + // get heightmap data + m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); + + // get model data + m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); + + // if there is no data, give up now + if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + return; + + // remove unused vertices + TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); + TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); + + // gather all mesh data for final data check, and bounds calculation + G3D::Array allVerts; + allVerts.append(meshData.liquidVerts); + allVerts.append(meshData.solidVerts); + + if (!allVerts.size()) + return; + + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + + m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); + + // build navmesh tile + buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) + { + set* tiles = getTileList(mapID); + + // old code for non-statically assigned bitmask sizes: + ///*** calculate number of bits needed to store tiles & polys ***/ + //int tileBits = dtIlog2(dtNextPow2(tiles->size())); + //if (tileBits < 1) tileBits = 1; // need at least one bit! + //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; + + int tileBits = STATIC_TILE_BITS; + int polyBits = STATIC_POLY_BITS; + + int maxTiles = tiles->size(); + int maxPolysPerTile = 1 << polyBits; + + /*** calculate bounds of map ***/ + + uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (tileX > tileXMax) + tileXMax = tileX; + else if (tileX < tileXMin) + tileXMin = tileX; + + if (tileY > tileYMax) + tileYMax = tileY; + else if (tileY < tileYMin) + tileYMin = tileY; + } + + // use Max because '32 - tileX' is negative for values over 32 + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + + /*** now create the navmesh ***/ + + // navmesh creation params + dtNavMeshParams navMeshParams; + memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); + navMeshParams.tileWidth = GRID_SIZE; + navMeshParams.tileHeight = GRID_SIZE; + rcVcopy(navMeshParams.orig, bmin); + navMeshParams.maxTiles = maxTiles; + navMeshParams.maxPolys = maxPolysPerTile; + + navMesh = dtAllocNavMesh(); + printf("Creating navMesh... \r"); + if (!navMesh->init(&navMeshParams)) + { + printf("Failed creating navmesh! \n"); + return; + } + + char fileName[25]; + sprintf(fileName, "mmaps/%03u.mmap", mapID); + + FILE* file = fopen(fileName, "wb"); + if (!file) + { + dtFreeNavMesh(navMesh); + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + return; + } + + // now that we know navMesh params are valid, we can write them to file + fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); + fclose(file); + } + + /**************************************************************************/ + void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, + MeshData &meshData, float bmin[3], float bmax[3], + dtNavMesh* navMesh) + { + // console output + char tileString[10]; + sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); + printf("%s Building movemap tiles... \r", tileString); + + IntermediateValues iv; + + float* tVerts = meshData.solidVerts.getCArray(); + int tVertCount = meshData.solidVerts.size() / 3; + int* tTris = meshData.solidTris.getCArray(); + int tTriCount = meshData.solidTris.size() / 3; + + float* lVerts = meshData.liquidVerts.getCArray(); + int lVertCount = meshData.liquidVerts.size() / 3; + int* lTris = meshData.liquidTris.getCArray(); + int lTriCount = meshData.liquidTris.size() / 3; + uint8* lTriFlags = meshData.liquidType.getCArray(); + + // these are WORLD UNIT based metrics + // this are basic unit dimentions + // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) + const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; + + // All are in UNIT metrics! + const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); + const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP + const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; + + rcConfig config; + memset(&config, 0, sizeof(rcConfig)); + + rcVcopy(config.bmin, bmin); + rcVcopy(config.bmax, bmax); + + config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + config.cs = BASE_UNIT_DIM; + config.ch = BASE_UNIT_DIM; + config.walkableSlopeAngle = m_maxWalkableAngle; + config.tileSize = VERTEX_PER_TILE; + config.walkableRadius = m_bigBaseUnit ? 1 : 2; + config.borderSize = config.walkableRadius + 3; + config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize + config.walkableHeight = m_bigBaseUnit ? 3 : 6; + config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight + config.minRegionArea = rcSqr(60); + config.mergeRegionArea = rcSqr(50); + config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + config.detailSampleDist = config.cs * 64; + config.detailSampleMaxError = config.ch * 2; + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + + // allocate subregions : tiles + Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; + + // Initialize per tile config. + rcConfig tileCfg; + memcpy(&tileCfg, &config, sizeof(rcConfig)); + tileCfg.width = config.tileSize + config.borderSize*2; + tileCfg.height = config.tileSize + config.borderSize*2; + + // build all tiles + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + + // Calculate the per tile bounding box. + tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + + float tbmin[2], tbmax[2]; + tbmin[0] = tileCfg.bmin[0]; + tbmin[1] = tileCfg.bmin[2]; + tbmax[0] = tileCfg.bmax[0]; + tbmax[1] = tileCfg.bmax[2]; + + // build heightfield + tile.solid = rcAllocHeightfield(); + if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) + { + printf("%sFailed building heightfield! \n", tileString); + continue; + } + + // mark all walkable tiles, both liquids and solids + unsigned char* triFlags = new unsigned char[tTriCount]; + memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); + rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); + rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); + delete [] triFlags; + + rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); + rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); + rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); + + rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); + + // compact heightfield spans + tile.chf = rcAllocCompactHeightfield(); + if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) + { + printf("%sFailed compacting heightfield! \n", tileString); + continue; + } + + // build polymesh intermediates + if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) + { + printf("%sFailed eroding area! \n", tileString); + continue; + } + + if (!rcBuildDistanceField(m_rcContext, *tile.chf)) + { + printf("%sFailed building distance field! \n", tileString); + continue; + } + + if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) + { + printf("%sFailed building regions! \n", tileString); + continue; + } + + tile.cset = rcAllocContourSet(); + if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) + { + printf("%sFailed building contours! \n", tileString); + continue; + } + + // build polymesh + tile.pmesh = rcAllocPolyMesh(); + if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) + { + printf("%sFailed building polymesh! \n", tileString); + continue; + } + + tile.dmesh = rcAllocPolyMeshDetail(); + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + { + printf("%sFailed building polymesh detail! \n", tileString); + continue; + } + + // free those up + // we may want to keep them in the future for debug + // but right now, we don't have the code to merge them + rcFreeHeightField(tile.solid); + tile.solid = NULL; + rcFreeCompactHeightfield(tile.chf); + tile.chf = NULL; + rcFreeContourSet(tile.cset); + tile.cset = NULL; + } + } + + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) + { + pmmerge[nmerge] = tile.pmesh; + dmmerge[nmerge] = tile.dmesh; + nmerge++; + } + } + } + + iv.polyMesh = rcAllocPolyMesh(); + if (!iv.polyMesh) + { + printf("%s alloc iv.polyMesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); + + iv.polyMeshDetail = rcAllocPolyMeshDetail(); + if (!iv.polyMeshDetail) + { + printf("%s alloc m_dmesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); + + // free things up + delete [] pmmerge; + delete [] dmmerge; + + delete [] tiles; + + // remove padding for extraction + for (int i = 0; i < iv.polyMesh->nverts; ++i) + { + unsigned short* v = &iv.polyMesh->verts[i*3]; + v[0] -= (unsigned short)config.borderSize; + v[2] -= (unsigned short)config.borderSize; + } + + // set polygons as walkable + // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off + for (int i = 0; i < iv.polyMesh->npolys; ++i) + if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) + iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; + + // setup mesh parameters + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + params.verts = iv.polyMesh->verts; + params.vertCount = iv.polyMesh->nverts; + params.polys = iv.polyMesh->polys; + params.polyAreas = iv.polyMesh->areas; + params.polyFlags = iv.polyMesh->flags; + params.polyCount = iv.polyMesh->npolys; + params.nvp = iv.polyMesh->nvp; + params.detailMeshes = iv.polyMeshDetail->meshes; + params.detailVerts = iv.polyMeshDetail->verts; + params.detailVertsCount = iv.polyMeshDetail->nverts; + params.detailTris = iv.polyMeshDetail->tris; + params.detailTriCount = iv.polyMeshDetail->ntris; + + params.offMeshConVerts = meshData.offMeshConnections.getCArray(); + params.offMeshConCount = meshData.offMeshConnections.size()/6; + params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); + params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); + params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); + params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); + + params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height + params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius + params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! + params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; + params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; + rcVcopy(params.bmin, bmin); + rcVcopy(params.bmax, bmax); + params.cs = config.cs; + params.ch = config.ch; + params.tileSize = VERTEX_PER_MAP; + + // will hold final navmesh + unsigned char* navData = NULL; + int navDataSize = 0; + + do + { + // these values are checked within dtCreateNavMeshData - handle them here + // so we have a clear error message + if (params.nvp > DT_VERTS_PER_POLYGON) + { + printf("%s Invalid verts-per-polygon value! \n", tileString); + continue; + } + if (params.vertCount >= 0xffff) + { + printf("%s Too many vertices! \n", tileString); + continue; + } + if (!params.vertCount || !params.verts) + { + // occurs mostly when adjacent tiles have models + // loaded but those models don't span into this tile + + // message is an annoyance + //printf("%sNo vertices to build tile! \n", tileString); + continue; + } + if (!params.polyCount || !params.polys || + TILES_PER_MAP*TILES_PER_MAP == params.polyCount) + { + // we have flat tiles with no actual geometry - don't build those, its useless + // keep in mind that we do output those into debug info + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("%s No polygons to build on tile! \n", tileString); + continue; + } + if (!params.detailMeshes || !params.detailVerts || !params.detailTris) + { + printf("%s No detail mesh to build tile! \n", tileString); + continue; + } + + printf("%s Building navmesh tile... \r", tileString); + if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) + { + printf("%s Failed building navmesh tile! \n", tileString); + continue; + } + + dtTileRef tileRef = 0; + printf("%s Adding tile to navmesh... \r", tileString); + // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile + // is removed via removeTile() + dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef); + if (!tileRef || dtResult != DT_SUCCESS) + { + printf("%s Failed adding tile to navmesh! \n", tileString); + continue; + } + + // file output + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "wb"); + if (!file) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + navMesh->removeTile(tileRef, NULL, NULL); + continue; + } + + printf("%s Writing to file... \r", tileString); + + // write header + MmapTileHeader header; + header.usesLiquids = m_terrainBuilder->usesLiquids(); + header.size = uint32(navDataSize); + fwrite(&header, sizeof(MmapTileHeader), 1, file); + + // write data + fwrite(navData, sizeof(unsigned char), navDataSize, file); + fclose(file); + + // now that tile is written to disk, we can unload it + navMesh->removeTile(tileRef, NULL, NULL); + } + while (0); + + if (m_debugOutput) + { + // restore padding so that the debug visualization is correct + for (int i = 0; i < iv.polyMesh->nverts; ++i) + { + unsigned short* v = &iv.polyMesh->verts[i*3]; + v[0] += (unsigned short)config.borderSize; + v[2] += (unsigned short)config.borderSize; + } + + iv.generateObjFile(mapID, tileX, tileY, meshData); + iv.writeIV(mapID, tileX, tileY); + } + } + + /**************************************************************************/ + void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) + { + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * GRID_SIZE; + bmax[2] = (32 - int(tileY)) * GRID_SIZE; + bmin[0] = bmax[0] - GRID_SIZE; + bmin[2] = bmax[2] - GRID_SIZE; + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipMap(uint32 mapID) + { + if (m_skipContinents) + switch (mapID) + { + case 0: + case 1: + case 530: + case 571: + return true; + default: + break; + } + + if (m_skipJunkMaps) + switch (mapID) + { + case 13: // test.wdt + case 25: // ScottTest.wdt + case 29: // Test.wdt + case 42: // Colin.wdt + case 169: // EmeraldDream.wdt (unused, and very large) + case 451: // development.wdt + case 573: // ExteriorTest.wdt + case 597: // CraigTest.wdt + case 605: // development_nonweighted.wdt + case 606: // QA_DVD.wdt + return true; + default: + if (isTransportMap(mapID)) + return true; + break; + } + + if (m_skipBattlegrounds) + switch (mapID) + { + case 30: // AV + case 37: // ? + case 489: // WSG + case 529: // AB + case 566: // EotS + case 607: // SotA + case 628: // IoC + return true; + default: + break; + } + + return false; + } + + /**************************************************************************/ + bool MapBuilder::isTransportMap(uint32 mapID) + { + switch (mapID) + { + // transport maps + case 582: + case 584: + case 586: + case 587: + case 588: + case 589: + case 590: + case 591: + case 592: + case 593: + case 594: + case 596: + case 610: + case 612: + case 613: + case 614: + case 620: + case 621: + case 622: + case 623: + case 641: + case 642: + case 647: + case 672: + case 673: + case 712: + case 713: + case 718: + return true; + default: + return false; + } + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "rb"); + if (!file) + return false; + + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, file); + fclose(file); + + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + return false; + + if (header.mmapVersion != MMAP_VERSION) + return false; + + return true; + } + +} diff --git a/src/tools/mmap_extractor/MapBuilder.h b/src/tools/mmap_extractor/MapBuilder.h new file mode 100644 index 00000000000..d0f33ce9a79 --- /dev/null +++ b/src/tools/mmap_extractor/MapBuilder.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MAP_BUILDER_H +#define _MAP_BUILDER_H + +#include +#include +#include + +#include "TerrainBuilder.h" +#include "IntermediateValues.h" + +#include "IVMapManager.h" +#include "WorldModel.h" + +#include "Recast.h" +#include "DetourNavMesh.h" + +using namespace std; +using namespace VMAP; + +// G3D namespace typedefs conflicts with ACE typedefs + +namespace MMAP +{ + typedef map*> TileList; + struct Tile + { + Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} + ~Tile() + { + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + rcFreeHeightField(solid); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + } + rcCompactHeightfield* chf; + rcHeightfield* solid; + rcContourSet* cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + }; + + class MapBuilder + { + public: + MapBuilder(float maxWalkableAngle = 60.f, + bool skipLiquid = false, + bool skipContinents = false, + bool skipJunkMaps = true, + bool skipBattlegrounds = false, + bool debugOutput = false, + bool bigBaseUnit = false, + const char* offMeshFilePath = NULL); + + ~MapBuilder(); + + // builds all mmap tiles for the specified map id (ignores skip settings) + void buildMap(uint32 mapID); + + // builds an mmap tile for the specified map and its mesh + void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); + + // builds list of maps, then builds all of mmap tiles (based on the skip settings) + void buildAllMaps(); + + private: + // detect maps and tiles + void discoverTiles(); + set* getTileList(uint32 mapID); + + void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); + + void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); + + // move map building + void buildMoveMapTile(uint32 mapID, + uint32 tileX, + uint32 tileY, + MeshData &meshData, + float bmin[3], + float bmax[3], + dtNavMesh* navMesh); + + void getTileBounds(uint32 tileX, uint32 tileY, + float* verts, int vertCount, + float* bmin, float* bmax); + void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); + + bool shouldSkipMap(uint32 mapID); + bool isTransportMap(uint32 mapID); + bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); + + TerrainBuilder* m_terrainBuilder; + TileList m_tiles; + + bool m_debugOutput; + + const char* m_offMeshFilePath; + bool m_skipContinents; + bool m_skipJunkMaps; + bool m_skipBattlegrounds; + + float m_maxWalkableAngle; + bool m_bigBaseUnit; + + // build performance - not really used for now + rcContext* m_rcContext; + }; +} + +#endif diff --git a/src/tools/mmap_extractor/PathCommon.h b/src/tools/mmap_extractor/PathCommon.h new file mode 100644 index 00000000000..fd02ec02d50 --- /dev/null +++ b/src/tools/mmap_extractor/PathCommon.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MMAP_COMMON_H +#define _MMAP_COMMON_H + +#include +#include + +#include "Define.h" + +#ifndef _WIN32 + #include + #include +#endif + +#ifdef __linux__ + #include +#endif + +using namespace std; + +namespace MMAP +{ + inline bool matchWildcardFilter(const char* filter, const char* str) + { + if (!filter || !str) + return false; + + // end on null character + while (*filter && *str) + { + if (*filter == '*') + { + if (*++filter == '\0') // wildcard at end of filter means all remaing chars match + return true; + + while (true) + { + if (*filter == *str) + break; + if (*str == '\0') + return false; // reached end of string without matching next filter character + str++; + } + } + else if (*filter != *str) + return false; // mismatch + + filter++; + str++; + } + + return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); + } + + enum ListFilesResult + { + LISTFILE_DIRECTORY_NOT_FOUND = 0, + LISTFILE_OK = 1 + }; + + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + { + #ifdef WIN32 + HANDLE hFind; + WIN32_FIND_DATA findFileInfo; + string directory; + + directory = dirpath + "/" + filter; + + hFind = FindFirstFile(directory.c_str(), &findFileInfo); + + if (hFind == INVALID_HANDLE_VALUE) + return LISTFILE_DIRECTORY_NOT_FOUND; + do + { + if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + fileList.push_back(string(findFileInfo.cFileName)); + } + while (FindNextFile(hFind, &findFileInfo)); + + FindClose(hFind); + + #else + const char *p = dirpath.c_str(); + DIR * dirp = opendir(p); + struct dirent * dp; + dirp = opendir(p); + + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + if (matchWildcardFilter(filter.c_str(), dp->d_name)) + fileList.push_back(string(dp->d_name)); + } + else + break; + } + + if (dirp) + closedir(dirp); + else + return LISTFILE_DIRECTORY_NOT_FOUND; + #endif + + return LISTFILE_OK; + } +} + +#endif diff --git a/src/tools/mmap_extractor/PathGenerator.cpp b/src/tools/mmap_extractor/PathGenerator.cpp new file mode 100644 index 00000000000..2eb2c6545c4 --- /dev/null +++ b/src/tools/mmap_extractor/PathGenerator.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2011 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 "PathCommon.h" +#include "MapBuilder.h" + +using namespace MMAP; + +bool checkDirectories(bool debugOutput) +{ + vector dirFiles; + + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'maps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'vmaps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'mmaps' directory does not exist\n"); + return false; + } + + dirFiles.clear(); + if (debugOutput) + { + if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); + return false; + } + } + + return true; +} + +bool handleArgs(int argc, char** argv, + int &mapnum, + int &tileX, + int &tileY, + float &maxAngle, + bool &skipLiquid, + bool &skipContinents, + bool &skipJunkMaps, + bool &skipBattlegrounds, + bool &debugOutput, + bool &silent, + bool &bigBaseUnit, + char* &offMeshInputPath) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--maxAngle") == 0) + { + param = argv[++i]; + if (!param) + return false; + + float maxangle = atof(param); + if (maxangle <= 90.f && maxangle >= 45.f) + maxAngle = maxangle; + else + printf("invalid option for '--maxAngle', using default\n"); + } + else if (strcmp(argv[i], "--tile") == 0) + { + param = argv[++i]; + if (!param) + return false; + + char* stileX = strtok(param, ","); + char* stileY = strtok(NULL, ","); + int tilex = atoi(stileX); + int tiley = atoi(stileY); + + if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) + tileX = tilex; + if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) + tileY = tiley; + + if (tileX < 0 || tileY < 0) + { + printf("invalid tile coords.\n"); + return false; + } + } + else if (strcmp(argv[i], "--skipLiquid") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipLiquid = true; + else if (strcmp(param, "false") == 0) + skipLiquid = false; + else + printf("invalid option for '--skipLiquid', using default\n"); + } + else if (strcmp(argv[i], "--skipContinents") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipContinents = true; + else if (strcmp(param, "false") == 0) + skipContinents = false; + else + printf("invalid option for '--skipContinents', using default\n"); + } + else if (strcmp(argv[i], "--skipJunkMaps") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipJunkMaps = true; + else if (strcmp(param, "false") == 0) + skipJunkMaps = false; + else + printf("invalid option for '--skipJunkMaps', using default\n"); + } + else if (strcmp(argv[i], "--skipBattlegrounds") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipBattlegrounds = true; + else if (strcmp(param, "false") == 0) + skipBattlegrounds = false; + else + printf("invalid option for '--skipBattlegrounds', using default\n"); + } + else if (strcmp(argv[i], "--debugOutput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + debugOutput = true; + else if (strcmp(param, "false") == 0) + debugOutput = false; + else + printf("invalid option for '--debugOutput', using default true\n"); + } + else if (strcmp(argv[i], "--silent") == 0) + { + silent = true; + } + else if (strcmp(argv[i], "--bigBaseUnit") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + bigBaseUnit = true; + else if (strcmp(param, "false") == 0) + bigBaseUnit = false; + else + printf("invalid option for '--bigBaseUnit', using default false\n"); + } + else if (strcmp(argv[i], "--offMeshInput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + offMeshInputPath = param; + } + else + { + int map = atoi(argv[i]); + if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) + mapnum = map; + else + { + printf("invalid map id\n"); + return false; + } + } + } + + return true; +} + +int finish(const char* message, int returnValue) +{ + printf("%s", message); + getchar(); + return returnValue; +} + +int main(int argc, char** argv) +{ + int mapnum = -1; + float maxAngle = 60.0f; + int tileX = -1, tileY = -1; + bool skipLiquid = false, + skipContinents = false, + skipJunkMaps = true, + skipBattlegrounds = false, + debugOutput = false, + silent = false, + bigBaseUnit = false; + char* offMeshInputPath = NULL; + + bool validParam = handleArgs(argc, argv, mapnum, + tileX, tileY, maxAngle, + skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, + debugOutput, silent, bigBaseUnit, offMeshInputPath); + + if (!validParam) + return silent ? -1 : finish("You have specified invalid parameters", -1); + + if (mapnum == -1 && debugOutput) + { + if (silent) + return -2; + + printf("You have specifed debug output, but didn't specify a map to generate.\n"); + printf("This will generate debug output for ALL maps.\n"); + printf("Are you sure you want to continue? (y/n) "); + if (getchar() != 'y') + return 0; + } + + if (!checkDirectories(debugOutput)) + return silent ? -3 : finish("Press any key to close...", -3); + + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, + skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + + if (tileX > -1 && tileY > -1 && mapnum >= 0) + builder.buildSingleTile(mapnum, tileX, tileY); + else if (mapnum >= 0) + builder.buildMap(uint32(mapnum)); + else + builder.buildAllMaps(); + + return silent ? 1 : finish("Movemap build is complete!", 1); +} diff --git a/src/tools/mmap_extractor/TerrainBuilder.cpp b/src/tools/mmap_extractor/TerrainBuilder.cpp new file mode 100644 index 00000000000..c696f6017a5 --- /dev/null +++ b/src/tools/mmap_extractor/TerrainBuilder.cpp @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "TerrainBuilder.h" + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "VMapManager2.h" +#include "MapTree.h" +#include "ModelInstance.h" + +namespace MMAP +{ + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } + TerrainBuilder::~TerrainBuilder() { } + + /**************************************************************************/ + void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) + { + switch (portion) + { + case ENTIRE: + loopStart = 0; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + case TOP: + loopStart = 0; + loopEnd = V8_SIZE; + loopInc = 1; + break; + case LEFT: + loopStart = 0; + loopEnd = V8_SIZE_SQ - V8_SIZE + 1; + loopInc = V8_SIZE; + break; + case RIGHT: + loopStart = V8_SIZE - 1; + loopEnd = V8_SIZE_SQ; + loopInc = V8_SIZE; + break; + case BOTTOM: + loopStart = V8_SIZE_SQ - V8_SIZE; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) + { + loadMap(mapID, tileX+1, tileY, meshData, LEFT); + loadMap(mapID, tileX-1, tileY, meshData, RIGHT); + loadMap(mapID, tileX, tileY+1, meshData, TOP); + loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); + } + } + + /**************************************************************************/ + bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) + { + char mapFileName[255]; + sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + + FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + return false; + + map_fileheader fheader; + fread(&fheader, sizeof(map_fileheader), 1, mapFile); + + if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + { + fclose(mapFile); + printf("%s is the wrong version, please extract new .map files\n", mapFileName); + return false; + } + + map_heightHeader hheader; + fseek(mapFile, fheader.heightMapOffset, SEEK_SET); + fread(&hheader, sizeof(map_heightHeader), 1, mapFile); + + bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + + // no data in this map file + if (!haveTerrain && !haveLiquid) + { + fclose(mapFile); + return false; + } + + // data used later + uint16 holes[16][16]; + memset(holes, 0, sizeof(holes)); + uint8 liquid_type[16][16]; + memset(liquid_type, 0, sizeof(liquid_type)); + G3D::Array ltriangles; + G3D::Array ttriangles; + + // terrain data + if (haveTerrain) + { + int i; + float heightMultiplier; + float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + + if (hheader.flags & MAP_HEIGHT_AS_INT8) + { + uint8 v9[V9_SIZE_SQ]; + uint8 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else if (hheader.flags & MAP_HEIGHT_AS_INT16) + { + uint16 v9[V9_SIZE_SQ]; + uint16 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else + { + fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); + fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + } + + // hole data + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + + int count = meshData.solidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + + for (i = 0; i < V9_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + for (i = 0; i < V8_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + int j, indices[3], loopStart, loopEnd, loopInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (i = loopStart; i < loopEnd; i+=loopInc) + for (j = TOP; j <= BOTTOM; j+=1) + { + getHeightTriangle(i, Spot(j), indices); + ttriangles.append(indices[2] + count); + ttriangles.append(indices[1] + count); + ttriangles.append(indices[0] + count); + } + } + + // liquid data + if (haveLiquid) + { + map_liquidHeader lheader; + fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); + fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + + float* liquid_map = NULL; + + if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) + fread(liquid_type, sizeof(liquid_type), 1, mapFile); + + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + liquid_map = new float [lheader.width*lheader.height]; + fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + } + + if (liquid_type && liquid_map) + { + int count = meshData.liquidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + int row, col; + + // generate coordinates + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + int j = 0; + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + + if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || + col < lheader.offsetX || col >= lheader.offsetX + lheader.width) + { + // dummy vert using invalid height + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); + continue; + } + + getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); + meshData.liquidVerts.append(coord[0]); + meshData.liquidVerts.append(coord[2]); + meshData.liquidVerts.append(coord[1]); + j++; + } + } + else + { + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); + } + } + + delete [] liquid_map; + + int indices[3], loopStart, loopEnd, loopInc, triInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + triInc = BOTTOM-TOP; + + // generate triangles + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+= triInc) + { + getHeightTriangle(i, Spot(j), indices, true); + ltriangles.append(indices[2] + count); + ltriangles.append(indices[1] + count); + ltriangles.append(indices[0] + count); + } + } + } + + fclose(mapFile); + + // now that we have gathered the data, we can figure out which parts to keep: + // liquid above ground, ground above liquid + int loopStart, loopEnd, loopInc, tTriCount = 4; + bool useTerrain, useLiquid; + + float* lverts = meshData.liquidVerts.getCArray(); + int* ltris = ltriangles.getCArray(); + + float* tverts = meshData.solidVerts.getCArray(); + int* ttris = ttriangles.getCArray(); + + if (ltriangles.size() + ttriangles.size() == 0) + return false; + + // make a copy of liquid vertices + // used to pad right-bottom frame due to lost vertex data at extraction + float* lverts_copy = NULL; + if (meshData.liquidVerts.size()) + { + lverts_copy = new float[meshData.liquidVerts.size()]; + memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); + } + + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (int i = loopStart; i < loopEnd; i+=loopInc) + { + for (int j = 0; j < 2; ++j) + { + // default is true, will change to false if needed + useTerrain = true; + useLiquid = true; + uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + + // if there is no liquid, don't use liquid + if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + useLiquid = false; + else + { + liquidType = getLiquidType(i, liquid_type); + switch (liquidType) + { + default: + useLiquid = false; + break; + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + // merge different types of water + liquidType = NAV_WATER; + break; + case MAP_LIQUID_TYPE_MAGMA: + liquidType = NAV_MAGMA; + break; + case MAP_LIQUID_TYPE_SLIME: + liquidType = NAV_SLIME; + break; + case MAP_LIQUID_TYPE_DARK_WATER: + // players should not be here, so logically neither should creatures + useTerrain = false; + useLiquid = false; + break; + } + } + + // if there is no terrain, don't use terrain + if (!ttriangles.size()) + useTerrain = false; + + // while extracting ADT data we are losing right-bottom vertices + // this code adds fair approximation of lost data + if (useLiquid) + { + float quadHeight = 0; + uint32 validCount = 0; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts_copy[ltris[idx]*3 + 1]; + if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) + { + quadHeight += h; + validCount++; + } + } + + // update vertex height data + if (validCount > 0 && validCount < 3) + { + quadHeight /= validCount; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts[ltris[idx]*3 + 1]; + if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) + lverts[ltris[idx]*3 + 1] = quadHeight; + } + } + + // no valid vertexes - don't use this poly at all + if (validCount == 0) + useLiquid = false; + } + + // if there is a hole here, don't use the terrain + if (useTerrain) + useTerrain = !isHole(i, holes); + + // we use only one terrain kind per quad - pick higher one + if (useTerrain && useLiquid) + { + float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + float maxLLevel = INVALID_MAP_LIQ_HEIGHT; + for(uint32 x = 0; x < 3; x++) + { + float h = lverts[ltris[x]*3 + 1]; + if (minLLevel > h) + minLLevel = h; + + if (maxLLevel < h) + maxLLevel = h; + } + + float maxTLevel = INVALID_MAP_LIQ_HEIGHT; + float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + for(uint32 x = 0; x < 6; x++) + { + float h = tverts[ttris[x]*3 + 1]; + if (maxTLevel < h) + maxTLevel = h; + + if (minTLevel > h) + minTLevel = h; + } + + // terrain under the liquid? + if (minLLevel > maxTLevel) + useTerrain = false; + + //liquid under the terrain? + if (minTLevel > maxLLevel) + useLiquid = false; + } + + // store the result + if (useLiquid) + { + meshData.liquidType.append(liquidType); + for (int k = 0; k < 3; ++k) + meshData.liquidTris.append(ltris[k]); + } + + if (useTerrain) + for (int k = 0; k < 3*tTriCount/2; ++k) + meshData.solidTris.append(ttris[k]); + + // advance to next set of triangles + ltris += 3; + ttris += 3*tTriCount/2; + } + } + + if (lverts_copy) + delete [] lverts_copy; + + return meshData.solidTris.size() || meshData.liquidTris.size(); + } + + /**************************************************************************/ + void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + switch (grid) + { + case GRID_V9: + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index]; + break; + case GRID_V8: + coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[2] = v[index]; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) + { + int rowOffset = square/V8_SIZE; + if (!liquid) + switch (triangle) + { + case TOP: + indices[0] = square+rowOffset; // 0-----1 .... 128 + indices[1] = square+1+rowOffset; // |\ T /| + indices[2] = (V9_SIZE_SQ)+square; // | \ / | + break; // |L 0 R| .. 127 + case LEFT: // | / \ | + indices[0] = square+rowOffset; // |/ B \| + indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 + indices[2] = square+V9_SIZE+rowOffset; // |\ /| + break; // | \ / | + case RIGHT: // | 128 | .. 255 + indices[0] = square+1+rowOffset; // | / \ | + indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| + indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 + break; + case BOTTOM: + indices[0] = (V9_SIZE_SQ)+square; + indices[1] = square+V9_SIZE+1+rowOffset; + indices[2] = square+V9_SIZE+rowOffset; + break; + default: break; + } + else + switch (triangle) + { // 0-----1 .... 128 + case TOP: // |\ | + indices[0] = square+rowOffset; // | \ T | + indices[1] = square+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | + break; // | \| + case BOTTOM: // 129---130 ... 386 + indices[0] = square+rowOffset; // |\ | + indices[1] = square+V9_SIZE+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+rowOffset; // | \ | + break; // | \ | + default: break; // | \| + } // 258---259 ... 515 + + } + + /**************************************************************************/ + void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index2]; + } + + static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; + static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + + /**************************************************************************/ + bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + int holeRow = row % 8 / 2; + int holeCol = (square - (row * 128 + cellCol * 8)) / 2; + + uint16 hole = holes[cellRow][cellCol]; + + return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; + } + + /**************************************************************************/ + uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + + return liquid_type[cellRow][cellCol]; + } + + /**************************************************************************/ + bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + IVMapManager* vmapManager = new VMapManager2(); + int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + bool retval = false; + + do + { + if (result == VMAP_LOAD_RESULT_ERROR) + break; + + InstanceTreeMap instanceTrees; + ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + + if (!instanceTrees[mapID]) + break; + + ModelInstance* models = NULL; + uint32 count = 0; + instanceTrees[mapID]->getModelInstances(models, count); + + if (!models) + break; + + for (uint32 i = 0; i < count; ++i) + { + ModelInstance instance = models[i]; + + // model instances exist in tree even though there are instances of that model in this tile + WorldModel* worldModel = instance.getWorldModel(); + if (!worldModel) + continue; + + // now we have a model to add to the meshdata + retval = true; + + vector groupModels; + worldModel->getGroupModels(groupModels); + + // all M2s need to have triangle indices reversed + bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + + // transform data + float scale = instance.iScale; + G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); + Vector3 position = instance.iPos; + position.x -= 32*GRID_SIZE; + position.y -= 32*GRID_SIZE; + + for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + { + vector tempVertices; + vector transformedVertices; + vector tempTriangles; + WmoLiquid* liquid = NULL; + + (*it).getMeshData(tempVertices, tempTriangles, liquid); + + // first handle collision mesh + transform(tempVertices, transformedVertices, scale, rotation, position); + + int offset = meshData.solidVerts.size() / 3; + + copyVertices(transformedVertices, meshData.solidVerts); + copyIndices(tempTriangles, meshData.solidTris, offset, isM2); + + // now handle liquid data + if (liquid) + { + vector liqVerts; + vector liqTris; + uint32 tilesX, tilesY, vertsX, vertsY; + Vector3 corner; + liquid->getPosInfo(tilesX, tilesY, corner); + vertsX = tilesX + 1; + vertsY = tilesY + 1; + uint8* flags = liquid->GetFlagsStorage(); + float* data = liquid->GetHeightStorage(); + uint8 type = NAV_EMPTY; + + // convert liquid type to NavTerrain + switch (liquid->GetType()) + { + case 0: + case 1: + type = NAV_WATER; + break; + case 2: + type = NAV_MAGMA; + break; + case 3: + type = NAV_SLIME; + break; + } + + // indexing is weird... + // after a lot of trial and error, this is what works: + // vertex = y*vertsX+x + // tile = x*tilesY+y + // flag = y*tilesY+x + + Vector3 vert; + for (uint32 x = 0; x < vertsX; ++x) + for (uint32 y = 0; y < vertsY; ++y) + { + vert = Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); + vert = vert * rotation * scale + position; + vert.x *= -1.f; + vert.y *= -1.f; + liqVerts.push_back(vert); + } + + int idx1, idx2, idx3, idx4; + uint32 square; + for (uint32 x = 0; x < tilesX; ++x) + for (uint32 y = 0; y < tilesY; ++y) + if ((flags[x+y*tilesX] & 0x0f) != 0x0f) + { + square = x * tilesY + y; + idx1 = square+x; + idx2 = square+1+x; + idx3 = square+tilesY+1+1+x; + idx4 = square+tilesY+1+x; + + // top triangle + liqTris.push_back(idx3); + liqTris.push_back(idx2); + liqTris.push_back(idx1); + // bottom triangle + liqTris.push_back(idx4); + liqTris.push_back(idx3); + liqTris.push_back(idx1); + } + + uint32 liqOffset = meshData.liquidVerts.size() / 3; + for (uint32 i = 0; i < liqVerts.size(); ++i) + meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); + + for (uint32 i = 0; i < liqTris.size() / 3; ++i) + { + meshData.liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset); + meshData.liquidType.append(type); + } + } + } + } + } + while (false); + + vmapManager->unloadMap(mapID, tileX, tileY); + delete vmapManager; + + return retval; + } + + /**************************************************************************/ + void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + // apply tranform, then mirror along the horizontal axes + Vector3 v((*it) * rotation * scale + position); + v.x *= -1.f; + v.y *= -1.f; + transformedVertices.push_back(v); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).y); + dest.push_back((*it).z); + dest.push_back((*it).x); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + { + if (flip) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx2+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx0+offset); + } + } + else + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx0+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx2+offset); + } + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) + { + int* src = source.getCArray(); + for (int32 i = 0; i < source.size(); ++i) + dest.append(src[i] + offset); + } + + /**************************************************************************/ + void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) + { + map vertMap; + + int* t = tris.getCArray(); + float* v = verts.getCArray(); + + // collect all the vertex indices from triangle + for (int i = 0; i < tris.size(); ++i) + { + if (vertMap.find(t[i]) != vertMap.end()) + continue; + + vertMap.insert(std::pair(t[i], 0)); + } + + // collect the vertices + G3D::Array cleanVerts; + int index, count = 0; + for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) + { + index = (*it).first; + (*it).second = count; + cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + count++; + } + verts.fastClear(); + verts.append(cleanVerts); + cleanVerts.clear(); + + // update triangles to use new indices + for (int i = 0; i < tris.size(); ++i) + { + map::iterator it; + if ((it = vertMap.find(t[i])) == vertMap.end()) + continue; + + t[i] = (*it).second; + } + + vertMap.clear(); + } + + /**************************************************************************/ + void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) + { + // no meshfile input given? + if (offMeshFilePath == NULL) + return; + + FILE* fp = fopen(offMeshFilePath, "rb"); + if (!fp) + { + printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); + return; + } + + // pretty silly thing, as we parse entire file and load only the tile we need + // but we don't expect this file to be too large + char* buf = new char[512]; + while(fgets(buf, 512, fp)) + { + float p0[3], p1[3]; + int mid, tx, ty; + float size; + if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + continue; + + if (mapID == mid, tileX == tx, tileY == ty) + { + meshData.offMeshConnections.append(p0[1]); + meshData.offMeshConnections.append(p0[2]); + meshData.offMeshConnections.append(p0[0]); + + meshData.offMeshConnections.append(p1[1]); + meshData.offMeshConnections.append(p1[2]); + meshData.offMeshConnections.append(p1[0]); + + meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided + meshData.offMeshConnectionRads.append(size); // agent size equivalent + // can be used same way as polygon flags + meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); + meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path + } + + } + + delete [] buf; + fclose(fp); + } +} diff --git a/src/tools/mmap_extractor/TerrainBuilder.h b/src/tools/mmap_extractor/TerrainBuilder.h new file mode 100644 index 00000000000..a7f21883af2 --- /dev/null +++ b/src/tools/mmap_extractor/TerrainBuilder.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MMAP_TERRAIN_BUILDER_H +#define _MMAP_TERRAIN_BUILDER_H + +#include "PathCommon.h" +#include "Map.h" +#include "SharedDefines.h" + +#include "WorldModel.h" + +#include "G3D/Array.h" +#include "G3D/Vector3.h" +#include "G3D/Matrix3.h" + +using namespace Trinity; + +namespace MMAP +{ + enum Spot + { + TOP = 1, + RIGHT = 2, + LEFT = 3, + BOTTOM = 4, + ENTIRE = 5 + }; + + enum Grid + { + GRID_V8, + GRID_V9 + }; + + static const int V9_SIZE = 129; + static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; + static const int V8_SIZE = 128; + static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; + static const float GRID_SIZE = 533.33333f; + static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; + + // see contrib/extractor/system.cpp, CONF_use_minHeight + static const float INVALID_MAP_LIQ_HEIGHT = -500.f; + static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; + + // see following files: + // contrib/extractor/system.cpp + // src/game/Map.cpp + static char const* MAP_VERSION_MAGIC = "v1.2"; + + struct MeshData + { + G3D::Array solidVerts; + G3D::Array solidTris; + + G3D::Array liquidVerts; + G3D::Array liquidTris; + G3D::Array liquidType; + + // offmesh connection data + G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection + G3D::Array offMeshConnectionRads; + G3D::Array offMeshConnectionDirs; + G3D::Array offMeshConnectionsAreas; + G3D::Array offMeshConnectionsFlags; + }; + + class TerrainBuilder + { + public: + TerrainBuilder(bool skipLiquid); + ~TerrainBuilder(); + + void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); + + bool usesLiquids() { return !m_skipLiquid; } + + // vert and triangle methods + static void transform(vector &original, vector &transformed, + float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); + static void copyVertices(vector &source, G3D::Array &dest); + static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); + static void cleanVertices(G3D::Array &verts, G3D::Array &tris); + private: + /// Loads a portion of a map's terrain + bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); + + /// Sets loop variables for selecting only certain parts of a map's terrain + void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); + + /// Controls whether liquids are loaded + bool m_skipLiquid; + + /// Load the map terrain from file + bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); + + /// Get the vector coordinate for a specific position + void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); + + /// Get the triangle's vector indices for a specific position + void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); + + /// Determines if the specific position's triangles should be rendered + bool isHole(int square, const uint16 holes[16][16]); + + /// Get the liquid vector coordinate for a specific position + void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); + + /// Get the liquid type for a specific position + uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); + + // hide parameterless and copy constructor + TerrainBuilder(); + TerrainBuilder(const TerrainBuilder &tb); + }; +} + +#endif + diff --git a/src/tools/mmap_extractor/VMapExtensions.cpp b/src/tools/mmap_extractor/VMapExtensions.cpp new file mode 100644 index 00000000000..4f203e11c21 --- /dev/null +++ b/src/tools/mmap_extractor/VMapExtensions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include +#include "MapTree.h" +#include "VMapManager2.h" +#include "WorldModel.h" +#include "ModelInstance.h" + +using namespace std; + +namespace VMAP +{ + // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator + // maybe add MapBuilder as friend to all of the below classes would be better? + + // declared in src/shared/vmap/MapTree.h + void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) + { + models = iTreeValues; + count = iNTreeValues; + } + + // declared in src/shared/vmap/VMapManager2.h + void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) + { + instanceMapTree = iInstanceMapTrees; + } + + // declared in src/shared/vmap/WorldModel.h + void WorldModel::getGroupModels(vector &groupModels) + { + groupModels = this->groupModels; + } + + // declared in src/shared/vmap/WorldModel.h + void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + { + vertices = this->vertices; + triangles = this->triangles; + liquid = iLiquid; + } + + // declared in src/shared/vmap/ModelInstance.h + WorldModel* const ModelInstance::getWorldModel() + { + return iModel; + } + + // declared in src/shared/vmap/WorldModel.h + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + { + tilesX = iTilesX; + tilesY = iTilesY; + corner = iCorner; + } +} -- cgit v1.2.3 From eae627f75287493ee12744af51112d43a8aaa10b Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 14:51:03 +0200 Subject: Core: + add mmaps files. + add the generator for movement. --- src/server/collision/Management/MMapFactory.cpp | 80 +++ src/server/collision/Management/MMapFactory.h | 51 ++ src/server/collision/Management/MMapManager.cpp | 301 ++++++++ src/server/collision/Management/MMapManager.h | 84 +++ .../PathFinderMovementGenerator.cpp | 780 +++++++++++++++++++++ .../PathFinderMovementGenerator.h | 135 ++++ 6 files changed, 1431 insertions(+) create mode 100644 src/server/collision/Management/MMapFactory.cpp create mode 100644 src/server/collision/Management/MMapFactory.h create mode 100644 src/server/collision/Management/MMapManager.cpp create mode 100644 src/server/collision/Management/MMapManager.h create mode 100644 src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp create mode 100644 src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h (limited to 'src') diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp new file mode 100644 index 00000000000..f4b2f3d47e4 --- /dev/null +++ b/src/server/collision/Management/MMapFactory.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * 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, see . + */ + +#include "MMapFactory.h" +#include "World.h" +#include "Config.h" +#include + +namespace MMAP +{ + // ######################## MMapFactory ######################## + // our global singleton copy + MMapManager *g_MMapManager = NULL; + + // stores list of mapids which do not use pathfinding + std::set* g_mmapDisabledIds = NULL; + + MMapManager* MMapFactory::createOrGetMMapManager() + { + if (g_MMapManager == NULL) + g_MMapManager = new MMapManager(); + + return g_MMapManager; + } + + void MMapFactory::preventPathfindingOnMaps(const char* ignoreMapIds) + { + if (!g_mmapDisabledIds) + g_mmapDisabledIds = new std::set(); + + uint32 strLenght = strlen(ignoreMapIds)+1; + char* mapList = new char[strLenght]; + memcpy(mapList, ignoreMapIds, sizeof(char)*strLenght); + + char* idstr = strtok(mapList, ","); + while (idstr) + { + g_mmapDisabledIds->insert(uint32(atoi(idstr))); + idstr = strtok(NULL, ","); + } + + delete[] mapList; + } + + bool MMapFactory::IsPathfindingEnabled(uint32 mapId) + { + return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) + && g_mmapDisabledIds->find(mapId) == g_mmapDisabledIds->end(); + } + + void MMapFactory::clear() + { + if (g_mmapDisabledIds) + { + delete g_mmapDisabledIds; + g_mmapDisabledIds = NULL; + } + + if (g_MMapManager) + { + delete g_MMapManager; + g_MMapManager = NULL; + } + } +} \ No newline at end of file diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h new file mode 100644 index 00000000000..ab047333a19 --- /dev/null +++ b/src/server/collision/Management/MMapFactory.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * 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, see . + */ + +#ifndef _MMAP_FACTORY_H +#define _MMAP_FACTORY_H + +#include "MMapManager.h" +#include "UnorderedMap.h" +#include "DetourAlloc.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" + +namespace MMAP +{ + enum MMAP_LOAD_RESULT + { + MMAP_LOAD_RESULT_ERROR, + MMAP_LOAD_RESULT_OK, + MMAP_LOAD_RESULT_IGNORED, + }; + + // static class + // holds all mmap global data + // access point to MMapManager singleton + class MMapFactory + { + public: + static MMapManager* createOrGetMMapManager(); + static void clear(); + static void preventPathfindingOnMaps(const char* ignoreMapIds); + static bool IsPathfindingEnabled(uint32 mapId); + }; +} + +#endif + diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp new file mode 100644 index 00000000000..aac5647a6de --- /dev/null +++ b/src/server/collision/Management/MMapManager.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * 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, see . + */ + +#include "MMapManager.h" +#include "Log.h" +#include "World.h" + +namespace MMAP +{ + // ######################## MMapManager ######################## + MMapManager::~MMapManager() + { + for (MMapDataSet::iterator i = loadedMMaps.begin(); i != loadedMMaps.end(); ++i) + delete i->second; + + // by now we should not have maps loaded + // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost! + } + + bool MMapManager::loadMapData(uint32 mapId) + { + // we already have this map loaded? + if (loadedMMaps.find(mapId) != loadedMMaps.end()) + return true; + + // load and init dtNavMesh - read parameters from file + uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap")+1; + char *fileName = new char[pathLen]; + snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId); + + FILE* file = fopen(fileName, "rb"); + if (!file) + { + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName); + delete [] fileName; + return false; + } + + dtNavMeshParams params; + fread(¶ms, sizeof(dtNavMeshParams), 1, file); + fclose(file); + + dtNavMesh* mesh = dtAllocNavMesh(); + ASSERT(mesh); + if (DT_SUCCESS != mesh->init(¶ms)) + { + dtFreeNavMesh(mesh); + sLog->outError("MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); + delete [] fileName; + return false; + } + + delete [] fileName; + + sLog->outDetail("MMAP:loadMapData: Loaded %03i.mmap", mapId); + + // store inside our map list + MMapData* mmap_data = new MMapData(mesh); + mmap_data->mmapLoadedTiles.clear(); + + loadedMMaps.insert(std::pair(mapId, mmap_data)); + return true; + } + + uint32 MMapManager::packTileID(int32 x, int32 y) + { + return uint32(x << 16 | y); + } + + bool MMapManager::loadMap(uint32 mapId, int32 x, int32 y) + { + // make sure the mmap is loaded and ready to load tiles + if(!loadMapData(mapId)) + return false; + + // get this mmap data + MMapData* mmap = loadedMMaps[mapId]; + ASSERT(mmap->navMesh); + + // check if we already have this tile loaded + uint32 packedGridPos = packTileID(x, y); + if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end()) + { + //sLog->outError("MMAP:loadMap: Asked to load already loaded navmesh tile. %03u%02i%02i.mmtile", mapId, y, x); + return false; + } + + // load this tile :: mmaps/MMMXXYY.mmtile + uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1; + char *fileName = new char[pathLen]; + // this change of y and x is needed because of mapbuilder.cpp (x and y are swapped there) so change it here so we dont need to re-extract. All swappes are done in other files. DONT CHANGE THIS! + snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, y, x); + + FILE *file = fopen(fileName, "rb"); + if (!file) + { + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMap: Could not open mmtile file '%s'", fileName); + delete [] fileName; + return false; + } + delete [] fileName; + + // read header + MmapTileHeader fileHeader; + fread(&fileHeader, sizeof(MmapTileHeader), 1, file); + + if (fileHeader.mmapMagic != MMAP_MAGIC) + { + sLog->outError("MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); + return false; + } + + if (fileHeader.mmapVersion != MMAP_VERSION) + { + sLog->outError("MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", + mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION); + return false; + } + + unsigned char* data = (unsigned char*)dtAlloc(fileHeader.size, DT_ALLOC_PERM); + ASSERT(data); + + size_t result = fread(data, fileHeader.size, 1, file); + if(!result) + { + sLog->outError("MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); + fclose(file); + return false; + } + + fclose(file); + + dtMeshHeader* header = (dtMeshHeader*)data; + dtTileRef tileRef = 0; + + // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed + if (DT_SUCCESS == mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)) + { + mmap->mmapLoadedTiles.insert(std::pair(packedGridPos, tileRef)); + ++loadedTiles; + sLog->outDetail("MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); + return true; + } + else + { + sLog->outError("MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); + dtFree(data); + return false; + } + + return false; + } + + bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) + { + // check if we have this map loaded + if (loadedMMaps.find(mapId) == loadedMMaps.end()) + { + // file may not exist, therefore not loaded + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, y, x); + return false; + } + + MMapData* mmap = loadedMMaps[mapId]; + + // check if we have this tile loaded + uint32 packedGridPos = packTileID(x, y); + if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end()) + { + // file may not exist, therefore not loaded + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, y, x); + return false; + } + + dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos]; + + // unload, and mark as non loaded + if (DT_SUCCESS != mmap->navMesh->removeTile(tileRef, NULL, NULL)) + { + // this is technically a memory leak + // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used + // we cannot recover from this error - assert out + sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + ASSERT(false); + } + else + { + mmap->mmapLoadedTiles.erase(packedGridPos); + --loadedTiles; + sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + return true; + } + + return false; + } + + bool MMapManager::unloadMap(uint32 mapId) + { + if (loadedMMaps.find(mapId) == loadedMMaps.end()) + { + // file may not exist, therefore not loaded + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId); + return false; + } + + // unload all tiles from given map + MMapData* mmap = loadedMMaps[mapId]; + for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i) + { + uint32 x = (i->first >> 16); + uint32 y = (i->first & 0x0000FFFF); + if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL)) + sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + else + { + --loadedTiles; + sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + } + } + + delete mmap; + loadedMMaps.erase(mapId); + sLog->outDetail("MMAP:unloadMap: Unloaded %03i.mmap", mapId); + + return true; + } + + bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId) + { + // check if we have this map loaded + if (loadedMMaps.find(mapId) == loadedMMaps.end()) + { + // file may not exist, therefore not loaded + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId); + return false; + } + + MMapData* mmap = loadedMMaps[mapId]; + if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) + { + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId); + return false; + } + + dtNavMeshQuery* query = mmap->navMeshQueries[instanceId]; + + dtFreeNavMeshQuery(query); + mmap->navMeshQueries.erase(instanceId); + sLog->outDetail("MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); + + return true; + } + + dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId) + { + if (loadedMMaps.find(mapId) == loadedMMaps.end()) + return NULL; + + return loadedMMaps[mapId]->navMesh; + } + + dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) + { + if (loadedMMaps.find(mapId) == loadedMMaps.end()) + return NULL; + + MMapData* mmap = loadedMMaps[mapId]; + if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) + { + // allocate mesh query + dtNavMeshQuery* query = dtAllocNavMeshQuery(); + ASSERT(query); + if (DT_SUCCESS != query->init(mmap->navMesh, 1024)) + { + dtFreeNavMeshQuery(query); + sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + return NULL; + } + + sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + mmap->navMeshQueries.insert(std::pair(instanceId, query)); + } + + return mmap->navMeshQueries[instanceId]; + } +} \ No newline at end of file diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h new file mode 100644 index 00000000000..8af452032d1 --- /dev/null +++ b/src/server/collision/Management/MMapManager.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * 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, see . + */ + +#ifndef _MMAP_MANAGER_H +#define _MMAP_MANAGER_H + +#include "UnorderedMap.h" +#include "DetourAlloc.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" + +// move map related classes +namespace MMAP +{ + typedef UNORDERED_MAP MMapTileSet; + typedef UNORDERED_MAP NavMeshQuerySet; + + // dummy struct to hold map's mmap data + struct MMapData + { + MMapData(dtNavMesh* mesh) : navMesh(mesh) {} + ~MMapData() + { + for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i) + dtFreeNavMeshQuery(i->second); + + if (navMesh) + dtFreeNavMesh(navMesh); + } + + dtNavMesh* navMesh; + + // we have to use single dtNavMeshQuery for every instance, since those are not thread safe + NavMeshQuerySet navMeshQueries; // instanceId to query + MMapTileSet mmapLoadedTiles; // maps [map grid coords] to [dtTile] + }; + + + typedef UNORDERED_MAP MMapDataSet; + + // singleton class + // holds all all access to mmap loading unloading and meshes + class MMapManager + { + public: + MMapManager() : loadedTiles(0) {} + ~MMapManager(); + + bool loadMap(uint32 mapId, int32 x, int32 y); + bool unloadMap(uint32 mapId, int32 x, int32 y); + bool unloadMap(uint32 mapId); + bool unloadMapInstance(uint32 mapId, uint32 instanceId); + + // the returned [dtNavMeshQuery const*] is NOT threadsafe + dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId); + dtNavMesh const* GetNavMesh(uint32 mapId); + + uint32 getLoadedTilesCount() const { return loadedTiles; } + uint32 getLoadedMapsCount() const { return loadedMMaps.size(); } + private: + bool loadMapData(uint32 mapId); + uint32 packTileID(int32 x, int32 y); + + MMapDataSet loadedMMaps; + uint32 loadedTiles; + }; +} + +#endif \ No newline at end of file diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp new file mode 100644 index 00000000000..686c57cb634 --- /dev/null +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2005-2011 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 "PathFinderMovementGenerator.h" +#include "Map.h" +#include "Creature.h" +#include "MMapFactory.h" +#include "MMapManager.h" +#include "Log.h" + +#include "DetourCommon.h" +#include "DetourNavMeshQuery.h" + +////////////////// PathFinderMovementGenerator ////////////////// +PathFinderMovementGenerator::PathFinderMovementGenerator(const Unit* owner) : + m_polyLength(0), m_type(PATHFIND_BLANK), + m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), + m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL) +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::PathFinderMovementGenerator for %u \n", m_sourceUnit->GetGUIDLow()); + + uint32 mapId = m_sourceUnit->GetMapId(); + if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) + { + MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); + m_navMesh = mmap->GetNavMesh(mapId); + m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId()); + } + + createFilter(); +} + +PathFinderMovementGenerator::~PathFinderMovementGenerator() +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::~PathFinderMovementGenerator() for %u \n", m_sourceUnit->GetGUIDLow()); +} + +bool PathFinderMovementGenerator::calculate(float destX, float destY, float destZ, bool forceDest) +{ + if (!Trinity::IsValidMapCoord(destX, destY, destZ) || + !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) + return false; + + Vector3 oldDest = getEndPosition(); + Vector3 dest(destX, destY, destZ); + setEndPosition(dest); + + float x, y, z; + m_sourceUnit->GetPosition(x, y, z); + Vector3 start(x, y, z); + setStartPosition(start); + + m_forceDestination = forceDest; + + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::calculate() for %u \n", m_sourceUnit->GetGUIDLow()); + + // make sure navMesh works - we can run on map w/o mmap + // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) + if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STAT_IGNORE_PATHFINDING) || + !HaveTile(start) || !HaveTile(dest)) + { + BuildShortcut(); + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + return true; + } + + updateFilter(); + + // check if destination moved - if not we can optimize something here + // we are following old, precalculated path? + float dist = m_sourceUnit->GetObjectSize(); + if (inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) + { + // our target is not moving - we just coming closer + // we are moving on precalculated path - enjoy the ride + sLog->outStaticDebug("++ PathFinderMovementGenerator::calculate:: precalculated path\n"); + + m_pathPoints.erase(m_pathPoints.begin()); + return false; + } + else + { + // target moved, so we need to update the poly path + BuildPolyPath(start, dest); + return true; + } +} + +dtPolyRef PathFinderMovementGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance) const +{ + if (!polyPath || !polyPathSize) + return INVALID_POLYREF; + + dtPolyRef nearestPoly = INVALID_POLYREF; + float minDist2d = FLT_MAX; + float minDist3d = 0.0f; + + for (uint32 i = 0; i < polyPathSize; ++i) + { + float closestPoint[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)) + continue; + + float d = dtVdist2DSqr(point, closestPoint); + if (d < minDist2d) + { + minDist2d = d; + nearestPoly = polyPath[i]; + minDist3d = dtVdistSqr(point, closestPoint); + } + + if(minDist2d < 1.0f) // shortcut out - close enough for us + break; + } + + if (distance) + *distance = dtSqrt(minDist3d); + + return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF; +} + +dtPolyRef PathFinderMovementGenerator::getPolyByLocation(const float* point, float *distance) const +{ + // first we check the current path + // if the current path doesn't contain the current poly, + // we need to use the expensive navMesh.findNearestPoly + dtPolyRef polyRef = getPathPolyByPosition(m_pathPolyRefs, m_polyLength, point, distance); + if (polyRef != INVALID_POLYREF) + return polyRef; + + // we don't have it in our old path + // try to get it by findNearestPoly() + // first try with low search box + float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area + float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f}; + dtStatus result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) + { + *distance = dtVdist(closestPoint, point); + return polyRef; + } + + // still nothing .. + // try with bigger search box + extents[1] = 200.0f; + result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) + { + *distance = dtVdist(closestPoint, point); + return polyRef; + } + + return INVALID_POLYREF; +} + +void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos) +{ + // *** getting start/end poly logic *** + + float distToStartPoly, distToEndPoly; + float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x}; + float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x}; + + dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly); + dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly); + + // we have a hole in our mesh + // make shortcut path and mark it as NOPATH ( with flying exception ) + // its up to caller how he will use this info + if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); + BuildShortcut(); + m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->canFly()) + ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; + return; + } + + // we may need a better number here + bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); + if (farFromPoly) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly); + + bool buildShotrcut = false; + if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + { + Creature* owner = (Creature*)m_sourceUnit; + + Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos; + if (m_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n"); + if (owner->canSwim()) + buildShotrcut = true; + } + else + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n"); + if (owner->canFly()) + buildShotrcut = true; + } + } + + if (buildShotrcut) + { + BuildShortcut(); + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + return; + } + else + { + float closestPoint[VERTEX_SIZE]; + // we may want to use closestPointOnPolyBoundary instead + if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)) + { + dtVcopy(endPoint, closestPoint); + setActualEndPosition(Vector3(endPoint[2],endPoint[0],endPoint[1])); + } + + m_type = PATHFIND_INCOMPLETE; + } + } + + // *** poly path generating logic *** + + // start and end are on same polygon + // just need to move in straight line + if (startPoly == endPoly) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == endPoly)\n"); + + BuildShortcut(); + + m_pathPolyRefs[0] = startPoly; + m_polyLength = 1; + + m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", m_type); + return; + } + + // look for startPoly/endPoly in current path + // TODO: we can merge it with getPathPolyByPosition() loop + bool startPolyFound = false; + bool endPolyFound = false; + uint32 pathStartIndex, pathEndIndex; + + if (m_polyLength) + { + for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex) + { + // here to carch few bugs + ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); + + if (m_pathPolyRefs[pathStartIndex] == startPoly) + { + startPolyFound = true; + break; + } + } + + for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) + if (m_pathPolyRefs[pathEndIndex] == endPoly) + { + endPolyFound = true; + break; + } + } + + if (startPolyFound && endPolyFound) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n"); + + // we moved along the path and the target did not move out of our old poly-path + // our path is a simple subpath case, we have all the data we need + // just "cut" it out + + m_polyLength = pathEndIndex - pathStartIndex + 1; + memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef)); + } + else if (startPolyFound && !endPolyFound) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n"); + + // we are moving on the old path but target moved out + // so we have atleast part of poly-path ready + + m_polyLength -= pathStartIndex; + + // try to adjust the suffix of the path instead of recalculating entire length + // at given interval the target cannot get too far from its last location + // thus we have less poly to cover + // sub-path of optimal path is optimal + + // take ~80% of the original length + // TODO : play with the values here + uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f); + memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef)); + + dtPolyRef suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; + + // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data + float suffixEndPoint[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + { + // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that + // try to recover by using prev polyref + --prefixPolyLength; + suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + { + // suffixStartPoly is still invalid, error state + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + } + + // generate suffix + uint32 suffixPolyLength = 0; + dtStatus dtResult = m_navMeshQuery->findPath( + suffixStartPoly, // start polygon + endPoly, // end polygon + suffixEndPoint, // start position + endPoint, // end position + &m_filter, // polygon search filter + m_pathPolyRefs + prefixPolyLength - 1, // [out] path + (int*)&suffixPolyLength, + MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path + + if (!suffixPolyLength || dtResult != DT_SUCCESS) + { + // this is probably an error state, but we'll leave it + // and hopefully recover on the next Update + // we still need to copy our preffix + sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + } + + sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); + + // new path = prefix + suffix - overlap + m_polyLength = prefixPolyLength + suffixPolyLength - 1; + } + else + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n"); + + // either we have no path at all -> first run + // or something went really wrong -> we aren't moving along the path to the target + // just generate new path + + // free and invalidate old path data + clear(); + + dtStatus dtResult = m_navMeshQuery->findPath( + startPoly, // start polygon + endPoly, // end polygon + startPoint, // start position + endPoint, // end position + &m_filter, // polygon search filter + m_pathPolyRefs, // [out] path + (int*)&m_polyLength, + MAX_PATH_LENGTH); // max number of polygons in output path + + if (!m_polyLength || dtResult != DT_SUCCESS) + { + // only happens if we passed bad data to findPath(), or navmesh is messed up + sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + } + + // by now we know what type of path we can get + if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE)) + m_type = PATHFIND_NORMAL; + else + m_type = PATHFIND_INCOMPLETE; + + // generate the point-path out of our up-to-date poly-path + BuildPointPath(startPoint, endPoint); +} + +void PathFinderMovementGenerator::BuildPointPath(const float *startPoint, const float *endPoint) +{ + float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE]; + uint32 pointCount = 0; + dtStatus dtResult = DT_FAILURE; + if (m_useStraightPath) + { + dtResult = m_navMeshQuery->findStraightPath( + startPoint, // start position + endPoint, // end position + m_pathPolyRefs, // current path + m_polyLength, // lenth of current path + pathPoints, // [out] path corner points + NULL, // [out] flags + NULL, // [out] shortened path + (int*)&pointCount, + m_pointPathLimit); // maximum number of points/polygons to use + } + else + { + dtResult = findSmoothPath( + startPoint, // start position + endPoint, // end position + m_pathPolyRefs, // current path + m_polyLength, // length of current path + pathPoints, // [out] path corner points + (int*)&pointCount, + m_pointPathLimit); // maximum number of points + } + + if (pointCount < 2 || dtResult != DT_SUCCESS) + { + // only happens if pass bad data to findStraightPath or navmesh is broken + // single point paths can be generated here + // TODO : check the exact cases + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount); + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + + m_pathPoints.resize(pointCount); + for (uint32 i = 0; i < pointCount; ++i) + m_pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); + + // first point is always our current location - we need the next one + setActualEndPosition(m_pathPoints[pointCount-1]); + + // force the given destination, if needed + if(m_forceDestination && + (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f))) + { + // we may want to keep partial subpath + if(dist3DSqr(getActualEndPosition(), getEndPosition()) < + 0.3f * dist3DSqr(getStartPosition(), getEndPosition())) + { + setActualEndPosition(getEndPosition()); + m_pathPoints[m_pathPoints.size()-1] = getEndPosition(); + } + else + { + setActualEndPosition(getEndPosition()); + BuildShortcut(); + } + + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + } + + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength); +} + +void PathFinderMovementGenerator::BuildShortcut() +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); + + clear(); + + // make two point path, our curr pos is the start, and dest is the end + m_pathPoints.resize(2); + + // set start and a default next position + m_pathPoints[0] = getStartPosition(); + m_pathPoints[1] = getActualEndPosition(); + + m_type = PATHFIND_SHORTCUT; +} + +void PathFinderMovementGenerator::createFilter() +{ + uint16 includeFlags = 0; + uint16 excludeFlags = 0; + + if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + { + Creature* creature = (Creature*)m_sourceUnit; + if (creature->canWalk()) + includeFlags |= NAV_GROUND; // walk + + // creatures don't take environmental damage + if (creature->canSwim()) + includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim + } + else if (m_sourceUnit->GetTypeId() == TYPEID_PLAYER) + { + // perfect support not possible, just stay 'safe' + includeFlags |= (NAV_GROUND | NAV_WATER); + } + + m_filter.setIncludeFlags(includeFlags); + m_filter.setExcludeFlags(excludeFlags); + + updateFilter(); +} + +void PathFinderMovementGenerator::updateFilter() +{ + // allow creatures to cheat and use different movement types if they are moved + // forcefully into terrain they can't normally move in + if (m_sourceUnit->IsInWater() || m_sourceUnit->IsUnderWater()) + { + uint16 includedFlags = m_filter.getIncludeFlags(); + includedFlags |= getNavTerrain(m_sourceUnit->GetPositionX(), + m_sourceUnit->GetPositionY(), + m_sourceUnit->GetPositionZ()); + + m_filter.setIncludeFlags(includedFlags); + } +} + +NavTerrain PathFinderMovementGenerator::getNavTerrain(float x, float y, float z) +{ + LiquidData data; + m_sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); + + switch (data.type) + { + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + return NAV_WATER; + case MAP_LIQUID_TYPE_MAGMA: + return NAV_MAGMA; + case MAP_LIQUID_TYPE_SLIME: + return NAV_SLIME; + default: + return NAV_GROUND; + } +} + +bool PathFinderMovementGenerator::HaveTile(const Vector3 &p) const +{ + int tx, ty; + float point[VERTEX_SIZE] = {p.y, p.z, p.x}; + + m_navMesh->calcTileLoc(point, &tx, &ty); + return (m_navMesh->getTileAt(tx, ty) != NULL); +} + +uint32 PathFinderMovementGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, + const dtPolyRef* visited, uint32 nvisited) +{ + int32 furthestPath = -1; + int32 furthestVisited = -1; + + // Find furthest common polygon. + for (int32 i = npath-1; i >= 0; --i) + { + bool found = false; + for (int32 j = nvisited-1; j >= 0; --j) + { + if (path[i] == visited[j]) + { + furthestPath = i; + furthestVisited = j; + found = true; + } + } + if (found) + break; + } + + // If no intersection found just return current path. + if (furthestPath == -1 || furthestVisited == -1) + return npath; + + // Concatenate paths. + + // Adjust beginning of the buffer to include the visited. + uint32 req = nvisited - furthestVisited; + uint32 orig = uint32(furthestPath+1) < npath ? furthestPath+1 : npath; + uint32 size = npath-orig > 0 ? npath-orig : 0; + if (req+size > maxPath) + size = maxPath-req; + + if (size) + memmove(path+req, path+orig, size*sizeof(dtPolyRef)); + + // Store visited + for (uint32 i = 0; i < req; ++i) + path[i] = visited[(nvisited-1)-i]; + + return req+size; +} + +bool PathFinderMovementGenerator::getSteerTarget(const float* startPos, const float* endPos, + float minTargetDist, const dtPolyRef* path, uint32 pathSize, + float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef) +{ + // Find steer target. + static const uint32 MAX_STEER_POINTS = 3; + float steerPath[MAX_STEER_POINTS*VERTEX_SIZE]; + unsigned char steerPathFlags[MAX_STEER_POINTS]; + dtPolyRef steerPathPolys[MAX_STEER_POINTS]; + uint32 nsteerPath = 0; + dtStatus dtResult = m_navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, + steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS); + if (!nsteerPath || DT_SUCCESS != dtResult) + return false; + + // Find vertex far enough to steer to. + uint32 ns = 0; + while (ns < nsteerPath) + { + // Stop at Off-Mesh link or when point is further than slop away. + if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || + !inRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) + break; + ns++; + } + // Failed to find good point to steer to. + if (ns >= nsteerPath) + return false; + + dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]); + steerPos[1] = startPos[1]; // keep Z value + steerPosFlag = steerPathFlags[ns]; + steerPosRef = steerPathPolys[ns]; + + return true; +} + +dtStatus PathFinderMovementGenerator::findSmoothPath(const float* startPos, const float* endPos, + const dtPolyRef* polyPath, uint32 polyPathSize, + float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize) +{ + *smoothPathSize = 0; + uint32 nsmoothPath = 0; + + dtPolyRef polys[MAX_PATH_LENGTH]; + memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize); + uint32 npolys = polyPathSize; + + float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)) + return DT_FAILURE; + + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)) + return DT_FAILURE; + + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + + // Move towards target a small advancement at a time until target reached or + // when ran out of memory to store the path. + while (npolys && nsmoothPath < maxSmoothPathSize) + { + // Find location to steer towards. + float steerPos[VERTEX_SIZE]; + unsigned char steerPosFlag; + dtPolyRef steerPosRef = INVALID_POLYREF; + + if (!getSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) + break; + + bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END); + bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION); + + // Find movement delta. + float delta[VERTEX_SIZE]; + dtVsub(delta, steerPos, iterPos); + float len = dtSqrt(dtVdot(delta,delta)); + // If the steer target is end of path or off-mesh link, do not move past the location. + if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE) + len = 1.0f; + else + len = SMOOTH_PATH_STEP_SIZE / len; + + float moveTgt[VERTEX_SIZE]; + dtVmad(moveTgt, iterPos, delta, len); + + // Move + float result[VERTEX_SIZE]; + const static uint32 MAX_VISIT_POLY = 16; + dtPolyRef visited[MAX_VISIT_POLY]; + + uint32 nvisited = 0; + m_navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); + npolys = fixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); + + m_navMeshQuery->getPolyHeight(polys[0], result, &result[1]); + result[1] += 0.5f; + dtVcopy(iterPos, result); + + // Handle end of path and off-mesh links when close enough. + if (endOfPath && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + { + // Reached end of path. + dtVcopy(iterPos, targetPos); + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + } + break; + } + else if (offMeshConnection && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + { + // Advance the path up to and over the off-mesh connection. + dtPolyRef prevRef = INVALID_POLYREF; + dtPolyRef polyRef = polys[0]; + uint32 npos = 0; + while (npos < npolys && polyRef != steerPosRef) + { + prevRef = polyRef; + polyRef = polys[npos]; + npos++; + } + + for (uint32 i = npos; i < npolys; ++i) + polys[i-npos] = polys[i]; + + npolys -= npos; + + // Handle the connection. + float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; + if (DT_SUCCESS == m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) + { + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos); + nsmoothPath++; + } + // Move position at the other side of the off-mesh link. + dtVcopy(iterPos, endPos); + m_navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); + iterPos[1] += 0.5f; + } + } + + // Store results. + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + } + } + + *smoothPathSize = nsmoothPath; + + // this is most likely a loop + return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; +} + +bool PathFinderMovementGenerator::inRangeYZX(const float* v1, const float* v2, float r, float h) const +{ + const float dx = v2[0] - v1[0]; + const float dy = v2[1] - v1[1]; // elevation + const float dz = v2[2] - v1[2]; + return (dx*dx + dz*dz) < r*r && fabsf(dy) < h; +} + +bool PathFinderMovementGenerator::inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const +{ + Vector3 d = p1-p2; + return (d.x*d.x + d.y*d.y) < r*r && fabsf(d.z) < h; +} + +float PathFinderMovementGenerator::dist3DSqr(const Vector3 &p1, const Vector3 &p2) const +{ + return (p1-p2).squaredLength(); +} diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h new file mode 100644 index 00000000000..f4edd1a1789 --- /dev/null +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005-2011 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 _PATH_INFO_H +#define _PATH_INFO_H + +#include "SharedDefines.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" +#include "MoveSplineInitArgs.h" + +using Movement::Vector3; +using Movement::PointsArray; + +class Unit; + +// 74*4.0f=296y number_of_points*interval = max_path_len +// this is way more than actual evade range +// I think we can safely cut those down even more +#define MAX_PATH_LENGTH 74 +#define MAX_POINT_PATH_LENGTH 74 + +#define SMOOTH_PATH_STEP_SIZE 4.0f +#define SMOOTH_PATH_SLOP 0.3f + +#define VERTEX_SIZE 3 +#define INVALID_POLYREF 0 + +enum PathType +{ + PATHFIND_BLANK = 0x0000, // path not built yet + PATHFIND_NORMAL = 0x0001, // normal path + PATHFIND_SHORTCUT = 0x0002, // travel through obstacles, terrain, air, etc (old behavior) + PATHFIND_INCOMPLETE = 0x0004, // we have partial path to follow - getting closer to target + PATHFIND_NOPATH = 0x0008, // no valid path at all or error in generating one + PATHFIND_NOT_USING_PATH = 0x0010 // used when we are either flying/swiming or on map w/o mmaps +}; + +class PathFinderMovementGenerator +{ + public: + PathFinderMovementGenerator(Unit const* owner); + ~PathFinderMovementGenerator(); + + // Calculate the path from owner to given destination + // return: true if new path was calculated, false otherwise (no change needed) + bool calculate(float destX, float destY, float destZ, bool forceDest = false); + + // option setters - use optional + void setUseStrightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; + void setPathLengthLimit(float distance) { m_pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; + + // result getters + Vector3 getStartPosition() const { return m_startPosition; } + Vector3 getEndPosition() const { return m_endPosition; } + Vector3 getActualEndPosition() const { return m_actualEndPosition; } + + PointsArray& getPath() { return m_pathPoints; } + PathType getPathType() const { return m_type; } + + private: + + dtPolyRef m_pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references + uint32 m_polyLength; // number of polygons in the path + + PointsArray m_pathPoints; // our actual (x,y,z) path to the target + PathType m_type; // tells what kind of path this is + + bool m_useStraightPath; // type of path will be generated + bool m_forceDestination; // when set, we will always arrive at given point + uint32 m_pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) + + Vector3 m_startPosition; // {x, y, z} of current location + Vector3 m_endPosition; // {x, y, z} of the destination + Vector3 m_actualEndPosition;// {x, y, z} of the closest possible point to given destination + + const Unit* const m_sourceUnit; // the unit that is moving + const dtNavMesh* m_navMesh; // the nav mesh + const dtNavMeshQuery* m_navMeshQuery; // the nav mesh query used to find the path + + dtQueryFilter m_filter; // use single filter for all movements, update it when needed + + void setStartPosition(Vector3 point) { m_startPosition = point; } + void setEndPosition(Vector3 point) { m_actualEndPosition = point; m_endPosition = point; } + void setActualEndPosition(Vector3 point) { m_actualEndPosition = point; } + + void clear() + { + m_polyLength = 0; + m_pathPoints.clear(); + } + + bool inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const; + float dist3DSqr(const Vector3 &p1, const Vector3 &p2) const; + bool inRangeYZX(const float* v1, const float* v2, float r, float h) const; + + dtPolyRef getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance = NULL) const; + dtPolyRef getPolyByLocation(const float* point, float *distance) const; + bool HaveTile(const Vector3 &p) const; + + void BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos); + void BuildPointPath(const float *startPoint, const float *endPoint); + void BuildShortcut(); + + NavTerrain getNavTerrain(float x, float y, float z); + void createFilter(); + void updateFilter(); + + // smooth path aux functions + uint32 fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, + const dtPolyRef* visited, uint32 nvisited); + bool getSteerTarget(const float* startPos, const float* endPos, float minTargetDist, + const dtPolyRef* path, uint32 pathSize, float* steerPos, + unsigned char& steerPosFlag, dtPolyRef& steerPosRef); + dtStatus findSmoothPath(const float* startPos, const float* endPos, + const dtPolyRef* polyPath, uint32 polyPathSize, + float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize); +}; + +#endif -- cgit v1.2.3 From d6bddc1c94427b325d9b4fd842562c5d8ae2f0c9 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:11:39 +0200 Subject: Core/Mmaps: * implemented loading part. --- src/server/collision/CMakeLists.txt | 2 ++ src/server/collision/Management/VMapManager2.h | 2 ++ src/server/collision/Maps/MapTree.h | 1 + src/server/collision/Models/ModelInstance.h | 2 ++ src/server/collision/Models/WorldModel.h | 6 ++++++ src/server/game/CMakeLists.txt | 2 ++ src/server/game/Entities/Unit/Unit.h | 3 ++- src/server/game/Maps/Map.cpp | 24 ++++++++++++++++++++++++ src/server/game/Maps/Map.h | 3 +++ src/server/game/Maps/MapInstanced.cpp | 2 ++ src/server/game/Movement/MovementGenerator.h | 3 +++ 11 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt index 9fc696ab19a..d54d5f91046 100644 --- a/src/server/collision/CMakeLists.txt +++ b/src/server/collision/CMakeLists.txt @@ -34,7 +34,9 @@ set(collision_STAT_SRCS include_directories( ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging ${CMAKE_SOURCE_DIR}/src/server/shared/Database ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h index 1fba108388a..c87c42fd832 100755 --- a/src/server/collision/Management/VMapManager2.h +++ b/src/server/collision/Management/VMapManager2.h @@ -112,6 +112,8 @@ namespace VMAP return getMapFileName(mapId); } virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y); + public: + void getInstanceMapTree(InstanceTreeMap &instanceMapTree); }; } diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 1732209c6bc..f0df713bf57 100755 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -80,6 +80,7 @@ namespace VMAP void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm); bool isTiled() const { return iIsTiled; } uint32 numLoadedTiles() const { return iLoadedTiles.size(); } + void getModelInstances(ModelInstance* &models, uint32 &count); }; struct AreaInfo diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 1118b654578..3c46967980f 100755 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -74,6 +74,8 @@ namespace VMAP G3D::Matrix3 iInvRot; float iInvScale; WorldModel* iModel; + public: + WorldModel* const getWorldModel(); }; } // namespace VMAP diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h index ebf828e4935..98be3494927 100755 --- a/src/server/collision/Models/WorldModel.h +++ b/src/server/collision/Models/WorldModel.h @@ -66,6 +66,8 @@ namespace VMAP uint32 iType; //!< liquid type float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values uint8 *iFlags; //!< info if liquid tile is used + public: + void getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const; }; /*! holding additional info for WMO group files */ @@ -98,6 +100,8 @@ namespace VMAP std::vector triangles; BIH meshTree; WmoLiquid* iLiquid; + public: + void getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid); }; /*! Holds a model (converted M2 or WMO) in its original coordinate space */ class WorldModel @@ -117,6 +121,8 @@ namespace VMAP uint32 RootWMOID; std::vector groupModels; BIH groupTree; + public: + void getGroupModels(std::vector &groupModels); }; } // namespace VMAP diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 1f680f6e9b0..ec5833b0368 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -106,6 +106,8 @@ set(game_STAT_SRCS include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/dep/SFMT diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index bb826c14dfc..b47c5a78dd5 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -498,6 +498,7 @@ enum UnitState UNIT_STATE_FLEEING_MOVE = 0x02000000, UNIT_STATE_CHASE_MOVE = 0x04000000, UNIT_STATE_FOLLOW_MOVE = 0x08000000, + UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator UNIT_STATE_UNATTACKABLE = (UNIT_STATE_IN_FLIGHT | UNIT_STATE_ONVEHICLE), // for real move using movegen check and stop (except unstoppable flight) UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE , @@ -1626,7 +1627,7 @@ class Unit : public WorldObject void JumpTo(float speedXY, float speedZ, bool forward = true); void JumpTo(WorldObject* obj, float speedZ); - void MonsterMoveWithSpeed(float x, float y, float z, float speed); + void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false); //void SetFacing(float ori, WorldObject* obj = NULL); void SendMonsterMoveExitVehicle(Position const* newPos); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index a1b3d913c99..c3732769d04 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -20,6 +20,7 @@ #include "GridStates.h" #include "ScriptMgr.h" #include "VMapFactory.h" +#include "MMapFactory.h" #include "MapInstanced.h" #include "CellImpl.h" #include "GridNotifiers.h" @@ -69,6 +70,9 @@ Map::~Map() if (!m_scriptSchedule.empty()) sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); + + MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); } bool Map::ExistMap(uint32 mapid, int gx, int gy) @@ -117,6 +121,24 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) return true; } +void Map::LoadMMap(int gx, int gy) +{ + // DONT CHANGE "gy" and "gx" - Its necessary ! + int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(GetId(), gy, gx); + switch (mmapLoadResult) + { + case MMAP::MMAP_LOAD_RESULT_OK: + sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + break; + case MMAP::MMAP_LOAD_RESULT_ERROR: + sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + break; + case MMAP::MMAP_LOAD_RESULT_IGNORED: + sLog->outStaticDebug("Ignored MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + break; + } +} + void Map::LoadVMap(int gx, int gy) { // x and y are swapped !! @@ -184,6 +206,7 @@ void Map::LoadMap(int gx, int gy, bool reload) void Map::LoadMapAndVMap(int gx, int gy) { LoadMap(gx, gy); + LoadMMap(gx, gy); if (i_InstanceId == 0) LoadVMap(gx, gy); // Only load the data for the base map } @@ -996,6 +1019,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) } // x and y are swapped VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gx, gy); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId(), gx, gy); } else ((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 766e3d23f93..925adfbc15a 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -76,6 +76,8 @@ struct map_fileheader uint32 heightMapSize; uint32 liquidMapOffset; uint32 liquidMapSize; + uint32 holesOffset; + uint32 holesSize; }; #define MAP_AREA_NO_AREA 0x0001 @@ -447,6 +449,7 @@ class Map : public GridRefManager void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); void LoadMap(int gx, int gy, bool reload = false); + void LoadMMap(int gx, int gy); GridMap* GetGrid(float x, float y); void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 5543251e115..5924b9246f6 100755 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -21,6 +21,7 @@ #include "MapManager.h" #include "Battleground.h" #include "VMapFactory.h" +#include "MMapFactory.h" #include "InstanceSaveMgr.h" #include "World.h" #include "Group.h" @@ -258,6 +259,7 @@ bool MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) if (m_InstancedMaps.size() <= 1 && sWorld->getBoolConfig(CONFIG_GRID_UNLOAD)) { VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(itr->second->GetId()); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(itr->second->GetId()); // in that case, unload grids of the base map, too // so in the next map creation, (EnsureGridCreated actually) VMaps will be reloaded Map::UnloadAll(); diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 0a2ebcfaeee..85e1fec0c2d 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -43,6 +43,9 @@ class MovementGenerator virtual MovementGeneratorType GetMovementGeneratorType() = 0; virtual void unitSpeedChanged() { } + + // used by Evade code for select point to evade with expected restart default movement + virtual bool GetResetPosition(Unit &, float& /*x*/, float& /*y*/, float& /*z*/) { return false; } }; template -- cgit v1.2.3 From b1b831a1d77e9c594de176805591a339beb7ef5e Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:20:45 +0200 Subject: Core/Movement: Implemented mmaps in ConfusedMovementGenerator. --- .../ConfusedMovementGenerator.cpp | 36 ++++++++++------------ .../MovementGenerators/ConfusedMovementGenerator.h | 6 +--- 2 files changed, 17 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 54a68f92c66..6357f3950ea 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -79,29 +79,15 @@ void ConfusedMovementGenerator::Initialize(T &unit) i_waypoints[idx][2] = z; } + unit.GetPosition(i_x, i_y, i_z); unit.StopMoving(); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } -template<> -void ConfusedMovementGenerator::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) -{ - is_water_ok = creature.canSwim(); - is_land_ok = creature.canWalk(); -} - -template<> -void ConfusedMovementGenerator::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok) -{ - is_water_ok = true; - is_land_ok = true; -} - template void ConfusedMovementGenerator::Reset(T &unit) { - i_nextMove = 1; i_nextMoveTime.Reset(0); unit.StopMoving(); unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); @@ -119,10 +105,7 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); if (unit.movespline->Finalized()) - { - i_nextMove = urand(1, MAX_CONF_WAYPOINTS); - i_nextMoveTime.Reset(urand(500, 1200)); // Guessed - } + i_nextMoveTime.Reset(urand(800, 1500)); } else { @@ -137,8 +120,20 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) float x = i_waypoints[i_nextMove][0]; float y = i_waypoints[i_nextMove][1]; float z = i_waypoints[i_nextMove][2]; + + unit.UpdateAllowedPositionZ(x, y, z); + + PathFinderMovementGenerator path(&unit); + path.setPathLengthLimit(30.0f); + path.calculate(x, y, z); + if (path.getPathType() & PATHFIND_NOPATH) + { + i_nextMoveTime.Reset(urand(800, 1000)); + return true; + } + Movement::MoveSplineInit init(unit); - init.MoveTo(x, y, z); + init.MovebyPath(path.getPath()); init.SetWalk(true); init.Launch(); } @@ -152,6 +147,7 @@ void ConfusedMovementGenerator::Finalize(Player &unit) { unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + unit.StopMoving(); } template<> diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index 7f2226ea069..c390892d0d0 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -22,8 +22,6 @@ #include "MovementGenerator.h" #include "Timer.h" -#define MAX_CONF_WAYPOINTS 24 //! Allows a twelve second confusion if i_nextMove always is the absolute minimum timer. - template class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMovementGenerator > { @@ -37,10 +35,8 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } private: - void _InitSpecific(T &, bool &, bool &); TimeTracker i_nextMoveTime; - float i_waypoints[MAX_CONF_WAYPOINTS+1][3]; - uint32 i_nextMove; + float i_waypoints[24+1][3]; }; #endif -- cgit v1.2.3 From 973adf112bff7d8ec0aeb09f9fd2545d82943868 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:48:19 +0200 Subject: More changes for mmaps. --- .../ConfusedMovementGenerator.cpp | 3 +-- src/server/game/Movement/Waypoints/Path.h | 24 ++++++++++++++++++---- src/server/game/World/World.cpp | 6 ++++++ src/server/game/World/World.h | 1 + src/server/scripts/CMakeLists.txt | 3 +++ src/server/shared/CMakeLists.txt | 1 + src/server/worldserver/CMakeLists.txt | 2 ++ 7 files changed, 34 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 6357f3950ea..caf81a0a141 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -19,6 +19,7 @@ #include "Creature.h" #include "MapManager.h" #include "ConfusedMovementGenerator.h" +#include "PathFinderMovementGenerator.h" #include "VMapFactory.h" #include "MoveSplineInit.h" #include "MoveSpline.h" @@ -42,8 +43,6 @@ void ConfusedMovementGenerator::Initialize(T &unit) i_nextMove = 1; bool is_water_ok, is_land_ok; - _InitSpecific(unit, is_water_ok, is_land_ok); - for (uint8 idx = 0; idx < MAX_CONF_WAYPOINTS + 1; ++idx) { float wanderX = x + (wander_distance * (float)rand_norm() - wander_distance/2); diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h index b6ddaa9d726..038958593fb 100755 --- a/src/server/game/Movement/Waypoints/Path.h +++ b/src/server/game/Movement/Waypoints/Path.h @@ -20,10 +20,12 @@ #define TRINITYCORE_PATH_H #include "Common.h" -#include +#include -struct SimplePathNode +struct PathNode { + PathNode(): x(0.0f), y(0.0f), z(0.0f) { } + PathNode(float _x, float _y, float _z): x(_x), y(_y), z(_z) { } float x, y, z; }; template @@ -36,6 +38,20 @@ class Path void resize(unsigned int sz) { i_nodes.resize(sz); } void clear() { i_nodes.clear(); } void erase(uint32 idx) { i_nodes.erase(i_nodes.begin()+idx); } + void crop(unsigned int start, unsigned int end) + { + while(start && !i_nodes.empty()) + { + i_nodes.pop_front(); + --start; + } + + while(end && !i_nodes.empty()) + { + i_nodes.pop_back(); + --end; + } + } float GetTotalLength(uint32 start, uint32 end) const { @@ -76,10 +92,10 @@ class Path void set(size_t idx, PathElem elem) { i_nodes[idx] = elem; } protected: - std::vector i_nodes; + std::deque i_nodes; }; -typedef Path SimplePath; +typedef Path SimplePath; #endif diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6e32d33a7bb..3870a108d57 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -21,6 +21,7 @@ */ #include "Common.h" +#include "Memory.h" #include "DatabaseEnv.h" #include "Config.h" #include "SystemConfig.h" @@ -54,6 +55,7 @@ #include "TemporarySummon.h" #include "WaypointMovementGenerator.h" #include "VMapFactory.h" +#include "MMapFactory.h" #include "GameEventMgr.h" #include "PoolMgr.h" #include "GridNotifiersImpl.h" @@ -1121,6 +1123,7 @@ void World::LoadConfigSettings(bool reload) } m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); + m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true); bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", true); @@ -1216,6 +1219,9 @@ void World::SetInitialWorldSettings() ///- Initialize the random number generator srand((unsigned int)time(NULL)); + ///- Initialize detour memory management + dtAllocSetCustom(dtCustomAlloc, dtCustomFree); + ///- Initialize config settings LoadConfigSettings(); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 95e9fbda8ca..ec3d09006bd 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -164,6 +164,7 @@ enum WorldBoolConfigs CONFIG_QUEST_IGNORE_AUTO_ACCEPT, CONFIG_QUEST_IGNORE_AUTO_COMPLETE, CONFIG_WARDEN_ENABLED, + CONFIG_ENABLE_MMAPS, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 728d95a0851..e249943eb7c 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -51,6 +51,8 @@ message("") include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/mersennetwister @@ -120,6 +122,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/Maps ${CMAKE_SOURCE_DIR}/src/server/game/Movement ${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints ${CMAKE_SOURCE_DIR}/src/server/game/Opcodes ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index 3ec35b5394a..d42049b1cdf 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -52,6 +52,7 @@ set(shared_STAT_SRCS include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/dep/sockets/include diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index d1419cb0fcb..080e71846a6 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -45,6 +45,7 @@ endif() include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/gsoap ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/SFMT @@ -168,6 +169,7 @@ target_link_libraries(worldserver collision g3dlib gsoap + Detour ${JEMALLOC_LIBRARY} ${READLINE_LIBRARY} ${TERMCAP_LIBRARY} -- cgit v1.2.3 From 710a617a3cf7b0f59c268fd0a6396d1e6e7393ba Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:52:00 +0200 Subject: Core/Tools: Store hole data. --- src/tools/map_extractor/System.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index bbde9f4675e..29836506861 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -292,6 +292,8 @@ struct map_fileheader uint32 heightMapSize; uint32 liquidMapOffset; uint32 liquidMapSize; + uint32 holesOffset; + uint32 holesSize; }; #define MAP_AREA_NO_AREA 0x0001 @@ -826,6 +828,28 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 map.liquidMapSize += sizeof(float)*liquidHeader.width*liquidHeader.height; } + // map hole info + uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; + + if (map.liquidMapOffset) + map.holesOffset = map.liquidMapOffset + map.liquidMapSize; + else + map.holesOffset = map.heightMapOffset + map.heightMapSize; + + map.holesSize = sizeof(holes); + memset(holes, 0, map.holesSize); + + 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; + holes[i][j] = cell->holes; + } + } + // Ok all data prepared - store it FILE *output=fopen(filename2, "wb"); if(!output) @@ -875,6 +899,9 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } + // store hole data + fwrite(holes, map.holesSize, 1, output); + fclose(output); return true; -- cgit v1.2.3 From ccb7a5a809a45bcf0ba6f5fbb59a71d475891564 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:53:21 +0200 Subject: Add config options. --- src/server/worldserver/worldserver.conf.dist | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 5d837100b0e..7366d248950 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -266,6 +266,21 @@ PlayerSave.Stats.MinLevel = 0 PlayerSave.Stats.SaveOnlyOnLogout = 1 +# +# mmap.enablePathFinding +# Description: Enable/Disable pathfinding using mmaps +# Default: 1 - (Enabled) +# 0 - (Disabled) + +mmap.enablePathFinding = 1 + +# +# mmap.ignoreMapIds +# Disable mmap pathfinding on the listed maps. +# List of map ids with delimiter ',' + +mmap.ignoreMapIds = "" + # # vmap.enableLOS # vmap.enableHeight -- cgit v1.2.3 From 2181b123ba1b45ae8725d4e06799bf3d3bee282d Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 15:55:27 +0200 Subject: Give mmap generator the correct name. --- src/tools/CMakeLists.txt | 2 +- src/tools/mmap_extractor/CMakeLists.txt | 68 -- src/tools/mmap_extractor/Info/readme.txt | 66 -- src/tools/mmap_extractor/IntermediateValues.cpp | 277 ------- src/tools/mmap_extractor/IntermediateValues.h | 53 -- src/tools/mmap_extractor/MapBuilder.cpp | 894 ----------------------- src/tools/mmap_extractor/MapBuilder.h | 129 ---- src/tools/mmap_extractor/PathCommon.h | 128 ---- src/tools/mmap_extractor/PathGenerator.cpp | 273 ------- src/tools/mmap_extractor/TerrainBuilder.cpp | 854 ---------------------- src/tools/mmap_extractor/TerrainBuilder.h | 138 ---- src/tools/mmap_extractor/VMapExtensions.cpp | 72 -- src/tools/mmaps_generator/CMakeLists.txt | 68 ++ src/tools/mmaps_generator/Info/readme.txt | 66 ++ src/tools/mmaps_generator/IntermediateValues.cpp | 277 +++++++ src/tools/mmaps_generator/IntermediateValues.h | 53 ++ src/tools/mmaps_generator/MapBuilder.cpp | 894 +++++++++++++++++++++++ src/tools/mmaps_generator/MapBuilder.h | 129 ++++ src/tools/mmaps_generator/PathCommon.h | 128 ++++ src/tools/mmaps_generator/PathGenerator.cpp | 273 +++++++ src/tools/mmaps_generator/TerrainBuilder.cpp | 854 ++++++++++++++++++++++ src/tools/mmaps_generator/TerrainBuilder.h | 138 ++++ src/tools/mmaps_generator/VMapExtensions.cpp | 72 ++ 23 files changed, 2953 insertions(+), 2953 deletions(-) delete mode 100644 src/tools/mmap_extractor/CMakeLists.txt delete mode 100644 src/tools/mmap_extractor/Info/readme.txt delete mode 100644 src/tools/mmap_extractor/IntermediateValues.cpp delete mode 100644 src/tools/mmap_extractor/IntermediateValues.h delete mode 100644 src/tools/mmap_extractor/MapBuilder.cpp delete mode 100644 src/tools/mmap_extractor/MapBuilder.h delete mode 100644 src/tools/mmap_extractor/PathCommon.h delete mode 100644 src/tools/mmap_extractor/PathGenerator.cpp delete mode 100644 src/tools/mmap_extractor/TerrainBuilder.cpp delete mode 100644 src/tools/mmap_extractor/TerrainBuilder.h delete mode 100644 src/tools/mmap_extractor/VMapExtensions.cpp create mode 100644 src/tools/mmaps_generator/CMakeLists.txt create mode 100644 src/tools/mmaps_generator/Info/readme.txt create mode 100644 src/tools/mmaps_generator/IntermediateValues.cpp create mode 100644 src/tools/mmaps_generator/IntermediateValues.h create mode 100644 src/tools/mmaps_generator/MapBuilder.cpp create mode 100644 src/tools/mmaps_generator/MapBuilder.h create mode 100644 src/tools/mmaps_generator/PathCommon.h create mode 100644 src/tools/mmaps_generator/PathGenerator.cpp create mode 100644 src/tools/mmaps_generator/TerrainBuilder.cpp create mode 100644 src/tools/mmaps_generator/TerrainBuilder.h create mode 100644 src/tools/mmaps_generator/VMapExtensions.cpp (limited to 'src') diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index f4c5f695b26..2d378966aff 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -11,4 +11,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) -add_subdirectory(mmaps_extractor) +add_subdirectory(mmaps_generator) diff --git a/src/tools/mmap_extractor/CMakeLists.txt b/src/tools/mmap_extractor/CMakeLists.txt deleted file mode 100644 index c7c1a954371..00000000000 --- a/src/tools/mmap_extractor/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2008-2011 Trinity -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -file(GLOB_RECURSE sources *.cpp *.h) - -# definitions -add_definitions(-DNO_CORE_FUNCS) -add_definitions(-DDEBUG) -add_definitions(-DNO_vsnprintf) - -include_directories( - ${CMAKE_BINARY_DIR} - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/zlib - ${CMAKE_SOURCE_DIR}/dep/bzip2 - ${CMAKE_SOURCE_DIR}/dep/acelite - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/src/server/game/Maps - ${CMAKE_SOURCE_DIR}/src/server/game/DataStores - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints - ${CMAKE_SOURCE_DIR}/src/server/game/Grids - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells - ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous - ${CMAKE_SOURCE_DIR}/src/server/game/Conditions - ${CMAKE_SOURCE_DIR}/src/server/collision - ${CMAKE_SOURCE_DIR}/src/server/collision/Management - ${CMAKE_SOURCE_DIR}/src/server/collision/Maps - ${CMAKE_SOURCE_DIR}/src/server/collision/Models -) - -add_executable(movements_extractor ${sources}) - -target_link_libraries(movements_extractor - ${MYSQL_LIBRARY} - ${ACE_LIBRARY} - ${BZIP2_LIBRARIES} - ${ZLIB_LIBRARIES} - Recast - Detour - collision - g3dlib - shared -) - -if( UNIX ) - install(TARGETS movements_extractor DESTINATION bin) -elseif( WIN32 ) - install(TARGETS movements_extractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() diff --git a/src/tools/mmap_extractor/Info/readme.txt b/src/tools/mmap_extractor/Info/readme.txt deleted file mode 100644 index 8d7c4f9d2e0..00000000000 --- a/src/tools/mmap_extractor/Info/readme.txt +++ /dev/null @@ -1,66 +0,0 @@ -Generator command line args - ---offMeshInput [file.*] Path to file containing off mesh connections data. - Format must be: (see offmesh_example.txt) - "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" - Single mesh connection per line. - ---silent Make us script friendly. Do not wait for user input - on error or completion. - ---bigBaseUnit [true|false] Generate tile/map using bigger basic unit. - Use this option only if you have unexpected gaps. - - false: use normal metrics (default) - ---maxAngle [#] Max walkable inclination angle - - float between 45 and 90 degrees (default 60) - ---skipLiquid liquid data for maps - - false: include liquid data (default) - ---skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), - 1 (Kalimdor), 530 (Outlands), 571 (Northrend) - - false: build continents (default) - ---skipJunkMaps [true|false] junk maps include some unused - maps, transport maps, and some other - - true: skip junk maps (default) - ---skipBattlegrounds [true|false] does not include PVP arenas - - false: skip battlegrounds (default) - ---debugOutput [true|false] create debugging files for use with RecastDemo - if you are only creating mmaps for use with MaNGOS, - you don't want debugging files - - false: don't create debugging files (default) - ---tile [#,#] Build the specified tile - seperate number with a comma ',' - must specify a map number (see below) - if this option is not used, all tiles are built - - [#] Build only the map specified by # - this command will build the map regardless of --skip* option settings - if you do not specify a map number, builds all maps that pass the filters specified by --skip* options - - -examples: - -movement_extractor -builds maps using the default settings (see above for defaults) - -movement_extractor --skipContinents true -builds the default maps, except continents - -movement_extractor 0 -builds all tiles of map 0 - -movement_extractor 0 --tile 34,46 -builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmap_extractor/IntermediateValues.cpp b/src/tools/mmap_extractor/IntermediateValues.cpp deleted file mode 100644 index 9eefb1e65f0..00000000000 --- a/src/tools/mmap_extractor/IntermediateValues.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#include "IntermediateValues.h" - -namespace MMAP -{ - IntermediateValues::~IntermediateValues() - { - rcFreeCompactHeightfield(compactHeightfield); - rcFreeHeightField(heightfield); - rcFreeContourSet(contours); - rcFreePolyMesh(polyMesh); - rcFreePolyMeshDetail(polyMeshDetail); - } - - void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) - { - char fileName[255]; - char tileString[25]; - sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); - - printf("%sWriting debug output... \r", tileString); - - string name("meshes/%03u%02i%02i."); - -#define DEBUG_WRITE(fileExtension,data) \ - do { \ - sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ - FILE* file = fopen(fileName, "wb"); \ - if (!file) \ - { \ - char message[1024]; \ - sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ - perror(message); \ - } \ - else \ - debugWrite(file, data); \ - if (file) fclose(file); \ - printf("%sWriting debug output... \r", tileString); \ - } while (false) - - if (heightfield) - DEBUG_WRITE("hf", heightfield); - if (compactHeightfield) - DEBUG_WRITE("chf", compactHeightfield); - if (contours) - DEBUG_WRITE("cs", contours); - if (polyMesh) - DEBUG_WRITE("pmesh", polyMesh); - if (polyMeshDetail) - DEBUG_WRITE("dmesh", polyMeshDetail); - -#undef DEBUG_WRITE - } - - void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->cs), sizeof(float), 1, file); - fwrite(&(mesh->ch), sizeof(float), 1, file); - fwrite(&(mesh->width), sizeof(int), 1, file); - fwrite(&(mesh->height), sizeof(int), 1, file); - fwrite(mesh->bmin, sizeof(float), 3, file); - fwrite(mesh->bmax, sizeof(float), 3, file); - - for (int y = 0; y < mesh->height; ++y) - for (int x = 0; x < mesh->width; ++x) - { - rcSpan* span = mesh->spans[x+y*mesh->width]; - - // first, count the number of spans - int spanCount = 0; - while (span) - { - spanCount++; - span = span->next; - } - - // write the span count - fwrite(&spanCount, sizeof(int), 1, file); - - // write the spans - span = mesh->spans[x+y*mesh->width]; - while (span) - { - fwrite(span, sizeof(rcSpan), 1, file); - span = span->next; - } - } - } - - void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) - { - if (!file | !chf) - return; - - fwrite(&(chf->width), sizeof(chf->width), 1, file); - fwrite(&(chf->height), sizeof(chf->height), 1, file); - fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); - - fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); - fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); - - fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); - fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); - - fwrite(chf->bmin, sizeof(chf->bmin), 1, file); - fwrite(chf->bmax, sizeof(chf->bmax), 1, file); - - fwrite(&(chf->cs), sizeof(chf->cs), 1, file); - fwrite(&(chf->ch), sizeof(chf->ch), 1, file); - - int tmp = 0; - if (chf->cells) tmp |= 1; - if (chf->spans) tmp |= 2; - if (chf->dist) tmp |= 4; - if (chf->areas) tmp |= 8; - - fwrite(&tmp, sizeof(tmp), 1, file); - - if (chf->cells) - fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); - if (chf->spans) - fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); - if (chf->dist) - fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); - if (chf->areas) - fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); - } - - void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) - { - if (!file || !cs) - return; - - fwrite(&(cs->cs), sizeof(float), 1, file); - fwrite(&(cs->ch), sizeof(float), 1, file); - fwrite(cs->bmin, sizeof(float), 3, file); - fwrite(cs->bmax, sizeof(float), 3, file); - fwrite(&(cs->nconts), sizeof(int), 1, file); - for (int i = 0; i < cs->nconts; ++i) - { - fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); - fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); - fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); - fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); - fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); - fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); - } - } - - void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->cs), sizeof(float), 1, file); - fwrite(&(mesh->ch), sizeof(float), 1, file); - fwrite(&(mesh->nvp), sizeof(int), 1, file); - fwrite(mesh->bmin, sizeof(float), 3, file); - fwrite(mesh->bmax, sizeof(float), 3, file); - fwrite(&(mesh->nverts), sizeof(int), 1, file); - fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); - fwrite(&(mesh->npolys), sizeof(int), 1, file); - fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); - fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); - fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); - fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); - } - - void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) - { - if (!file || !mesh) - return; - - fwrite(&(mesh->nverts), sizeof(int), 1, file); - fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); - fwrite(&(mesh->ntris), sizeof(int), 1, file); - fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); - fwrite(&(mesh->nmeshes), sizeof(int), 1, file); - fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); - } - - void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - char objFileName[255]; - sprintf(objFileName, "meshes/map%03u.obj", mapID); - - FILE* objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - G3D::Array allVerts; - G3D::Array allTris; - - allTris.append(meshData.liquidTris); - allVerts.append(meshData.liquidVerts); - TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); - allVerts.append(meshData.solidVerts); - - float* verts = allVerts.getCArray(); - int vertCount = allVerts.size() / 3; - int* tris = allTris.getCArray(); - int triCount = allTris.size() / 3; - - for (int i = 0; i < allVerts.size() / 3; i++) - fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); - - for (int i = 0; i < allTris.size() / 3; i++) - fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); - - fclose(objFile); - - - char tileString[25]; - sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); - printf("%sWriting debug output... \r", tileString); - - sprintf(objFileName, "meshes/%03u.map", mapID); - - objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - char b = '\0'; - fwrite(&b, sizeof(char), 1, objFile); - fclose(objFile); - - sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); - objFile = fopen(objFileName, "wb"); - if (!objFile) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); - perror(message); - return; - } - - fwrite(&vertCount, sizeof(int), 1, objFile); - fwrite(verts, sizeof(float), vertCount*3, objFile); - fflush(objFile); - - fwrite(&triCount, sizeof(int), 1, objFile); - fwrite(tris, sizeof(int), triCount*3, objFile); - fflush(objFile); - - fclose(objFile); - } -} diff --git a/src/tools/mmap_extractor/IntermediateValues.h b/src/tools/mmap_extractor/IntermediateValues.h deleted file mode 100644 index a267a0f6412..00000000000 --- a/src/tools/mmap_extractor/IntermediateValues.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#ifndef _INTERMEDIATE_VALUES_H -#define _INTERMEDIATE_VALUES_H - -#include "PathCommon.h" -#include "TerrainBuilder.h" -#include "Recast.h" -#include "DetourNavMesh.h" - -namespace MMAP -{ - // this class gathers all debug info holding and output - struct IntermediateValues - { - rcHeightfield* heightfield; - rcCompactHeightfield* compactHeightfield; - rcContourSet* contours; - rcPolyMesh* polyMesh; - rcPolyMeshDetail* polyMeshDetail; - - IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), - contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} - ~IntermediateValues(); - - void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); - - void debugWrite(FILE* file, const rcHeightfield* mesh); - void debugWrite(FILE* file, const rcCompactHeightfield* chf); - void debugWrite(FILE* file, const rcContourSet* cs); - void debugWrite(FILE* file, const rcPolyMesh* mesh); - void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); - - void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - }; -} -#endif diff --git a/src/tools/mmap_extractor/MapBuilder.cpp b/src/tools/mmap_extractor/MapBuilder.cpp deleted file mode 100644 index 3ca158f0127..00000000000 --- a/src/tools/mmap_extractor/MapBuilder.cpp +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#include "PathCommon.h" -#include "MapBuilder.h" - -#include "MapTree.h" -#include "ModelInstance.h" -#include "LoginDatabase.h" - -#include "DetourNavMeshBuilder.h" -#include "DetourCommon.h" - -// These make the linker happy. -LoginDatabaseWorkerPool LoginDatabase; -#include "DisableMgr.h" -namespace DisableMgr -{ - bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) - { - return 0; - } -} - -using namespace VMAP; - -namespace MMAP -{ - MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, - bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, - bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : - m_terrainBuilder(NULL), - m_debugOutput (debugOutput), - m_skipContinents (skipContinents), - m_skipJunkMaps (skipJunkMaps), - m_skipBattlegrounds (skipBattlegrounds), - m_maxWalkableAngle (maxWalkableAngle), - m_bigBaseUnit (bigBaseUnit), - m_rcContext (NULL), - m_offMeshFilePath (offMeshFilePath) - { - m_terrainBuilder = new TerrainBuilder(skipLiquid); - - m_rcContext = new rcContext(false); - - discoverTiles(); - } - - /**************************************************************************/ - MapBuilder::~MapBuilder() - { - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - (*it).second->clear(); - delete (*it).second; - } - - delete m_terrainBuilder; - delete m_rcContext; - } - - /**************************************************************************/ - void MapBuilder::discoverTiles() - { - vector files; - uint32 mapID, tileX, tileY, tileID, count = 0; - char filter[12]; - - printf("Discovering maps... "); - getDirContents(files, "maps"); - for (uint32 i = 0; i < files.size(); ++i) - { - mapID = uint32(atoi(files[i].substr(0,3).c_str())); - if (m_tiles.find(mapID) == m_tiles.end()) - { - m_tiles.insert(pair*>(mapID, new set)); - count++; - } - } - - files.clear(); - getDirContents(files, "vmaps", "*.vmtree"); - for (uint32 i = 0; i < files.size(); ++i) - { - mapID = uint32(atoi(files[i].substr(0,3).c_str())); - m_tiles.insert(pair*>(mapID, new set)); - count++; - } - printf("found %u.\n", count); - - count = 0; - printf("Discovering tiles... "); - for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) - { - set* tiles = (*itr).second; - mapID = (*itr).first; - - sprintf(filter, "%03u*.vmtile", mapID); - files.clear(); - getDirContents(files, "vmaps", filter); - for (uint32 i = 0; i < files.size(); ++i) - { - tileX = uint32(atoi(files[i].substr(7,2).c_str())); - tileY = uint32(atoi(files[i].substr(4,2).c_str())); - tileID = StaticMapTree::packTileID(tileY, tileX); - - tiles->insert(tileID); - count++; - } - - sprintf(filter, "%03u*", mapID); - files.clear(); - getDirContents(files, "maps", filter); - for (uint32 i = 0; i < files.size(); ++i) - { - tileY = uint32(atoi(files[i].substr(3,2).c_str())); - tileX = uint32(atoi(files[i].substr(5,2).c_str())); - tileID = StaticMapTree::packTileID(tileX, tileY); - - if (tiles->insert(tileID).second) - count++; - } - } - printf("found %u.\n\n", count); - } - - /**************************************************************************/ - set* MapBuilder::getTileList(uint32 mapID) - { - TileList::iterator itr = m_tiles.find(mapID); - if (itr != m_tiles.end()) - return (*itr).second; - - set* tiles = new set(); - m_tiles.insert(pair*>(mapID, tiles)); - return tiles; - } - - /**************************************************************************/ - void MapBuilder::buildAllMaps() - { - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - uint32 mapID = (*it).first; - if (!shouldSkipMap(mapID)) - buildMap(mapID); - } - } - - /**************************************************************************/ - void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) - { - maxX = INT_MAX; - maxY = INT_MAX; - minX = INT_MIN; - minY = INT_MIN; - - float bmin[3], bmax[3], lmin[3], lmax[3]; - MeshData meshData; - - // make sure we process maps which don't have tiles - // initialize the static tree, which loads WDT models - if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() && meshData.liquidVerts.size()) - { - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - rcVmin(bmin, lmin); - rcVmax(bmax, lmax); - } - else if (meshData.solidVerts.size()) - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - else - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - - // convert coord bounds to grid bounds - maxX = 32 - bmin[0] / GRID_SIZE; - maxY = 32 - bmin[2] / GRID_SIZE; - minX = 32 - bmax[0] / GRID_SIZE; - minY = 32 - bmax[2] / GRID_SIZE; - } - - /**************************************************************************/ - void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) - { - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) - { - printf("Failed creating navmesh! \n"); - return; - } - - buildTile(mapID, tileX, tileY, navMesh); - dtFreeNavMesh(navMesh); - } - - /**************************************************************************/ - void MapBuilder::buildMap(uint32 mapID) - { - printf("Building map %03u:\n", mapID); - - set* tiles = getTileList(mapID); - - // make sure we process maps which don't have tiles - if (!tiles->size()) - { - // convert coord bounds to grid bounds - uint32 minX, minY, maxX, maxY; - getGridBounds(mapID, minX, minY, maxX, maxY); - - // add all tiles within bounds to tile list. - for (uint32 i = minX; i <= maxX; ++i) - for (uint32 j = minY; j <= maxY; ++j) - tiles->insert(StaticMapTree::packTileID(i, j)); - } - - if (!tiles->size()) - return; - - // build navMesh - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) - { - printf("Failed creating navmesh! \n"); - return; - } - - // now start building mmtiles for each tile - printf("We have %u tiles. \n", (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - uint32 tileX, tileY; - - // unpack tile coords - StaticMapTree::unpackTileID((*it), tileX, tileY); - - if (shouldSkipTile(mapID, tileX, tileY)) - continue; - - buildTile(mapID, tileX, tileY, navMesh); - } - - dtFreeNavMesh(navMesh); - - printf("Complete! \n\n"); - } - - /**************************************************************************/ - void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) - { - printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); - - MeshData meshData; - - // get heightmap data - m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); - - // get model data - m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); - - // if there is no data, give up now - if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) - return; - - // remove unused vertices - TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); - TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); - - // gather all mesh data for final data check, and bounds calculation - G3D::Array allVerts; - allVerts.append(meshData.liquidVerts); - allVerts.append(meshData.solidVerts); - - if (!allVerts.size()) - return; - - // get bounds of current tile - float bmin[3], bmax[3]; - getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); - - m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); - - // build navmesh tile - buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); - } - - /**************************************************************************/ - void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) - { - set* tiles = getTileList(mapID); - - // old code for non-statically assigned bitmask sizes: - ///*** calculate number of bits needed to store tiles & polys ***/ - //int tileBits = dtIlog2(dtNextPow2(tiles->size())); - //if (tileBits < 1) tileBits = 1; // need at least one bit! - //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; - - int tileBits = STATIC_TILE_BITS; - int polyBits = STATIC_POLY_BITS; - - int maxTiles = tiles->size(); - int maxPolysPerTile = 1 << polyBits; - - /*** calculate bounds of map ***/ - - uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - StaticMapTree::unpackTileID((*it), tileX, tileY); - - if (tileX > tileXMax) - tileXMax = tileX; - else if (tileX < tileXMin) - tileXMin = tileX; - - if (tileY > tileYMax) - tileYMax = tileY; - else if (tileY < tileYMin) - tileYMin = tileY; - } - - // use Max because '32 - tileX' is negative for values over 32 - float bmin[3], bmax[3]; - getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); - - /*** now create the navmesh ***/ - - // navmesh creation params - dtNavMeshParams navMeshParams; - memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); - navMeshParams.tileWidth = GRID_SIZE; - navMeshParams.tileHeight = GRID_SIZE; - rcVcopy(navMeshParams.orig, bmin); - navMeshParams.maxTiles = maxTiles; - navMeshParams.maxPolys = maxPolysPerTile; - - navMesh = dtAllocNavMesh(); - printf("Creating navMesh... \r"); - if (!navMesh->init(&navMeshParams)) - { - printf("Failed creating navmesh! \n"); - return; - } - - char fileName[25]; - sprintf(fileName, "mmaps/%03u.mmap", mapID); - - FILE* file = fopen(fileName, "wb"); - if (!file) - { - dtFreeNavMesh(navMesh); - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); - perror(message); - return; - } - - // now that we know navMesh params are valid, we can write them to file - fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); - fclose(file); - } - - /**************************************************************************/ - void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, - MeshData &meshData, float bmin[3], float bmax[3], - dtNavMesh* navMesh) - { - // console output - char tileString[10]; - sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); - printf("%s Building movemap tiles... \r", tileString); - - IntermediateValues iv; - - float* tVerts = meshData.solidVerts.getCArray(); - int tVertCount = meshData.solidVerts.size() / 3; - int* tTris = meshData.solidTris.getCArray(); - int tTriCount = meshData.solidTris.size() / 3; - - float* lVerts = meshData.liquidVerts.getCArray(); - int lVertCount = meshData.liquidVerts.size() / 3; - int* lTris = meshData.liquidTris.getCArray(); - int lTriCount = meshData.liquidTris.size() / 3; - uint8* lTriFlags = meshData.liquidType.getCArray(); - - // these are WORLD UNIT based metrics - // this are basic unit dimentions - // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) - const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; - - // All are in UNIT metrics! - const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); - const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP - const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; - - rcConfig config; - memset(&config, 0, sizeof(rcConfig)); - - rcVcopy(config.bmin, bmin); - rcVcopy(config.bmax, bmax); - - config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; - config.cs = BASE_UNIT_DIM; - config.ch = BASE_UNIT_DIM; - config.walkableSlopeAngle = m_maxWalkableAngle; - config.tileSize = VERTEX_PER_TILE; - config.walkableRadius = m_bigBaseUnit ? 1 : 2; - config.borderSize = config.walkableRadius + 3; - config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize - config.walkableHeight = m_bigBaseUnit ? 3 : 6; - config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight - config.minRegionArea = rcSqr(60); - config.mergeRegionArea = rcSqr(50); - config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) - config.detailSampleDist = config.cs * 64; - config.detailSampleMaxError = config.ch * 2; - - // this sets the dimensions of the heightfield - should maybe happen before border padding - rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); - - // allocate subregions : tiles - Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; - - // Initialize per tile config. - rcConfig tileCfg; - memcpy(&tileCfg, &config, sizeof(rcConfig)); - tileCfg.width = config.tileSize + config.borderSize*2; - tileCfg.height = config.tileSize + config.borderSize*2; - - // build all tiles - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; - - // Calculate the per tile bounding box. - tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; - tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; - - float tbmin[2], tbmax[2]; - tbmin[0] = tileCfg.bmin[0]; - tbmin[1] = tileCfg.bmin[2]; - tbmax[0] = tileCfg.bmax[0]; - tbmax[1] = tileCfg.bmax[2]; - - // build heightfield - tile.solid = rcAllocHeightfield(); - if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) - { - printf("%sFailed building heightfield! \n", tileString); - continue; - } - - // mark all walkable tiles, both liquids and solids - unsigned char* triFlags = new unsigned char[tTriCount]; - memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); - rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); - rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); - delete [] triFlags; - - rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); - rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); - rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); - - rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); - - // compact heightfield spans - tile.chf = rcAllocCompactHeightfield(); - if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) - { - printf("%sFailed compacting heightfield! \n", tileString); - continue; - } - - // build polymesh intermediates - if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) - { - printf("%sFailed eroding area! \n", tileString); - continue; - } - - if (!rcBuildDistanceField(m_rcContext, *tile.chf)) - { - printf("%sFailed building distance field! \n", tileString); - continue; - } - - if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) - { - printf("%sFailed building regions! \n", tileString); - continue; - } - - tile.cset = rcAllocContourSet(); - if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) - { - printf("%sFailed building contours! \n", tileString); - continue; - } - - // build polymesh - tile.pmesh = rcAllocPolyMesh(); - if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) - { - printf("%sFailed building polymesh! \n", tileString); - continue; - } - - tile.dmesh = rcAllocPolyMeshDetail(); - if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) - { - printf("%sFailed building polymesh detail! \n", tileString); - continue; - } - - // free those up - // we may want to keep them in the future for debug - // but right now, we don't have the code to merge them - rcFreeHeightField(tile.solid); - tile.solid = NULL; - rcFreeCompactHeightfield(tile.chf); - tile.chf = NULL; - rcFreeContourSet(tile.cset); - tile.cset = NULL; - } - } - - // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; - if (!pmmerge) - { - printf("%s alloc pmmerge FIALED! \r", tileString); - return; - } - - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; - if (!dmmerge) - { - printf("%s alloc dmmerge FIALED! \r", tileString); - return; - } - - int nmerge = 0; - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; - if (tile.pmesh) - { - pmmerge[nmerge] = tile.pmesh; - dmmerge[nmerge] = tile.dmesh; - nmerge++; - } - } - } - - iv.polyMesh = rcAllocPolyMesh(); - if (!iv.polyMesh) - { - printf("%s alloc iv.polyMesh FIALED! \r", tileString); - return; - } - rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); - - iv.polyMeshDetail = rcAllocPolyMeshDetail(); - if (!iv.polyMeshDetail) - { - printf("%s alloc m_dmesh FIALED! \r", tileString); - return; - } - rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); - - // free things up - delete [] pmmerge; - delete [] dmmerge; - - delete [] tiles; - - // remove padding for extraction - for (int i = 0; i < iv.polyMesh->nverts; ++i) - { - unsigned short* v = &iv.polyMesh->verts[i*3]; - v[0] -= (unsigned short)config.borderSize; - v[2] -= (unsigned short)config.borderSize; - } - - // set polygons as walkable - // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off - for (int i = 0; i < iv.polyMesh->npolys; ++i) - if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) - iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; - - // setup mesh parameters - dtNavMeshCreateParams params; - memset(¶ms, 0, sizeof(params)); - params.verts = iv.polyMesh->verts; - params.vertCount = iv.polyMesh->nverts; - params.polys = iv.polyMesh->polys; - params.polyAreas = iv.polyMesh->areas; - params.polyFlags = iv.polyMesh->flags; - params.polyCount = iv.polyMesh->npolys; - params.nvp = iv.polyMesh->nvp; - params.detailMeshes = iv.polyMeshDetail->meshes; - params.detailVerts = iv.polyMeshDetail->verts; - params.detailVertsCount = iv.polyMeshDetail->nverts; - params.detailTris = iv.polyMeshDetail->tris; - params.detailTriCount = iv.polyMeshDetail->ntris; - - params.offMeshConVerts = meshData.offMeshConnections.getCArray(); - params.offMeshConCount = meshData.offMeshConnections.size()/6; - params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); - params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); - params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); - params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); - - params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height - params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius - params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! - params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; - params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; - rcVcopy(params.bmin, bmin); - rcVcopy(params.bmax, bmax); - params.cs = config.cs; - params.ch = config.ch; - params.tileSize = VERTEX_PER_MAP; - - // will hold final navmesh - unsigned char* navData = NULL; - int navDataSize = 0; - - do - { - // these values are checked within dtCreateNavMeshData - handle them here - // so we have a clear error message - if (params.nvp > DT_VERTS_PER_POLYGON) - { - printf("%s Invalid verts-per-polygon value! \n", tileString); - continue; - } - if (params.vertCount >= 0xffff) - { - printf("%s Too many vertices! \n", tileString); - continue; - } - if (!params.vertCount || !params.verts) - { - // occurs mostly when adjacent tiles have models - // loaded but those models don't span into this tile - - // message is an annoyance - //printf("%sNo vertices to build tile! \n", tileString); - continue; - } - if (!params.polyCount || !params.polys || - TILES_PER_MAP*TILES_PER_MAP == params.polyCount) - { - // we have flat tiles with no actual geometry - don't build those, its useless - // keep in mind that we do output those into debug info - // drop tiles with only exact count - some tiles may have geometry while having less tiles - printf("%s No polygons to build on tile! \n", tileString); - continue; - } - if (!params.detailMeshes || !params.detailVerts || !params.detailTris) - { - printf("%s No detail mesh to build tile! \n", tileString); - continue; - } - - printf("%s Building navmesh tile... \r", tileString); - if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) - { - printf("%s Failed building navmesh tile! \n", tileString); - continue; - } - - dtTileRef tileRef = 0; - printf("%s Adding tile to navmesh... \r", tileString); - // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile - // is removed via removeTile() - dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef); - if (!tileRef || dtResult != DT_SUCCESS) - { - printf("%s Failed adding tile to navmesh! \n", tileString); - continue; - } - - // file output - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "wb"); - if (!file) - { - char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); - perror(message); - navMesh->removeTile(tileRef, NULL, NULL); - continue; - } - - printf("%s Writing to file... \r", tileString); - - // write header - MmapTileHeader header; - header.usesLiquids = m_terrainBuilder->usesLiquids(); - header.size = uint32(navDataSize); - fwrite(&header, sizeof(MmapTileHeader), 1, file); - - // write data - fwrite(navData, sizeof(unsigned char), navDataSize, file); - fclose(file); - - // now that tile is written to disk, we can unload it - navMesh->removeTile(tileRef, NULL, NULL); - } - while (0); - - if (m_debugOutput) - { - // restore padding so that the debug visualization is correct - for (int i = 0; i < iv.polyMesh->nverts; ++i) - { - unsigned short* v = &iv.polyMesh->verts[i*3]; - v[0] += (unsigned short)config.borderSize; - v[2] += (unsigned short)config.borderSize; - } - - iv.generateObjFile(mapID, tileX, tileY, meshData); - iv.writeIV(mapID, tileX, tileY); - } - } - - /**************************************************************************/ - void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) - { - // this is for elevation - if (verts && vertCount) - rcCalcBounds(verts, vertCount, bmin, bmax); - else - { - bmin[1] = FLT_MIN; - bmax[1] = FLT_MAX; - } - - // this is for width and depth - bmax[0] = (32 - int(tileX)) * GRID_SIZE; - bmax[2] = (32 - int(tileY)) * GRID_SIZE; - bmin[0] = bmax[0] - GRID_SIZE; - bmin[2] = bmax[2] - GRID_SIZE; - } - - /**************************************************************************/ - bool MapBuilder::shouldSkipMap(uint32 mapID) - { - if (m_skipContinents) - switch (mapID) - { - case 0: - case 1: - case 530: - case 571: - return true; - default: - break; - } - - if (m_skipJunkMaps) - switch (mapID) - { - case 13: // test.wdt - case 25: // ScottTest.wdt - case 29: // Test.wdt - case 42: // Colin.wdt - case 169: // EmeraldDream.wdt (unused, and very large) - case 451: // development.wdt - case 573: // ExteriorTest.wdt - case 597: // CraigTest.wdt - case 605: // development_nonweighted.wdt - case 606: // QA_DVD.wdt - return true; - default: - if (isTransportMap(mapID)) - return true; - break; - } - - if (m_skipBattlegrounds) - switch (mapID) - { - case 30: // AV - case 37: // ? - case 489: // WSG - case 529: // AB - case 566: // EotS - case 607: // SotA - case 628: // IoC - return true; - default: - break; - } - - return false; - } - - /**************************************************************************/ - bool MapBuilder::isTransportMap(uint32 mapID) - { - switch (mapID) - { - // transport maps - case 582: - case 584: - case 586: - case 587: - case 588: - case 589: - case 590: - case 591: - case 592: - case 593: - case 594: - case 596: - case 610: - case 612: - case 613: - case 614: - case 620: - case 621: - case 622: - case 623: - case 641: - case 642: - case 647: - case 672: - case 673: - case 712: - case 713: - case 718: - return true; - default: - return false; - } - } - - /**************************************************************************/ - bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) - { - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "rb"); - if (!file) - return false; - - MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, file); - fclose(file); - - if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) - return false; - - if (header.mmapVersion != MMAP_VERSION) - return false; - - return true; - } - -} diff --git a/src/tools/mmap_extractor/MapBuilder.h b/src/tools/mmap_extractor/MapBuilder.h deleted file mode 100644 index d0f33ce9a79..00000000000 --- a/src/tools/mmap_extractor/MapBuilder.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#ifndef _MAP_BUILDER_H -#define _MAP_BUILDER_H - -#include -#include -#include - -#include "TerrainBuilder.h" -#include "IntermediateValues.h" - -#include "IVMapManager.h" -#include "WorldModel.h" - -#include "Recast.h" -#include "DetourNavMesh.h" - -using namespace std; -using namespace VMAP; - -// G3D namespace typedefs conflicts with ACE typedefs - -namespace MMAP -{ - typedef map*> TileList; - struct Tile - { - Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} - ~Tile() - { - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - rcFreeHeightField(solid); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - } - rcCompactHeightfield* chf; - rcHeightfield* solid; - rcContourSet* cset; - rcPolyMesh* pmesh; - rcPolyMeshDetail* dmesh; - }; - - class MapBuilder - { - public: - MapBuilder(float maxWalkableAngle = 60.f, - bool skipLiquid = false, - bool skipContinents = false, - bool skipJunkMaps = true, - bool skipBattlegrounds = false, - bool debugOutput = false, - bool bigBaseUnit = false, - const char* offMeshFilePath = NULL); - - ~MapBuilder(); - - // builds all mmap tiles for the specified map id (ignores skip settings) - void buildMap(uint32 mapID); - - // builds an mmap tile for the specified map and its mesh - void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); - - // builds list of maps, then builds all of mmap tiles (based on the skip settings) - void buildAllMaps(); - - private: - // detect maps and tiles - void discoverTiles(); - set* getTileList(uint32 mapID); - - void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); - - void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); - - // move map building - void buildMoveMapTile(uint32 mapID, - uint32 tileX, - uint32 tileY, - MeshData &meshData, - float bmin[3], - float bmax[3], - dtNavMesh* navMesh); - - void getTileBounds(uint32 tileX, uint32 tileY, - float* verts, int vertCount, - float* bmin, float* bmax); - void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); - - bool shouldSkipMap(uint32 mapID); - bool isTransportMap(uint32 mapID); - bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); - - TerrainBuilder* m_terrainBuilder; - TileList m_tiles; - - bool m_debugOutput; - - const char* m_offMeshFilePath; - bool m_skipContinents; - bool m_skipJunkMaps; - bool m_skipBattlegrounds; - - float m_maxWalkableAngle; - bool m_bigBaseUnit; - - // build performance - not really used for now - rcContext* m_rcContext; - }; -} - -#endif diff --git a/src/tools/mmap_extractor/PathCommon.h b/src/tools/mmap_extractor/PathCommon.h deleted file mode 100644 index fd02ec02d50..00000000000 --- a/src/tools/mmap_extractor/PathCommon.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#ifndef _MMAP_COMMON_H -#define _MMAP_COMMON_H - -#include -#include - -#include "Define.h" - -#ifndef _WIN32 - #include - #include -#endif - -#ifdef __linux__ - #include -#endif - -using namespace std; - -namespace MMAP -{ - inline bool matchWildcardFilter(const char* filter, const char* str) - { - if (!filter || !str) - return false; - - // end on null character - while (*filter && *str) - { - if (*filter == '*') - { - if (*++filter == '\0') // wildcard at end of filter means all remaing chars match - return true; - - while (true) - { - if (*filter == *str) - break; - if (*str == '\0') - return false; // reached end of string without matching next filter character - str++; - } - } - else if (*filter != *str) - return false; // mismatch - - filter++; - str++; - } - - return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); - } - - enum ListFilesResult - { - LISTFILE_DIRECTORY_NOT_FOUND = 0, - LISTFILE_OK = 1 - }; - - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) - { - #ifdef WIN32 - HANDLE hFind; - WIN32_FIND_DATA findFileInfo; - string directory; - - directory = dirpath + "/" + filter; - - hFind = FindFirstFile(directory.c_str(), &findFileInfo); - - if (hFind == INVALID_HANDLE_VALUE) - return LISTFILE_DIRECTORY_NOT_FOUND; - do - { - if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - fileList.push_back(string(findFileInfo.cFileName)); - } - while (FindNextFile(hFind, &findFileInfo)); - - FindClose(hFind); - - #else - const char *p = dirpath.c_str(); - DIR * dirp = opendir(p); - struct dirent * dp; - dirp = opendir(p); - - while (dirp) - { - errno = 0; - if ((dp = readdir(dirp)) != NULL) - { - if (matchWildcardFilter(filter.c_str(), dp->d_name)) - fileList.push_back(string(dp->d_name)); - } - else - break; - } - - if (dirp) - closedir(dirp); - else - return LISTFILE_DIRECTORY_NOT_FOUND; - #endif - - return LISTFILE_OK; - } -} - -#endif diff --git a/src/tools/mmap_extractor/PathGenerator.cpp b/src/tools/mmap_extractor/PathGenerator.cpp deleted file mode 100644 index 2eb2c6545c4..00000000000 --- a/src/tools/mmap_extractor/PathGenerator.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2005-2011 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 "PathCommon.h" -#include "MapBuilder.h" - -using namespace MMAP; - -bool checkDirectories(bool debugOutput) -{ - vector dirFiles; - - if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) - { - printf("'maps' directory is empty or does not exist\n"); - return false; - } - - dirFiles.clear(); - if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) - { - printf("'vmaps' directory is empty or does not exist\n"); - return false; - } - - dirFiles.clear(); - if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) - { - printf("'mmaps' directory does not exist\n"); - return false; - } - - dirFiles.clear(); - if (debugOutput) - { - if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) - { - printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); - return false; - } - } - - return true; -} - -bool handleArgs(int argc, char** argv, - int &mapnum, - int &tileX, - int &tileY, - float &maxAngle, - bool &skipLiquid, - bool &skipContinents, - bool &skipJunkMaps, - bool &skipBattlegrounds, - bool &debugOutput, - bool &silent, - bool &bigBaseUnit, - char* &offMeshInputPath) -{ - char* param = NULL; - for (int i = 1; i < argc; ++i) - { - if (strcmp(argv[i], "--maxAngle") == 0) - { - param = argv[++i]; - if (!param) - return false; - - float maxangle = atof(param); - if (maxangle <= 90.f && maxangle >= 45.f) - maxAngle = maxangle; - else - printf("invalid option for '--maxAngle', using default\n"); - } - else if (strcmp(argv[i], "--tile") == 0) - { - param = argv[++i]; - if (!param) - return false; - - char* stileX = strtok(param, ","); - char* stileY = strtok(NULL, ","); - int tilex = atoi(stileX); - int tiley = atoi(stileY); - - if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) - tileX = tilex; - if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) - tileY = tiley; - - if (tileX < 0 || tileY < 0) - { - printf("invalid tile coords.\n"); - return false; - } - } - else if (strcmp(argv[i], "--skipLiquid") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipLiquid = true; - else if (strcmp(param, "false") == 0) - skipLiquid = false; - else - printf("invalid option for '--skipLiquid', using default\n"); - } - else if (strcmp(argv[i], "--skipContinents") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipContinents = true; - else if (strcmp(param, "false") == 0) - skipContinents = false; - else - printf("invalid option for '--skipContinents', using default\n"); - } - else if (strcmp(argv[i], "--skipJunkMaps") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipJunkMaps = true; - else if (strcmp(param, "false") == 0) - skipJunkMaps = false; - else - printf("invalid option for '--skipJunkMaps', using default\n"); - } - else if (strcmp(argv[i], "--skipBattlegrounds") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipBattlegrounds = true; - else if (strcmp(param, "false") == 0) - skipBattlegrounds = false; - else - printf("invalid option for '--skipBattlegrounds', using default\n"); - } - else if (strcmp(argv[i], "--debugOutput") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - debugOutput = true; - else if (strcmp(param, "false") == 0) - debugOutput = false; - else - printf("invalid option for '--debugOutput', using default true\n"); - } - else if (strcmp(argv[i], "--silent") == 0) - { - silent = true; - } - else if (strcmp(argv[i], "--bigBaseUnit") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - bigBaseUnit = true; - else if (strcmp(param, "false") == 0) - bigBaseUnit = false; - else - printf("invalid option for '--bigBaseUnit', using default false\n"); - } - else if (strcmp(argv[i], "--offMeshInput") == 0) - { - param = argv[++i]; - if (!param) - return false; - - offMeshInputPath = param; - } - else - { - int map = atoi(argv[i]); - if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) - mapnum = map; - else - { - printf("invalid map id\n"); - return false; - } - } - } - - return true; -} - -int finish(const char* message, int returnValue) -{ - printf("%s", message); - getchar(); - return returnValue; -} - -int main(int argc, char** argv) -{ - int mapnum = -1; - float maxAngle = 60.0f; - int tileX = -1, tileY = -1; - bool skipLiquid = false, - skipContinents = false, - skipJunkMaps = true, - skipBattlegrounds = false, - debugOutput = false, - silent = false, - bigBaseUnit = false; - char* offMeshInputPath = NULL; - - bool validParam = handleArgs(argc, argv, mapnum, - tileX, tileY, maxAngle, - skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath); - - if (!validParam) - return silent ? -1 : finish("You have specified invalid parameters", -1); - - if (mapnum == -1 && debugOutput) - { - if (silent) - return -2; - - printf("You have specifed debug output, but didn't specify a map to generate.\n"); - printf("This will generate debug output for ALL maps.\n"); - printf("Are you sure you want to continue? (y/n) "); - if (getchar() != 'y') - return 0; - } - - if (!checkDirectories(debugOutput)) - return silent ? -3 : finish("Press any key to close...", -3); - - MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, - skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); - - if (tileX > -1 && tileY > -1 && mapnum >= 0) - builder.buildSingleTile(mapnum, tileX, tileY); - else if (mapnum >= 0) - builder.buildMap(uint32(mapnum)); - else - builder.buildAllMaps(); - - return silent ? 1 : finish("Movemap build is complete!", 1); -} diff --git a/src/tools/mmap_extractor/TerrainBuilder.cpp b/src/tools/mmap_extractor/TerrainBuilder.cpp deleted file mode 100644 index c696f6017a5..00000000000 --- a/src/tools/mmap_extractor/TerrainBuilder.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#include "TerrainBuilder.h" - -#include "PathCommon.h" -#include "MapBuilder.h" - -#include "VMapManager2.h" -#include "MapTree.h" -#include "ModelInstance.h" - -namespace MMAP -{ - TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } - TerrainBuilder::~TerrainBuilder() { } - - /**************************************************************************/ - void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) - { - switch (portion) - { - case ENTIRE: - loopStart = 0; - loopEnd = V8_SIZE_SQ; - loopInc = 1; - break; - case TOP: - loopStart = 0; - loopEnd = V8_SIZE; - loopInc = 1; - break; - case LEFT: - loopStart = 0; - loopEnd = V8_SIZE_SQ - V8_SIZE + 1; - loopInc = V8_SIZE; - break; - case RIGHT: - loopStart = V8_SIZE - 1; - loopEnd = V8_SIZE_SQ; - loopInc = V8_SIZE; - break; - case BOTTOM: - loopStart = V8_SIZE_SQ - V8_SIZE; - loopEnd = V8_SIZE_SQ; - loopInc = 1; - break; - } - } - - /**************************************************************************/ - void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) - { - loadMap(mapID, tileX+1, tileY, meshData, LEFT); - loadMap(mapID, tileX-1, tileY, meshData, RIGHT); - loadMap(mapID, tileX, tileY+1, meshData, TOP); - loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); - } - } - - /**************************************************************************/ - bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) - { - char mapFileName[255]; - sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); - - FILE* mapFile = fopen(mapFileName, "rb"); - if (!mapFile) - return false; - - map_fileheader fheader; - fread(&fheader, sizeof(map_fileheader), 1, mapFile); - - if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) - { - fclose(mapFile); - printf("%s is the wrong version, please extract new .map files\n", mapFileName); - return false; - } - - map_heightHeader hheader; - fseek(mapFile, fheader.heightMapOffset, SEEK_SET); - fread(&hheader, sizeof(map_heightHeader), 1, mapFile); - - bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); - bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; - - // no data in this map file - if (!haveTerrain && !haveLiquid) - { - fclose(mapFile); - return false; - } - - // data used later - uint16 holes[16][16]; - memset(holes, 0, sizeof(holes)); - uint8 liquid_type[16][16]; - memset(liquid_type, 0, sizeof(liquid_type)); - G3D::Array ltriangles; - G3D::Array ttriangles; - - // terrain data - if (haveTerrain) - { - int i; - float heightMultiplier; - float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; - - if (hheader.flags & MAP_HEIGHT_AS_INT8) - { - uint8 v9[V9_SIZE_SQ]; - uint8 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); - heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; - - for (i = 0; i < V9_SIZE_SQ; ++i) - V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - - for (i = 0; i < V8_SIZE_SQ; ++i) - V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; - } - else if (hheader.flags & MAP_HEIGHT_AS_INT16) - { - uint16 v9[V9_SIZE_SQ]; - uint16 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); - heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; - - for (i = 0; i < V9_SIZE_SQ; ++i) - V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - - for (i = 0; i < V8_SIZE_SQ; ++i) - V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; - } - else - { - fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); - fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); - } - - // hole data - memset(holes, 0, fheader.holesSize); - fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); - - int count = meshData.solidVerts.size() / 3; - float xoffset = (float(tileX)-32)*GRID_SIZE; - float yoffset = (float(tileY)-32)*GRID_SIZE; - - float coord[3]; - - for (i = 0; i < V9_SIZE_SQ; ++i) - { - getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); - } - - for (i = 0; i < V8_SIZE_SQ; ++i) - { - getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); - } - - int j, indices[3], loopStart, loopEnd, loopInc; - getLoopVars(portion, loopStart, loopEnd, loopInc); - for (i = loopStart; i < loopEnd; i+=loopInc) - for (j = TOP; j <= BOTTOM; j+=1) - { - getHeightTriangle(i, Spot(j), indices); - ttriangles.append(indices[2] + count); - ttriangles.append(indices[1] + count); - ttriangles.append(indices[0] + count); - } - } - - // liquid data - if (haveLiquid) - { - map_liquidHeader lheader; - fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); - fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); - - float* liquid_map = NULL; - - if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) - fread(liquid_type, sizeof(liquid_type), 1, mapFile); - - if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) - { - liquid_map = new float [lheader.width*lheader.height]; - fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); - } - - if (liquid_type && liquid_map) - { - int count = meshData.liquidVerts.size() / 3; - float xoffset = (float(tileX)-32)*GRID_SIZE; - float yoffset = (float(tileY)-32)*GRID_SIZE; - - float coord[3]; - int row, col; - - // generate coordinates - if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) - { - int j = 0; - for (int i = 0; i < V9_SIZE_SQ; ++i) - { - row = i / V9_SIZE; - col = i % V9_SIZE; - - if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || - col < lheader.offsetX || col >= lheader.offsetX + lheader.width) - { - // dummy vert using invalid height - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); - continue; - } - - getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); - meshData.liquidVerts.append(coord[0]); - meshData.liquidVerts.append(coord[2]); - meshData.liquidVerts.append(coord[1]); - j++; - } - } - else - { - for (int i = 0; i < V9_SIZE_SQ; ++i) - { - row = i / V9_SIZE; - col = i % V9_SIZE; - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); - } - } - - delete [] liquid_map; - - int indices[3], loopStart, loopEnd, loopInc, triInc; - getLoopVars(portion, loopStart, loopEnd, loopInc); - triInc = BOTTOM-TOP; - - // generate triangles - for (int i = loopStart; i < loopEnd; i+=loopInc) - for (int j = TOP; j <= BOTTOM; j+= triInc) - { - getHeightTriangle(i, Spot(j), indices, true); - ltriangles.append(indices[2] + count); - ltriangles.append(indices[1] + count); - ltriangles.append(indices[0] + count); - } - } - } - - fclose(mapFile); - - // now that we have gathered the data, we can figure out which parts to keep: - // liquid above ground, ground above liquid - int loopStart, loopEnd, loopInc, tTriCount = 4; - bool useTerrain, useLiquid; - - float* lverts = meshData.liquidVerts.getCArray(); - int* ltris = ltriangles.getCArray(); - - float* tverts = meshData.solidVerts.getCArray(); - int* ttris = ttriangles.getCArray(); - - if (ltriangles.size() + ttriangles.size() == 0) - return false; - - // make a copy of liquid vertices - // used to pad right-bottom frame due to lost vertex data at extraction - float* lverts_copy = NULL; - if (meshData.liquidVerts.size()) - { - lverts_copy = new float[meshData.liquidVerts.size()]; - memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); - } - - getLoopVars(portion, loopStart, loopEnd, loopInc); - for (int i = loopStart; i < loopEnd; i+=loopInc) - { - for (int j = 0; j < 2; ++j) - { - // default is true, will change to false if needed - useTerrain = true; - useLiquid = true; - uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; - - // if there is no liquid, don't use liquid - if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) - useLiquid = false; - else - { - liquidType = getLiquidType(i, liquid_type); - switch (liquidType) - { - default: - useLiquid = false; - break; - case MAP_LIQUID_TYPE_WATER: - case MAP_LIQUID_TYPE_OCEAN: - // merge different types of water - liquidType = NAV_WATER; - break; - case MAP_LIQUID_TYPE_MAGMA: - liquidType = NAV_MAGMA; - break; - case MAP_LIQUID_TYPE_SLIME: - liquidType = NAV_SLIME; - break; - case MAP_LIQUID_TYPE_DARK_WATER: - // players should not be here, so logically neither should creatures - useTerrain = false; - useLiquid = false; - break; - } - } - - // if there is no terrain, don't use terrain - if (!ttriangles.size()) - useTerrain = false; - - // while extracting ADT data we are losing right-bottom vertices - // this code adds fair approximation of lost data - if (useLiquid) - { - float quadHeight = 0; - uint32 validCount = 0; - for(uint32 idx = 0; idx < 3; idx++) - { - float h = lverts_copy[ltris[idx]*3 + 1]; - if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) - { - quadHeight += h; - validCount++; - } - } - - // update vertex height data - if (validCount > 0 && validCount < 3) - { - quadHeight /= validCount; - for(uint32 idx = 0; idx < 3; idx++) - { - float h = lverts[ltris[idx]*3 + 1]; - if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) - lverts[ltris[idx]*3 + 1] = quadHeight; - } - } - - // no valid vertexes - don't use this poly at all - if (validCount == 0) - useLiquid = false; - } - - // if there is a hole here, don't use the terrain - if (useTerrain) - useTerrain = !isHole(i, holes); - - // we use only one terrain kind per quad - pick higher one - if (useTerrain && useLiquid) - { - float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; - float maxLLevel = INVALID_MAP_LIQ_HEIGHT; - for(uint32 x = 0; x < 3; x++) - { - float h = lverts[ltris[x]*3 + 1]; - if (minLLevel > h) - minLLevel = h; - - if (maxLLevel < h) - maxLLevel = h; - } - - float maxTLevel = INVALID_MAP_LIQ_HEIGHT; - float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; - for(uint32 x = 0; x < 6; x++) - { - float h = tverts[ttris[x]*3 + 1]; - if (maxTLevel < h) - maxTLevel = h; - - if (minTLevel > h) - minTLevel = h; - } - - // terrain under the liquid? - if (minLLevel > maxTLevel) - useTerrain = false; - - //liquid under the terrain? - if (minTLevel > maxLLevel) - useLiquid = false; - } - - // store the result - if (useLiquid) - { - meshData.liquidType.append(liquidType); - for (int k = 0; k < 3; ++k) - meshData.liquidTris.append(ltris[k]); - } - - if (useTerrain) - for (int k = 0; k < 3*tTriCount/2; ++k) - meshData.solidTris.append(ttris[k]); - - // advance to next set of triangles - ltris += 3; - ttris += 3*tTriCount/2; - } - } - - if (lverts_copy) - delete [] lverts_copy; - - return meshData.solidTris.size() || meshData.liquidTris.size(); - } - - /**************************************************************************/ - void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) - { - // wow coords: x, y, height - // coord is mirroed about the horizontal axes - switch (grid) - { - case GRID_V9: - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index]; - break; - case GRID_V8: - coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[2] = v[index]; - break; - } - } - - /**************************************************************************/ - void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) - { - int rowOffset = square/V8_SIZE; - if (!liquid) - switch (triangle) - { - case TOP: - indices[0] = square+rowOffset; // 0-----1 .... 128 - indices[1] = square+1+rowOffset; // |\ T /| - indices[2] = (V9_SIZE_SQ)+square; // | \ / | - break; // |L 0 R| .. 127 - case LEFT: // | / \ | - indices[0] = square+rowOffset; // |/ B \| - indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 - indices[2] = square+V9_SIZE+rowOffset; // |\ /| - break; // | \ / | - case RIGHT: // | 128 | .. 255 - indices[0] = square+1+rowOffset; // | / \ | - indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| - indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 - break; - case BOTTOM: - indices[0] = (V9_SIZE_SQ)+square; - indices[1] = square+V9_SIZE+1+rowOffset; - indices[2] = square+V9_SIZE+rowOffset; - break; - default: break; - } - else - switch (triangle) - { // 0-----1 .... 128 - case TOP: // |\ | - indices[0] = square+rowOffset; // | \ T | - indices[1] = square+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | - break; // | \| - case BOTTOM: // 129---130 ... 386 - indices[0] = square+rowOffset; // |\ | - indices[1] = square+V9_SIZE+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+rowOffset; // | \ | - break; // | \ | - default: break; // | \| - } // 258---259 ... 515 - - } - - /**************************************************************************/ - void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) - { - // wow coords: x, y, height - // coord is mirroed about the horizontal axes - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index2]; - } - - static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; - static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; - - /**************************************************************************/ - bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) - { - int row = square / 128; - int col = square % 128; - int cellRow = row / 8; // 8 squares per cell - int cellCol = col / 8; - int holeRow = row % 8 / 2; - int holeCol = (square - (row * 128 + cellCol * 8)) / 2; - - uint16 hole = holes[cellRow][cellCol]; - - return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; - } - - /**************************************************************************/ - uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) - { - int row = square / 128; - int col = square % 128; - int cellRow = row / 8; // 8 squares per cell - int cellCol = col / 8; - - return liquid_type[cellRow][cellCol]; - } - - /**************************************************************************/ - bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) - { - IVMapManager* vmapManager = new VMapManager2(); - int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); - bool retval = false; - - do - { - if (result == VMAP_LOAD_RESULT_ERROR) - break; - - InstanceTreeMap instanceTrees; - ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); - - if (!instanceTrees[mapID]) - break; - - ModelInstance* models = NULL; - uint32 count = 0; - instanceTrees[mapID]->getModelInstances(models, count); - - if (!models) - break; - - for (uint32 i = 0; i < count; ++i) - { - ModelInstance instance = models[i]; - - // model instances exist in tree even though there are instances of that model in this tile - WorldModel* worldModel = instance.getWorldModel(); - if (!worldModel) - continue; - - // now we have a model to add to the meshdata - retval = true; - - vector groupModels; - worldModel->getGroupModels(groupModels); - - // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; - - // transform data - float scale = instance.iScale; - G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); - Vector3 position = instance.iPos; - position.x -= 32*GRID_SIZE; - position.y -= 32*GRID_SIZE; - - for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) - { - vector tempVertices; - vector transformedVertices; - vector tempTriangles; - WmoLiquid* liquid = NULL; - - (*it).getMeshData(tempVertices, tempTriangles, liquid); - - // first handle collision mesh - transform(tempVertices, transformedVertices, scale, rotation, position); - - int offset = meshData.solidVerts.size() / 3; - - copyVertices(transformedVertices, meshData.solidVerts); - copyIndices(tempTriangles, meshData.solidTris, offset, isM2); - - // now handle liquid data - if (liquid) - { - vector liqVerts; - vector liqTris; - uint32 tilesX, tilesY, vertsX, vertsY; - Vector3 corner; - liquid->getPosInfo(tilesX, tilesY, corner); - vertsX = tilesX + 1; - vertsY = tilesY + 1; - uint8* flags = liquid->GetFlagsStorage(); - float* data = liquid->GetHeightStorage(); - uint8 type = NAV_EMPTY; - - // convert liquid type to NavTerrain - switch (liquid->GetType()) - { - case 0: - case 1: - type = NAV_WATER; - break; - case 2: - type = NAV_MAGMA; - break; - case 3: - type = NAV_SLIME; - break; - } - - // indexing is weird... - // after a lot of trial and error, this is what works: - // vertex = y*vertsX+x - // tile = x*tilesY+y - // flag = y*tilesY+x - - Vector3 vert; - for (uint32 x = 0; x < vertsX; ++x) - for (uint32 y = 0; y < vertsY; ++y) - { - vert = Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); - vert = vert * rotation * scale + position; - vert.x *= -1.f; - vert.y *= -1.f; - liqVerts.push_back(vert); - } - - int idx1, idx2, idx3, idx4; - uint32 square; - for (uint32 x = 0; x < tilesX; ++x) - for (uint32 y = 0; y < tilesY; ++y) - if ((flags[x+y*tilesX] & 0x0f) != 0x0f) - { - square = x * tilesY + y; - idx1 = square+x; - idx2 = square+1+x; - idx3 = square+tilesY+1+1+x; - idx4 = square+tilesY+1+x; - - // top triangle - liqTris.push_back(idx3); - liqTris.push_back(idx2); - liqTris.push_back(idx1); - // bottom triangle - liqTris.push_back(idx4); - liqTris.push_back(idx3); - liqTris.push_back(idx1); - } - - uint32 liqOffset = meshData.liquidVerts.size() / 3; - for (uint32 i = 0; i < liqVerts.size(); ++i) - meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); - - for (uint32 i = 0; i < liqTris.size() / 3; ++i) - { - meshData.liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset); - meshData.liquidType.append(type); - } - } - } - } - } - while (false); - - vmapManager->unloadMap(mapID, tileX, tileY); - delete vmapManager; - - return retval; - } - - /**************************************************************************/ - void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - // apply tranform, then mirror along the horizontal axes - Vector3 v((*it) * rotation * scale + position); - v.x *= -1.f; - v.y *= -1.f; - transformedVertices.push_back(v); - } - } - - /**************************************************************************/ - void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).y); - dest.push_back((*it).z); - dest.push_back((*it).x); - } - } - - /**************************************************************************/ - void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) - { - if (flip) - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).idx2+offset); - dest.push_back((*it).idx1+offset); - dest.push_back((*it).idx0+offset); - } - } - else - { - for (vector::iterator it = source.begin(); it != source.end(); ++it) - { - dest.push_back((*it).idx0+offset); - dest.push_back((*it).idx1+offset); - dest.push_back((*it).idx2+offset); - } - } - } - - /**************************************************************************/ - void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) - { - int* src = source.getCArray(); - for (int32 i = 0; i < source.size(); ++i) - dest.append(src[i] + offset); - } - - /**************************************************************************/ - void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) - { - map vertMap; - - int* t = tris.getCArray(); - float* v = verts.getCArray(); - - // collect all the vertex indices from triangle - for (int i = 0; i < tris.size(); ++i) - { - if (vertMap.find(t[i]) != vertMap.end()) - continue; - - vertMap.insert(std::pair(t[i], 0)); - } - - // collect the vertices - G3D::Array cleanVerts; - int index, count = 0; - for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) - { - index = (*it).first; - (*it).second = count; - cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); - count++; - } - verts.fastClear(); - verts.append(cleanVerts); - cleanVerts.clear(); - - // update triangles to use new indices - for (int i = 0; i < tris.size(); ++i) - { - map::iterator it; - if ((it = vertMap.find(t[i])) == vertMap.end()) - continue; - - t[i] = (*it).second; - } - - vertMap.clear(); - } - - /**************************************************************************/ - void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) - { - // no meshfile input given? - if (offMeshFilePath == NULL) - return; - - FILE* fp = fopen(offMeshFilePath, "rb"); - if (!fp) - { - printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); - return; - } - - // pretty silly thing, as we parse entire file and load only the tile we need - // but we don't expect this file to be too large - char* buf = new char[512]; - while(fgets(buf, 512, fp)) - { - float p0[3], p1[3]; - int mid, tx, ty; - float size; - if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, - &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) - continue; - - if (mapID == mid, tileX == tx, tileY == ty) - { - meshData.offMeshConnections.append(p0[1]); - meshData.offMeshConnections.append(p0[2]); - meshData.offMeshConnections.append(p0[0]); - - meshData.offMeshConnections.append(p1[1]); - meshData.offMeshConnections.append(p1[2]); - meshData.offMeshConnections.append(p1[0]); - - meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided - meshData.offMeshConnectionRads.append(size); // agent size equivalent - // can be used same way as polygon flags - meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); - meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path - } - - } - - delete [] buf; - fclose(fp); - } -} diff --git a/src/tools/mmap_extractor/TerrainBuilder.h b/src/tools/mmap_extractor/TerrainBuilder.h deleted file mode 100644 index a7f21883af2..00000000000 --- a/src/tools/mmap_extractor/TerrainBuilder.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#ifndef _MMAP_TERRAIN_BUILDER_H -#define _MMAP_TERRAIN_BUILDER_H - -#include "PathCommon.h" -#include "Map.h" -#include "SharedDefines.h" - -#include "WorldModel.h" - -#include "G3D/Array.h" -#include "G3D/Vector3.h" -#include "G3D/Matrix3.h" - -using namespace Trinity; - -namespace MMAP -{ - enum Spot - { - TOP = 1, - RIGHT = 2, - LEFT = 3, - BOTTOM = 4, - ENTIRE = 5 - }; - - enum Grid - { - GRID_V8, - GRID_V9 - }; - - static const int V9_SIZE = 129; - static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; - static const int V8_SIZE = 128; - static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; - static const float GRID_SIZE = 533.33333f; - static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; - - // see contrib/extractor/system.cpp, CONF_use_minHeight - static const float INVALID_MAP_LIQ_HEIGHT = -500.f; - static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; - - // see following files: - // contrib/extractor/system.cpp - // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.2"; - - struct MeshData - { - G3D::Array solidVerts; - G3D::Array solidTris; - - G3D::Array liquidVerts; - G3D::Array liquidTris; - G3D::Array liquidType; - - // offmesh connection data - G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection - G3D::Array offMeshConnectionRads; - G3D::Array offMeshConnectionDirs; - G3D::Array offMeshConnectionsAreas; - G3D::Array offMeshConnectionsFlags; - }; - - class TerrainBuilder - { - public: - TerrainBuilder(bool skipLiquid); - ~TerrainBuilder(); - - void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); - void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); - - bool usesLiquids() { return !m_skipLiquid; } - - // vert and triangle methods - static void transform(vector &original, vector &transformed, - float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); - static void copyVertices(vector &source, G3D::Array &dest); - static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); - static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); - static void cleanVertices(G3D::Array &verts, G3D::Array &tris); - private: - /// Loads a portion of a map's terrain - bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); - - /// Sets loop variables for selecting only certain parts of a map's terrain - void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); - - /// Controls whether liquids are loaded - bool m_skipLiquid; - - /// Load the map terrain from file - bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); - - /// Get the vector coordinate for a specific position - void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); - - /// Get the triangle's vector indices for a specific position - void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); - - /// Determines if the specific position's triangles should be rendered - bool isHole(int square, const uint16 holes[16][16]); - - /// Get the liquid vector coordinate for a specific position - void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); - - /// Get the liquid type for a specific position - uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); - - // hide parameterless and copy constructor - TerrainBuilder(); - TerrainBuilder(const TerrainBuilder &tb); - }; -} - -#endif - diff --git a/src/tools/mmap_extractor/VMapExtensions.cpp b/src/tools/mmap_extractor/VMapExtensions.cpp deleted file mode 100644 index 4f203e11c21..00000000000 --- a/src/tools/mmap_extractor/VMapExtensions.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008-2011 TrinityCore - * Copyright (C) 2005-2011 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, see . - */ - -#include -#include "MapTree.h" -#include "VMapManager2.h" -#include "WorldModel.h" -#include "ModelInstance.h" - -using namespace std; - -namespace VMAP -{ - // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator - // maybe add MapBuilder as friend to all of the below classes would be better? - - // declared in src/shared/vmap/MapTree.h - void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) - { - models = iTreeValues; - count = iNTreeValues; - } - - // declared in src/shared/vmap/VMapManager2.h - void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) - { - instanceMapTree = iInstanceMapTrees; - } - - // declared in src/shared/vmap/WorldModel.h - void WorldModel::getGroupModels(vector &groupModels) - { - groupModels = this->groupModels; - } - - // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) - { - vertices = this->vertices; - triangles = this->triangles; - liquid = iLiquid; - } - - // declared in src/shared/vmap/ModelInstance.h - WorldModel* const ModelInstance::getWorldModel() - { - return iModel; - } - - // declared in src/shared/vmap/WorldModel.h - void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const - { - tilesX = iTilesX; - tilesY = iTilesY; - corner = iCorner; - } -} diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt new file mode 100644 index 00000000000..46bf9d00d43 --- /dev/null +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (C) 2008-2011 Trinity +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +# definitions +add_definitions(-DNO_CORE_FUNCS) +add_definitions(-DDEBUG) +add_definitions(-DNO_vsnprintf) + +include_directories( + ${CMAKE_BINARY_DIR} + ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/zlib + ${CMAKE_SOURCE_DIR}/dep/bzip2 + ${CMAKE_SOURCE_DIR}/dep/acelite + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/src/server/game/Maps + ${CMAKE_SOURCE_DIR}/src/server/game/DataStores + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints + ${CMAKE_SOURCE_DIR}/src/server/game/Grids + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells + ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous + ${CMAKE_SOURCE_DIR}/src/server/game/Conditions + ${CMAKE_SOURCE_DIR}/src/server/collision + ${CMAKE_SOURCE_DIR}/src/server/collision/Management + ${CMAKE_SOURCE_DIR}/src/server/collision/Maps + ${CMAKE_SOURCE_DIR}/src/server/collision/Models +) + +add_executable(mmaps_generator ${sources}) + +target_link_libraries(mmaps_generator + ${MYSQL_LIBRARY} + ${ACE_LIBRARY} + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + Recast + Detour + collision + g3dlib + shared +) + +if( UNIX ) + install(TARGETS mmaps_generator DESTINATION bin) +elseif( WIN32 ) + install(TARGETS mmaps_generator DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() diff --git a/src/tools/mmaps_generator/Info/readme.txt b/src/tools/mmaps_generator/Info/readme.txt new file mode 100644 index 00000000000..8d7c4f9d2e0 --- /dev/null +++ b/src/tools/mmaps_generator/Info/readme.txt @@ -0,0 +1,66 @@ +Generator command line args + +--offMeshInput [file.*] Path to file containing off mesh connections data. + Format must be: (see offmesh_example.txt) + "map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments" + Single mesh connection per line. + +--silent Make us script friendly. Do not wait for user input + on error or completion. + +--bigBaseUnit [true|false] Generate tile/map using bigger basic unit. + Use this option only if you have unexpected gaps. + + false: use normal metrics (default) + +--maxAngle [#] Max walkable inclination angle + + float between 45 and 90 degrees (default 60) + +--skipLiquid liquid data for maps + + false: include liquid data (default) + +--skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), + 1 (Kalimdor), 530 (Outlands), 571 (Northrend) + + false: build continents (default) + +--skipJunkMaps [true|false] junk maps include some unused + maps, transport maps, and some other + + true: skip junk maps (default) + +--skipBattlegrounds [true|false] does not include PVP arenas + + false: skip battlegrounds (default) + +--debugOutput [true|false] create debugging files for use with RecastDemo + if you are only creating mmaps for use with MaNGOS, + you don't want debugging files + + false: don't create debugging files (default) + +--tile [#,#] Build the specified tile + seperate number with a comma ',' + must specify a map number (see below) + if this option is not used, all tiles are built + + [#] Build only the map specified by # + this command will build the map regardless of --skip* option settings + if you do not specify a map number, builds all maps that pass the filters specified by --skip* options + + +examples: + +movement_extractor +builds maps using the default settings (see above for defaults) + +movement_extractor --skipContinents true +builds the default maps, except continents + +movement_extractor 0 +builds all tiles of map 0 + +movement_extractor 0 --tile 34,46 +builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp new file mode 100644 index 00000000000..9eefb1e65f0 --- /dev/null +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "IntermediateValues.h" + +namespace MMAP +{ + IntermediateValues::~IntermediateValues() + { + rcFreeCompactHeightfield(compactHeightfield); + rcFreeHeightField(heightfield); + rcFreeContourSet(contours); + rcFreePolyMesh(polyMesh); + rcFreePolyMeshDetail(polyMeshDetail); + } + + void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); + + printf("%sWriting debug output... \r", tileString); + + string name("meshes/%03u%02i%02i."); + +#define DEBUG_WRITE(fileExtension,data) \ + do { \ + sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ + FILE* file = fopen(fileName, "wb"); \ + if (!file) \ + { \ + char message[1024]; \ + sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ + perror(message); \ + } \ + else \ + debugWrite(file, data); \ + if (file) fclose(file); \ + printf("%sWriting debug output... \r", tileString); \ + } while (false) + + if (heightfield) + DEBUG_WRITE("hf", heightfield); + if (compactHeightfield) + DEBUG_WRITE("chf", compactHeightfield); + if (contours) + DEBUG_WRITE("cs", contours); + if (polyMesh) + DEBUG_WRITE("pmesh", polyMesh); + if (polyMeshDetail) + DEBUG_WRITE("dmesh", polyMeshDetail); + +#undef DEBUG_WRITE + } + + void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->width), sizeof(int), 1, file); + fwrite(&(mesh->height), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + + for (int y = 0; y < mesh->height; ++y) + for (int x = 0; x < mesh->width; ++x) + { + rcSpan* span = mesh->spans[x+y*mesh->width]; + + // first, count the number of spans + int spanCount = 0; + while (span) + { + spanCount++; + span = span->next; + } + + // write the span count + fwrite(&spanCount, sizeof(int), 1, file); + + // write the spans + span = mesh->spans[x+y*mesh->width]; + while (span) + { + fwrite(span, sizeof(rcSpan), 1, file); + span = span->next; + } + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) + { + if (!file | !chf) + return; + + fwrite(&(chf->width), sizeof(chf->width), 1, file); + fwrite(&(chf->height), sizeof(chf->height), 1, file); + fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); + + fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); + fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); + + fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); + fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); + + fwrite(chf->bmin, sizeof(chf->bmin), 1, file); + fwrite(chf->bmax, sizeof(chf->bmax), 1, file); + + fwrite(&(chf->cs), sizeof(chf->cs), 1, file); + fwrite(&(chf->ch), sizeof(chf->ch), 1, file); + + int tmp = 0; + if (chf->cells) tmp |= 1; + if (chf->spans) tmp |= 2; + if (chf->dist) tmp |= 4; + if (chf->areas) tmp |= 8; + + fwrite(&tmp, sizeof(tmp), 1, file); + + if (chf->cells) + fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file); + if (chf->spans) + fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); + if (chf->dist) + fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); + if (chf->areas) + fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) + { + if (!file || !cs) + return; + + fwrite(&(cs->cs), sizeof(float), 1, file); + fwrite(&(cs->ch), sizeof(float), 1, file); + fwrite(cs->bmin, sizeof(float), 3, file); + fwrite(cs->bmax, sizeof(float), 3, file); + fwrite(&(cs->nconts), sizeof(int), 1, file); + for (int i = 0; i < cs->nconts; ++i) + { + fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); + fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); + fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); + fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file); + fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); + fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file); + } + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->cs), sizeof(float), 1, file); + fwrite(&(mesh->ch), sizeof(float), 1, file); + fwrite(&(mesh->nvp), sizeof(int), 1, file); + fwrite(mesh->bmin, sizeof(float), 3, file); + fwrite(mesh->bmax, sizeof(float), 3, file); + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file); + fwrite(&(mesh->npolys), sizeof(int), 1, file); + fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file); + fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); + fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); + fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); + } + + void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) + { + if (!file || !mesh) + return; + + fwrite(&(mesh->nverts), sizeof(int), 1, file); + fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file); + fwrite(&(mesh->ntris), sizeof(int), 1, file); + fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file); + fwrite(&(mesh->nmeshes), sizeof(int), 1, file); + fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file); + } + + void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + char objFileName[255]; + sprintf(objFileName, "meshes/map%03u.obj", mapID); + + FILE* objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + G3D::Array allVerts; + G3D::Array allTris; + + allTris.append(meshData.liquidTris); + allVerts.append(meshData.liquidVerts); + TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); + allVerts.append(meshData.solidVerts); + + float* verts = allVerts.getCArray(); + int vertCount = allVerts.size() / 3; + int* tris = allTris.getCArray(); + int triCount = allTris.size() / 3; + + for (int i = 0; i < allVerts.size() / 3; i++) + fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); + + for (int i = 0; i < allTris.size() / 3; i++) + fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); + + fclose(objFile); + + + char tileString[25]; + sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); + printf("%sWriting debug output... \r", tileString); + + sprintf(objFileName, "meshes/%03u.map", mapID); + + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + char b = '\0'; + fwrite(&b, sizeof(char), 1, objFile); + fclose(objFile); + + sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); + objFile = fopen(objFileName, "wb"); + if (!objFile) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", objFileName); + perror(message); + return; + } + + fwrite(&vertCount, sizeof(int), 1, objFile); + fwrite(verts, sizeof(float), vertCount*3, objFile); + fflush(objFile); + + fwrite(&triCount, sizeof(int), 1, objFile); + fwrite(tris, sizeof(int), triCount*3, objFile); + fflush(objFile); + + fclose(objFile); + } +} diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h new file mode 100644 index 00000000000..a267a0f6412 --- /dev/null +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _INTERMEDIATE_VALUES_H +#define _INTERMEDIATE_VALUES_H + +#include "PathCommon.h" +#include "TerrainBuilder.h" +#include "Recast.h" +#include "DetourNavMesh.h" + +namespace MMAP +{ + // this class gathers all debug info holding and output + struct IntermediateValues + { + rcHeightfield* heightfield; + rcCompactHeightfield* compactHeightfield; + rcContourSet* contours; + rcPolyMesh* polyMesh; + rcPolyMeshDetail* polyMeshDetail; + + IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} + ~IntermediateValues(); + + void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); + + void debugWrite(FILE* file, const rcHeightfield* mesh); + void debugWrite(FILE* file, const rcCompactHeightfield* chf); + void debugWrite(FILE* file, const rcContourSet* cs); + void debugWrite(FILE* file, const rcPolyMesh* mesh); + void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); + + void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + }; +} +#endif diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp new file mode 100644 index 00000000000..3ca158f0127 --- /dev/null +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "MapTree.h" +#include "ModelInstance.h" +#include "LoginDatabase.h" + +#include "DetourNavMeshBuilder.h" +#include "DetourCommon.h" + +// These make the linker happy. +LoginDatabaseWorkerPool LoginDatabase; +#include "DisableMgr.h" +namespace DisableMgr +{ + bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + { + return 0; + } +} + +using namespace VMAP; + +namespace MMAP +{ + MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, + bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, + bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : + m_terrainBuilder(NULL), + m_debugOutput (debugOutput), + m_skipContinents (skipContinents), + m_skipJunkMaps (skipJunkMaps), + m_skipBattlegrounds (skipBattlegrounds), + m_maxWalkableAngle (maxWalkableAngle), + m_bigBaseUnit (bigBaseUnit), + m_rcContext (NULL), + m_offMeshFilePath (offMeshFilePath) + { + m_terrainBuilder = new TerrainBuilder(skipLiquid); + + m_rcContext = new rcContext(false); + + discoverTiles(); + } + + /**************************************************************************/ + MapBuilder::~MapBuilder() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + (*it).second->clear(); + delete (*it).second; + } + + delete m_terrainBuilder; + delete m_rcContext; + } + + /**************************************************************************/ + void MapBuilder::discoverTiles() + { + vector files; + uint32 mapID, tileX, tileY, tileID, count = 0; + char filter[12]; + + printf("Discovering maps... "); + getDirContents(files, "maps"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + if (m_tiles.find(mapID) == m_tiles.end()) + { + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + } + + files.clear(); + getDirContents(files, "vmaps", "*.vmtree"); + for (uint32 i = 0; i < files.size(); ++i) + { + mapID = uint32(atoi(files[i].substr(0,3).c_str())); + m_tiles.insert(pair*>(mapID, new set)); + count++; + } + printf("found %u.\n", count); + + count = 0; + printf("Discovering tiles... "); + for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) + { + set* tiles = (*itr).second; + mapID = (*itr).first; + + sprintf(filter, "%03u*.vmtile", mapID); + files.clear(); + getDirContents(files, "vmaps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileX = uint32(atoi(files[i].substr(7,2).c_str())); + tileY = uint32(atoi(files[i].substr(4,2).c_str())); + tileID = StaticMapTree::packTileID(tileY, tileX); + + tiles->insert(tileID); + count++; + } + + sprintf(filter, "%03u*", mapID); + files.clear(); + getDirContents(files, "maps", filter); + for (uint32 i = 0; i < files.size(); ++i) + { + tileY = uint32(atoi(files[i].substr(3,2).c_str())); + tileX = uint32(atoi(files[i].substr(5,2).c_str())); + tileID = StaticMapTree::packTileID(tileX, tileY); + + if (tiles->insert(tileID).second) + count++; + } + } + printf("found %u.\n\n", count); + } + + /**************************************************************************/ + set* MapBuilder::getTileList(uint32 mapID) + { + TileList::iterator itr = m_tiles.find(mapID); + if (itr != m_tiles.end()) + return (*itr).second; + + set* tiles = new set(); + m_tiles.insert(pair*>(mapID, tiles)); + return tiles; + } + + /**************************************************************************/ + void MapBuilder::buildAllMaps() + { + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + uint32 mapID = (*it).first; + if (!shouldSkipMap(mapID)) + buildMap(mapID); + } + } + + /**************************************************************************/ + void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) + { + maxX = INT_MAX; + maxY = INT_MAX; + minX = INT_MIN; + minY = INT_MIN; + + float bmin[3], bmax[3], lmin[3], lmax[3]; + MeshData meshData; + + // make sure we process maps which don't have tiles + // initialize the static tree, which loads WDT models + if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) + return; + + // get the coord bounds of the model data + if (meshData.solidVerts.size() && meshData.liquidVerts.size()) + { + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + rcVmin(bmin, lmin); + rcVmax(bmax, lmax); + } + else if (meshData.solidVerts.size()) + rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); + else + rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); + + // convert coord bounds to grid bounds + maxX = 32 - bmin[0] / GRID_SIZE; + maxY = 32 - bmin[2] / GRID_SIZE; + minX = 32 - bmax[0] / GRID_SIZE; + minY = 32 - bmax[2] / GRID_SIZE; + } + + /**************************************************************************/ + void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + buildTile(mapID, tileX, tileY, navMesh); + dtFreeNavMesh(navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildMap(uint32 mapID) + { + printf("Building map %03u:\n", mapID); + + set* tiles = getTileList(mapID); + + // make sure we process maps which don't have tiles + if (!tiles->size()) + { + // convert coord bounds to grid bounds + uint32 minX, minY, maxX, maxY; + getGridBounds(mapID, minX, minY, maxX, maxY); + + // add all tiles within bounds to tile list. + for (uint32 i = minX; i <= maxX; ++i) + for (uint32 j = minY; j <= maxY; ++j) + tiles->insert(StaticMapTree::packTileID(i, j)); + } + + if (!tiles->size()) + return; + + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } + + // now start building mmtiles for each tile + printf("We have %u tiles. \n", (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; + + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (shouldSkipTile(mapID, tileX, tileY)) + continue; + + buildTile(mapID, tileX, tileY, navMesh); + } + + dtFreeNavMesh(navMesh); + + printf("Complete! \n\n"); + } + + /**************************************************************************/ + void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) + { + printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + + MeshData meshData; + + // get heightmap data + m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData); + + // get model data + m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData); + + // if there is no data, give up now + if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + return; + + // remove unused vertices + TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); + TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); + + // gather all mesh data for final data check, and bounds calculation + G3D::Array allVerts; + allVerts.append(meshData.liquidVerts); + allVerts.append(meshData.solidVerts); + + if (!allVerts.size()) + return; + + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + + m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); + + // build navmesh tile + buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); + } + + /**************************************************************************/ + void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) + { + set* tiles = getTileList(mapID); + + // old code for non-statically assigned bitmask sizes: + ///*** calculate number of bits needed to store tiles & polys ***/ + //int tileBits = dtIlog2(dtNextPow2(tiles->size())); + //if (tileBits < 1) tileBits = 1; // need at least one bit! + //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; + + int tileBits = STATIC_TILE_BITS; + int polyBits = STATIC_POLY_BITS; + + int maxTiles = tiles->size(); + int maxPolysPerTile = 1 << polyBits; + + /*** calculate bounds of map ***/ + + uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + StaticMapTree::unpackTileID((*it), tileX, tileY); + + if (tileX > tileXMax) + tileXMax = tileX; + else if (tileX < tileXMin) + tileXMin = tileX; + + if (tileY > tileYMax) + tileYMax = tileY; + else if (tileY < tileYMin) + tileYMin = tileY; + } + + // use Max because '32 - tileX' is negative for values over 32 + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + + /*** now create the navmesh ***/ + + // navmesh creation params + dtNavMeshParams navMeshParams; + memset(&navMeshParams, 0, sizeof(dtNavMeshParams)); + navMeshParams.tileWidth = GRID_SIZE; + navMeshParams.tileHeight = GRID_SIZE; + rcVcopy(navMeshParams.orig, bmin); + navMeshParams.maxTiles = maxTiles; + navMeshParams.maxPolys = maxPolysPerTile; + + navMesh = dtAllocNavMesh(); + printf("Creating navMesh... \r"); + if (!navMesh->init(&navMeshParams)) + { + printf("Failed creating navmesh! \n"); + return; + } + + char fileName[25]; + sprintf(fileName, "mmaps/%03u.mmap", mapID); + + FILE* file = fopen(fileName, "wb"); + if (!file) + { + dtFreeNavMesh(navMesh); + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + return; + } + + // now that we know navMesh params are valid, we can write them to file + fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file); + fclose(file); + } + + /**************************************************************************/ + void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, + MeshData &meshData, float bmin[3], float bmax[3], + dtNavMesh* navMesh) + { + // console output + char tileString[10]; + sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); + printf("%s Building movemap tiles... \r", tileString); + + IntermediateValues iv; + + float* tVerts = meshData.solidVerts.getCArray(); + int tVertCount = meshData.solidVerts.size() / 3; + int* tTris = meshData.solidTris.getCArray(); + int tTriCount = meshData.solidTris.size() / 3; + + float* lVerts = meshData.liquidVerts.getCArray(); + int lVertCount = meshData.liquidVerts.size() / 3; + int* lTris = meshData.liquidTris.getCArray(); + int lTriCount = meshData.liquidTris.size() / 3; + uint8* lTriFlags = meshData.liquidType.getCArray(); + + // these are WORLD UNIT based metrics + // this are basic unit dimentions + // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) + const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f; + + // All are in UNIT metrics! + const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); + const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP + const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; + + rcConfig config; + memset(&config, 0, sizeof(rcConfig)); + + rcVcopy(config.bmin, bmin); + rcVcopy(config.bmax, bmax); + + config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + config.cs = BASE_UNIT_DIM; + config.ch = BASE_UNIT_DIM; + config.walkableSlopeAngle = m_maxWalkableAngle; + config.tileSize = VERTEX_PER_TILE; + config.walkableRadius = m_bigBaseUnit ? 1 : 2; + config.borderSize = config.walkableRadius + 3; + config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize + config.walkableHeight = m_bigBaseUnit ? 3 : 6; + config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight + config.minRegionArea = rcSqr(60); + config.mergeRegionArea = rcSqr(50); + config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + config.detailSampleDist = config.cs * 64; + config.detailSampleMaxError = config.ch * 2; + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + + // allocate subregions : tiles + Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; + + // Initialize per tile config. + rcConfig tileCfg; + memcpy(&tileCfg, &config, sizeof(rcConfig)); + tileCfg.width = config.tileSize + config.borderSize*2; + tileCfg.height = config.tileSize + config.borderSize*2; + + // build all tiles + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + + // Calculate the per tile bounding box. + tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + + float tbmin[2], tbmax[2]; + tbmin[0] = tileCfg.bmin[0]; + tbmin[1] = tileCfg.bmin[2]; + tbmax[0] = tileCfg.bmax[0]; + tbmax[1] = tileCfg.bmax[2]; + + // build heightfield + tile.solid = rcAllocHeightfield(); + if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) + { + printf("%sFailed building heightfield! \n", tileString); + continue; + } + + // mark all walkable tiles, both liquids and solids + unsigned char* triFlags = new unsigned char[tTriCount]; + memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); + rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); + rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); + delete [] triFlags; + + rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); + rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); + rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); + + rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); + + // compact heightfield spans + tile.chf = rcAllocCompactHeightfield(); + if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) + { + printf("%sFailed compacting heightfield! \n", tileString); + continue; + } + + // build polymesh intermediates + if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) + { + printf("%sFailed eroding area! \n", tileString); + continue; + } + + if (!rcBuildDistanceField(m_rcContext, *tile.chf)) + { + printf("%sFailed building distance field! \n", tileString); + continue; + } + + if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) + { + printf("%sFailed building regions! \n", tileString); + continue; + } + + tile.cset = rcAllocContourSet(); + if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) + { + printf("%sFailed building contours! \n", tileString); + continue; + } + + // build polymesh + tile.pmesh = rcAllocPolyMesh(); + if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) + { + printf("%sFailed building polymesh! \n", tileString); + continue; + } + + tile.dmesh = rcAllocPolyMeshDetail(); + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + { + printf("%sFailed building polymesh detail! \n", tileString); + continue; + } + + // free those up + // we may want to keep them in the future for debug + // but right now, we don't have the code to merge them + rcFreeHeightField(tile.solid); + tile.solid = NULL; + rcFreeCompactHeightfield(tile.chf); + tile.chf = NULL; + rcFreeContourSet(tile.cset); + tile.cset = NULL; + } + } + + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; + for (int y = 0; y < TILES_PER_MAP; ++y) + { + for (int x = 0; x < TILES_PER_MAP; ++x) + { + Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) + { + pmmerge[nmerge] = tile.pmesh; + dmmerge[nmerge] = tile.dmesh; + nmerge++; + } + } + } + + iv.polyMesh = rcAllocPolyMesh(); + if (!iv.polyMesh) + { + printf("%s alloc iv.polyMesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); + + iv.polyMeshDetail = rcAllocPolyMeshDetail(); + if (!iv.polyMeshDetail) + { + printf("%s alloc m_dmesh FIALED! \r", tileString); + return; + } + rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); + + // free things up + delete [] pmmerge; + delete [] dmmerge; + + delete [] tiles; + + // remove padding for extraction + for (int i = 0; i < iv.polyMesh->nverts; ++i) + { + unsigned short* v = &iv.polyMesh->verts[i*3]; + v[0] -= (unsigned short)config.borderSize; + v[2] -= (unsigned short)config.borderSize; + } + + // set polygons as walkable + // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off + for (int i = 0; i < iv.polyMesh->npolys; ++i) + if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA) + iv.polyMesh->flags[i] = iv.polyMesh->areas[i]; + + // setup mesh parameters + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + params.verts = iv.polyMesh->verts; + params.vertCount = iv.polyMesh->nverts; + params.polys = iv.polyMesh->polys; + params.polyAreas = iv.polyMesh->areas; + params.polyFlags = iv.polyMesh->flags; + params.polyCount = iv.polyMesh->npolys; + params.nvp = iv.polyMesh->nvp; + params.detailMeshes = iv.polyMeshDetail->meshes; + params.detailVerts = iv.polyMeshDetail->verts; + params.detailVertsCount = iv.polyMeshDetail->nverts; + params.detailTris = iv.polyMeshDetail->tris; + params.detailTriCount = iv.polyMeshDetail->ntris; + + params.offMeshConVerts = meshData.offMeshConnections.getCArray(); + params.offMeshConCount = meshData.offMeshConnections.size()/6; + params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); + params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); + params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); + params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); + + params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height + params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius + params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! + params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; + params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; + rcVcopy(params.bmin, bmin); + rcVcopy(params.bmax, bmax); + params.cs = config.cs; + params.ch = config.ch; + params.tileSize = VERTEX_PER_MAP; + + // will hold final navmesh + unsigned char* navData = NULL; + int navDataSize = 0; + + do + { + // these values are checked within dtCreateNavMeshData - handle them here + // so we have a clear error message + if (params.nvp > DT_VERTS_PER_POLYGON) + { + printf("%s Invalid verts-per-polygon value! \n", tileString); + continue; + } + if (params.vertCount >= 0xffff) + { + printf("%s Too many vertices! \n", tileString); + continue; + } + if (!params.vertCount || !params.verts) + { + // occurs mostly when adjacent tiles have models + // loaded but those models don't span into this tile + + // message is an annoyance + //printf("%sNo vertices to build tile! \n", tileString); + continue; + } + if (!params.polyCount || !params.polys || + TILES_PER_MAP*TILES_PER_MAP == params.polyCount) + { + // we have flat tiles with no actual geometry - don't build those, its useless + // keep in mind that we do output those into debug info + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("%s No polygons to build on tile! \n", tileString); + continue; + } + if (!params.detailMeshes || !params.detailVerts || !params.detailTris) + { + printf("%s No detail mesh to build tile! \n", tileString); + continue; + } + + printf("%s Building navmesh tile... \r", tileString); + if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) + { + printf("%s Failed building navmesh tile! \n", tileString); + continue; + } + + dtTileRef tileRef = 0; + printf("%s Adding tile to navmesh... \r", tileString); + // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile + // is removed via removeTile() + dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef); + if (!tileRef || dtResult != DT_SUCCESS) + { + printf("%s Failed adding tile to navmesh! \n", tileString); + continue; + } + + // file output + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "wb"); + if (!file) + { + char message[1024]; + sprintf(message, "Failed to open %s for writing!\n", fileName); + perror(message); + navMesh->removeTile(tileRef, NULL, NULL); + continue; + } + + printf("%s Writing to file... \r", tileString); + + // write header + MmapTileHeader header; + header.usesLiquids = m_terrainBuilder->usesLiquids(); + header.size = uint32(navDataSize); + fwrite(&header, sizeof(MmapTileHeader), 1, file); + + // write data + fwrite(navData, sizeof(unsigned char), navDataSize, file); + fclose(file); + + // now that tile is written to disk, we can unload it + navMesh->removeTile(tileRef, NULL, NULL); + } + while (0); + + if (m_debugOutput) + { + // restore padding so that the debug visualization is correct + for (int i = 0; i < iv.polyMesh->nverts; ++i) + { + unsigned short* v = &iv.polyMesh->verts[i*3]; + v[0] += (unsigned short)config.borderSize; + v[2] += (unsigned short)config.borderSize; + } + + iv.generateObjFile(mapID, tileX, tileY, meshData); + iv.writeIV(mapID, tileX, tileY); + } + } + + /**************************************************************************/ + void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) + { + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * GRID_SIZE; + bmax[2] = (32 - int(tileY)) * GRID_SIZE; + bmin[0] = bmax[0] - GRID_SIZE; + bmin[2] = bmax[2] - GRID_SIZE; + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipMap(uint32 mapID) + { + if (m_skipContinents) + switch (mapID) + { + case 0: + case 1: + case 530: + case 571: + return true; + default: + break; + } + + if (m_skipJunkMaps) + switch (mapID) + { + case 13: // test.wdt + case 25: // ScottTest.wdt + case 29: // Test.wdt + case 42: // Colin.wdt + case 169: // EmeraldDream.wdt (unused, and very large) + case 451: // development.wdt + case 573: // ExteriorTest.wdt + case 597: // CraigTest.wdt + case 605: // development_nonweighted.wdt + case 606: // QA_DVD.wdt + return true; + default: + if (isTransportMap(mapID)) + return true; + break; + } + + if (m_skipBattlegrounds) + switch (mapID) + { + case 30: // AV + case 37: // ? + case 489: // WSG + case 529: // AB + case 566: // EotS + case 607: // SotA + case 628: // IoC + return true; + default: + break; + } + + return false; + } + + /**************************************************************************/ + bool MapBuilder::isTransportMap(uint32 mapID) + { + switch (mapID) + { + // transport maps + case 582: + case 584: + case 586: + case 587: + case 588: + case 589: + case 590: + case 591: + case 592: + case 593: + case 594: + case 596: + case 610: + case 612: + case 613: + case 614: + case 620: + case 621: + case 622: + case 623: + case 641: + case 642: + case 647: + case 672: + case 673: + case 712: + case 713: + case 718: + return true; + default: + return false; + } + } + + /**************************************************************************/ + bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) + { + char fileName[255]; + sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); + FILE* file = fopen(fileName, "rb"); + if (!file) + return false; + + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, file); + fclose(file); + + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + return false; + + if (header.mmapVersion != MMAP_VERSION) + return false; + + return true; + } + +} diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h new file mode 100644 index 00000000000..d0f33ce9a79 --- /dev/null +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MAP_BUILDER_H +#define _MAP_BUILDER_H + +#include +#include +#include + +#include "TerrainBuilder.h" +#include "IntermediateValues.h" + +#include "IVMapManager.h" +#include "WorldModel.h" + +#include "Recast.h" +#include "DetourNavMesh.h" + +using namespace std; +using namespace VMAP; + +// G3D namespace typedefs conflicts with ACE typedefs + +namespace MMAP +{ + typedef map*> TileList; + struct Tile + { + Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} + ~Tile() + { + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + rcFreeHeightField(solid); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + } + rcCompactHeightfield* chf; + rcHeightfield* solid; + rcContourSet* cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + }; + + class MapBuilder + { + public: + MapBuilder(float maxWalkableAngle = 60.f, + bool skipLiquid = false, + bool skipContinents = false, + bool skipJunkMaps = true, + bool skipBattlegrounds = false, + bool debugOutput = false, + bool bigBaseUnit = false, + const char* offMeshFilePath = NULL); + + ~MapBuilder(); + + // builds all mmap tiles for the specified map id (ignores skip settings) + void buildMap(uint32 mapID); + + // builds an mmap tile for the specified map and its mesh + void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); + + // builds list of maps, then builds all of mmap tiles (based on the skip settings) + void buildAllMaps(); + + private: + // detect maps and tiles + void discoverTiles(); + set* getTileList(uint32 mapID); + + void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); + + void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); + + // move map building + void buildMoveMapTile(uint32 mapID, + uint32 tileX, + uint32 tileY, + MeshData &meshData, + float bmin[3], + float bmax[3], + dtNavMesh* navMesh); + + void getTileBounds(uint32 tileX, uint32 tileY, + float* verts, int vertCount, + float* bmin, float* bmax); + void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); + + bool shouldSkipMap(uint32 mapID); + bool isTransportMap(uint32 mapID); + bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); + + TerrainBuilder* m_terrainBuilder; + TileList m_tiles; + + bool m_debugOutput; + + const char* m_offMeshFilePath; + bool m_skipContinents; + bool m_skipJunkMaps; + bool m_skipBattlegrounds; + + float m_maxWalkableAngle; + bool m_bigBaseUnit; + + // build performance - not really used for now + rcContext* m_rcContext; + }; +} + +#endif diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h new file mode 100644 index 00000000000..fd02ec02d50 --- /dev/null +++ b/src/tools/mmaps_generator/PathCommon.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MMAP_COMMON_H +#define _MMAP_COMMON_H + +#include +#include + +#include "Define.h" + +#ifndef _WIN32 + #include + #include +#endif + +#ifdef __linux__ + #include +#endif + +using namespace std; + +namespace MMAP +{ + inline bool matchWildcardFilter(const char* filter, const char* str) + { + if (!filter || !str) + return false; + + // end on null character + while (*filter && *str) + { + if (*filter == '*') + { + if (*++filter == '\0') // wildcard at end of filter means all remaing chars match + return true; + + while (true) + { + if (*filter == *str) + break; + if (*str == '\0') + return false; // reached end of string without matching next filter character + str++; + } + } + else if (*filter != *str) + return false; // mismatch + + filter++; + str++; + } + + return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0'); + } + + enum ListFilesResult + { + LISTFILE_DIRECTORY_NOT_FOUND = 0, + LISTFILE_OK = 1 + }; + + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + { + #ifdef WIN32 + HANDLE hFind; + WIN32_FIND_DATA findFileInfo; + string directory; + + directory = dirpath + "/" + filter; + + hFind = FindFirstFile(directory.c_str(), &findFileInfo); + + if (hFind == INVALID_HANDLE_VALUE) + return LISTFILE_DIRECTORY_NOT_FOUND; + do + { + if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + fileList.push_back(string(findFileInfo.cFileName)); + } + while (FindNextFile(hFind, &findFileInfo)); + + FindClose(hFind); + + #else + const char *p = dirpath.c_str(); + DIR * dirp = opendir(p); + struct dirent * dp; + dirp = opendir(p); + + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + if (matchWildcardFilter(filter.c_str(), dp->d_name)) + fileList.push_back(string(dp->d_name)); + } + else + break; + } + + if (dirp) + closedir(dirp); + else + return LISTFILE_DIRECTORY_NOT_FOUND; + #endif + + return LISTFILE_OK; + } +} + +#endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp new file mode 100644 index 00000000000..2eb2c6545c4 --- /dev/null +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2005-2011 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 "PathCommon.h" +#include "MapBuilder.h" + +using namespace MMAP; + +bool checkDirectories(bool debugOutput) +{ + vector dirFiles; + + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'maps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + { + printf("'vmaps' directory is empty or does not exist\n"); + return false; + } + + dirFiles.clear(); + if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'mmaps' directory does not exist\n"); + return false; + } + + dirFiles.clear(); + if (debugOutput) + { + if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) + { + printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); + return false; + } + } + + return true; +} + +bool handleArgs(int argc, char** argv, + int &mapnum, + int &tileX, + int &tileY, + float &maxAngle, + bool &skipLiquid, + bool &skipContinents, + bool &skipJunkMaps, + bool &skipBattlegrounds, + bool &debugOutput, + bool &silent, + bool &bigBaseUnit, + char* &offMeshInputPath) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--maxAngle") == 0) + { + param = argv[++i]; + if (!param) + return false; + + float maxangle = atof(param); + if (maxangle <= 90.f && maxangle >= 45.f) + maxAngle = maxangle; + else + printf("invalid option for '--maxAngle', using default\n"); + } + else if (strcmp(argv[i], "--tile") == 0) + { + param = argv[++i]; + if (!param) + return false; + + char* stileX = strtok(param, ","); + char* stileY = strtok(NULL, ","); + int tilex = atoi(stileX); + int tiley = atoi(stileY); + + if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0)) + tileX = tilex; + if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0)) + tileY = tiley; + + if (tileX < 0 || tileY < 0) + { + printf("invalid tile coords.\n"); + return false; + } + } + else if (strcmp(argv[i], "--skipLiquid") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipLiquid = true; + else if (strcmp(param, "false") == 0) + skipLiquid = false; + else + printf("invalid option for '--skipLiquid', using default\n"); + } + else if (strcmp(argv[i], "--skipContinents") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipContinents = true; + else if (strcmp(param, "false") == 0) + skipContinents = false; + else + printf("invalid option for '--skipContinents', using default\n"); + } + else if (strcmp(argv[i], "--skipJunkMaps") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipJunkMaps = true; + else if (strcmp(param, "false") == 0) + skipJunkMaps = false; + else + printf("invalid option for '--skipJunkMaps', using default\n"); + } + else if (strcmp(argv[i], "--skipBattlegrounds") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + skipBattlegrounds = true; + else if (strcmp(param, "false") == 0) + skipBattlegrounds = false; + else + printf("invalid option for '--skipBattlegrounds', using default\n"); + } + else if (strcmp(argv[i], "--debugOutput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + debugOutput = true; + else if (strcmp(param, "false") == 0) + debugOutput = false; + else + printf("invalid option for '--debugOutput', using default true\n"); + } + else if (strcmp(argv[i], "--silent") == 0) + { + silent = true; + } + else if (strcmp(argv[i], "--bigBaseUnit") == 0) + { + param = argv[++i]; + if (!param) + return false; + + if (strcmp(param, "true") == 0) + bigBaseUnit = true; + else if (strcmp(param, "false") == 0) + bigBaseUnit = false; + else + printf("invalid option for '--bigBaseUnit', using default false\n"); + } + else if (strcmp(argv[i], "--offMeshInput") == 0) + { + param = argv[++i]; + if (!param) + return false; + + offMeshInputPath = param; + } + else + { + int map = atoi(argv[i]); + if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0))) + mapnum = map; + else + { + printf("invalid map id\n"); + return false; + } + } + } + + return true; +} + +int finish(const char* message, int returnValue) +{ + printf("%s", message); + getchar(); + return returnValue; +} + +int main(int argc, char** argv) +{ + int mapnum = -1; + float maxAngle = 60.0f; + int tileX = -1, tileY = -1; + bool skipLiquid = false, + skipContinents = false, + skipJunkMaps = true, + skipBattlegrounds = false, + debugOutput = false, + silent = false, + bigBaseUnit = false; + char* offMeshInputPath = NULL; + + bool validParam = handleArgs(argc, argv, mapnum, + tileX, tileY, maxAngle, + skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, + debugOutput, silent, bigBaseUnit, offMeshInputPath); + + if (!validParam) + return silent ? -1 : finish("You have specified invalid parameters", -1); + + if (mapnum == -1 && debugOutput) + { + if (silent) + return -2; + + printf("You have specifed debug output, but didn't specify a map to generate.\n"); + printf("This will generate debug output for ALL maps.\n"); + printf("Are you sure you want to continue? (y/n) "); + if (getchar() != 'y') + return 0; + } + + if (!checkDirectories(debugOutput)) + return silent ? -3 : finish("Press any key to close...", -3); + + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, + skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + + if (tileX > -1 && tileY > -1 && mapnum >= 0) + builder.buildSingleTile(mapnum, tileX, tileY); + else if (mapnum >= 0) + builder.buildMap(uint32(mapnum)); + else + builder.buildAllMaps(); + + return silent ? 1 : finish("Movemap build is complete!", 1); +} diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp new file mode 100644 index 00000000000..c696f6017a5 --- /dev/null +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include "TerrainBuilder.h" + +#include "PathCommon.h" +#include "MapBuilder.h" + +#include "VMapManager2.h" +#include "MapTree.h" +#include "ModelInstance.h" + +namespace MMAP +{ + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } + TerrainBuilder::~TerrainBuilder() { } + + /**************************************************************************/ + void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc) + { + switch (portion) + { + case ENTIRE: + loopStart = 0; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + case TOP: + loopStart = 0; + loopEnd = V8_SIZE; + loopInc = 1; + break; + case LEFT: + loopStart = 0; + loopEnd = V8_SIZE_SQ - V8_SIZE + 1; + loopInc = V8_SIZE; + break; + case RIGHT: + loopStart = V8_SIZE - 1; + loopEnd = V8_SIZE_SQ; + loopInc = V8_SIZE; + break; + case BOTTOM: + loopStart = V8_SIZE_SQ - V8_SIZE; + loopEnd = V8_SIZE_SQ; + loopInc = 1; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + if (loadMap(mapID, tileX, tileY, meshData, ENTIRE)) + { + loadMap(mapID, tileX+1, tileY, meshData, LEFT); + loadMap(mapID, tileX-1, tileY, meshData, RIGHT); + loadMap(mapID, tileX, tileY+1, meshData, TOP); + loadMap(mapID, tileX, tileY-1, meshData, BOTTOM); + } + } + + /**************************************************************************/ + bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) + { + char mapFileName[255]; + sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + + FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + return false; + + map_fileheader fheader; + fread(&fheader, sizeof(map_fileheader), 1, mapFile); + + if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + { + fclose(mapFile); + printf("%s is the wrong version, please extract new .map files\n", mapFileName); + return false; + } + + map_heightHeader hheader; + fseek(mapFile, fheader.heightMapOffset, SEEK_SET); + fread(&hheader, sizeof(map_heightHeader), 1, mapFile); + + bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + + // no data in this map file + if (!haveTerrain && !haveLiquid) + { + fclose(mapFile); + return false; + } + + // data used later + uint16 holes[16][16]; + memset(holes, 0, sizeof(holes)); + uint8 liquid_type[16][16]; + memset(liquid_type, 0, sizeof(liquid_type)); + G3D::Array ltriangles; + G3D::Array ttriangles; + + // terrain data + if (haveTerrain) + { + int i; + float heightMultiplier; + float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + + if (hheader.flags & MAP_HEIGHT_AS_INT8) + { + uint8 v9[V9_SIZE_SQ]; + uint8 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else if (hheader.flags & MAP_HEIGHT_AS_INT16) + { + uint16 v9[V9_SIZE_SQ]; + uint16 v8[V8_SIZE_SQ]; + fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; + + for (i = 0; i < V9_SIZE_SQ; ++i) + V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; + + for (i = 0; i < V8_SIZE_SQ; ++i) + V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; + } + else + { + fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); + fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + } + + // hole data + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + + int count = meshData.solidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + + for (i = 0; i < V9_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + for (i = 0; i < V8_SIZE_SQ; ++i) + { + getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); + meshData.solidVerts.append(coord[0]); + meshData.solidVerts.append(coord[2]); + meshData.solidVerts.append(coord[1]); + } + + int j, indices[3], loopStart, loopEnd, loopInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (i = loopStart; i < loopEnd; i+=loopInc) + for (j = TOP; j <= BOTTOM; j+=1) + { + getHeightTriangle(i, Spot(j), indices); + ttriangles.append(indices[2] + count); + ttriangles.append(indices[1] + count); + ttriangles.append(indices[0] + count); + } + } + + // liquid data + if (haveLiquid) + { + map_liquidHeader lheader; + fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); + fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + + float* liquid_map = NULL; + + if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) + fread(liquid_type, sizeof(liquid_type), 1, mapFile); + + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + liquid_map = new float [lheader.width*lheader.height]; + fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + } + + if (liquid_type && liquid_map) + { + int count = meshData.liquidVerts.size() / 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; + float yoffset = (float(tileY)-32)*GRID_SIZE; + + float coord[3]; + int row, col; + + // generate coordinates + if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) + { + int j = 0; + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + + if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height || + col < lheader.offsetX || col >= lheader.offsetX + lheader.width) + { + // dummy vert using invalid height + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); + continue; + } + + getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map); + meshData.liquidVerts.append(coord[0]); + meshData.liquidVerts.append(coord[2]); + meshData.liquidVerts.append(coord[1]); + j++; + } + } + else + { + for (int i = 0; i < V9_SIZE_SQ; ++i) + { + row = i / V9_SIZE; + col = i % V9_SIZE; + meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); + } + } + + delete [] liquid_map; + + int indices[3], loopStart, loopEnd, loopInc, triInc; + getLoopVars(portion, loopStart, loopEnd, loopInc); + triInc = BOTTOM-TOP; + + // generate triangles + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+= triInc) + { + getHeightTriangle(i, Spot(j), indices, true); + ltriangles.append(indices[2] + count); + ltriangles.append(indices[1] + count); + ltriangles.append(indices[0] + count); + } + } + } + + fclose(mapFile); + + // now that we have gathered the data, we can figure out which parts to keep: + // liquid above ground, ground above liquid + int loopStart, loopEnd, loopInc, tTriCount = 4; + bool useTerrain, useLiquid; + + float* lverts = meshData.liquidVerts.getCArray(); + int* ltris = ltriangles.getCArray(); + + float* tverts = meshData.solidVerts.getCArray(); + int* ttris = ttriangles.getCArray(); + + if (ltriangles.size() + ttriangles.size() == 0) + return false; + + // make a copy of liquid vertices + // used to pad right-bottom frame due to lost vertex data at extraction + float* lverts_copy = NULL; + if (meshData.liquidVerts.size()) + { + lverts_copy = new float[meshData.liquidVerts.size()]; + memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size()); + } + + getLoopVars(portion, loopStart, loopEnd, loopInc); + for (int i = loopStart; i < loopEnd; i+=loopInc) + { + for (int j = 0; j < 2; ++j) + { + // default is true, will change to false if needed + useTerrain = true; + useLiquid = true; + uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + + // if there is no liquid, don't use liquid + if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + useLiquid = false; + else + { + liquidType = getLiquidType(i, liquid_type); + switch (liquidType) + { + default: + useLiquid = false; + break; + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + // merge different types of water + liquidType = NAV_WATER; + break; + case MAP_LIQUID_TYPE_MAGMA: + liquidType = NAV_MAGMA; + break; + case MAP_LIQUID_TYPE_SLIME: + liquidType = NAV_SLIME; + break; + case MAP_LIQUID_TYPE_DARK_WATER: + // players should not be here, so logically neither should creatures + useTerrain = false; + useLiquid = false; + break; + } + } + + // if there is no terrain, don't use terrain + if (!ttriangles.size()) + useTerrain = false; + + // while extracting ADT data we are losing right-bottom vertices + // this code adds fair approximation of lost data + if (useLiquid) + { + float quadHeight = 0; + uint32 validCount = 0; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts_copy[ltris[idx]*3 + 1]; + if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX) + { + quadHeight += h; + validCount++; + } + } + + // update vertex height data + if (validCount > 0 && validCount < 3) + { + quadHeight /= validCount; + for(uint32 idx = 0; idx < 3; idx++) + { + float h = lverts[ltris[idx]*3 + 1]; + if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX) + lverts[ltris[idx]*3 + 1] = quadHeight; + } + } + + // no valid vertexes - don't use this poly at all + if (validCount == 0) + useLiquid = false; + } + + // if there is a hole here, don't use the terrain + if (useTerrain) + useTerrain = !isHole(i, holes); + + // we use only one terrain kind per quad - pick higher one + if (useTerrain && useLiquid) + { + float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + float maxLLevel = INVALID_MAP_LIQ_HEIGHT; + for(uint32 x = 0; x < 3; x++) + { + float h = lverts[ltris[x]*3 + 1]; + if (minLLevel > h) + minLLevel = h; + + if (maxLLevel < h) + maxLLevel = h; + } + + float maxTLevel = INVALID_MAP_LIQ_HEIGHT; + float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX; + for(uint32 x = 0; x < 6; x++) + { + float h = tverts[ttris[x]*3 + 1]; + if (maxTLevel < h) + maxTLevel = h; + + if (minTLevel > h) + minTLevel = h; + } + + // terrain under the liquid? + if (minLLevel > maxTLevel) + useTerrain = false; + + //liquid under the terrain? + if (minTLevel > maxLLevel) + useLiquid = false; + } + + // store the result + if (useLiquid) + { + meshData.liquidType.append(liquidType); + for (int k = 0; k < 3; ++k) + meshData.liquidTris.append(ltris[k]); + } + + if (useTerrain) + for (int k = 0; k < 3*tTriCount/2; ++k) + meshData.solidTris.append(ttris[k]); + + // advance to next set of triangles + ltris += 3; + ttris += 3*tTriCount/2; + } + } + + if (lverts_copy) + delete [] lverts_copy; + + return meshData.solidTris.size() || meshData.liquidTris.size(); + } + + /**************************************************************************/ + void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + switch (grid) + { + case GRID_V9: + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index]; + break; + case GRID_V8: + coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; + coord[2] = v[index]; + break; + } + } + + /**************************************************************************/ + void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) + { + int rowOffset = square/V8_SIZE; + if (!liquid) + switch (triangle) + { + case TOP: + indices[0] = square+rowOffset; // 0-----1 .... 128 + indices[1] = square+1+rowOffset; // |\ T /| + indices[2] = (V9_SIZE_SQ)+square; // | \ / | + break; // |L 0 R| .. 127 + case LEFT: // | / \ | + indices[0] = square+rowOffset; // |/ B \| + indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 + indices[2] = square+V9_SIZE+rowOffset; // |\ /| + break; // | \ / | + case RIGHT: // | 128 | .. 255 + indices[0] = square+1+rowOffset; // | / \ | + indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| + indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 + break; + case BOTTOM: + indices[0] = (V9_SIZE_SQ)+square; + indices[1] = square+V9_SIZE+1+rowOffset; + indices[2] = square+V9_SIZE+rowOffset; + break; + default: break; + } + else + switch (triangle) + { // 0-----1 .... 128 + case TOP: // |\ | + indices[0] = square+rowOffset; // | \ T | + indices[1] = square+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | + break; // | \| + case BOTTOM: // 129---130 ... 386 + indices[0] = square+rowOffset; // |\ | + indices[1] = square+V9_SIZE+1+rowOffset; // | \ | + indices[2] = square+V9_SIZE+rowOffset; // | \ | + break; // | \ | + default: break; // | \| + } // 258---259 ... 515 + + } + + /**************************************************************************/ + void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) + { + // wow coords: x, y, height + // coord is mirroed about the horizontal axes + coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; + coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; + coord[2] = v[index2]; + } + + static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; + static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; + + /**************************************************************************/ + bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + int holeRow = row % 8 / 2; + int holeCol = (square - (row * 128 + cellCol * 8)) / 2; + + uint16 hole = holes[cellRow][cellCol]; + + return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; + } + + /**************************************************************************/ + uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16]) + { + int row = square / 128; + int col = square % 128; + int cellRow = row / 8; // 8 squares per cell + int cellCol = col / 8; + + return liquid_type[cellRow][cellCol]; + } + + /**************************************************************************/ + bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) + { + IVMapManager* vmapManager = new VMapManager2(); + int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + bool retval = false; + + do + { + if (result == VMAP_LOAD_RESULT_ERROR) + break; + + InstanceTreeMap instanceTrees; + ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + + if (!instanceTrees[mapID]) + break; + + ModelInstance* models = NULL; + uint32 count = 0; + instanceTrees[mapID]->getModelInstances(models, count); + + if (!models) + break; + + for (uint32 i = 0; i < count; ++i) + { + ModelInstance instance = models[i]; + + // model instances exist in tree even though there are instances of that model in this tile + WorldModel* worldModel = instance.getWorldModel(); + if (!worldModel) + continue; + + // now we have a model to add to the meshdata + retval = true; + + vector groupModels; + worldModel->getGroupModels(groupModels); + + // all M2s need to have triangle indices reversed + bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + + // transform data + float scale = instance.iScale; + G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); + Vector3 position = instance.iPos; + position.x -= 32*GRID_SIZE; + position.y -= 32*GRID_SIZE; + + for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + { + vector tempVertices; + vector transformedVertices; + vector tempTriangles; + WmoLiquid* liquid = NULL; + + (*it).getMeshData(tempVertices, tempTriangles, liquid); + + // first handle collision mesh + transform(tempVertices, transformedVertices, scale, rotation, position); + + int offset = meshData.solidVerts.size() / 3; + + copyVertices(transformedVertices, meshData.solidVerts); + copyIndices(tempTriangles, meshData.solidTris, offset, isM2); + + // now handle liquid data + if (liquid) + { + vector liqVerts; + vector liqTris; + uint32 tilesX, tilesY, vertsX, vertsY; + Vector3 corner; + liquid->getPosInfo(tilesX, tilesY, corner); + vertsX = tilesX + 1; + vertsY = tilesY + 1; + uint8* flags = liquid->GetFlagsStorage(); + float* data = liquid->GetHeightStorage(); + uint8 type = NAV_EMPTY; + + // convert liquid type to NavTerrain + switch (liquid->GetType()) + { + case 0: + case 1: + type = NAV_WATER; + break; + case 2: + type = NAV_MAGMA; + break; + case 3: + type = NAV_SLIME; + break; + } + + // indexing is weird... + // after a lot of trial and error, this is what works: + // vertex = y*vertsX+x + // tile = x*tilesY+y + // flag = y*tilesY+x + + Vector3 vert; + for (uint32 x = 0; x < vertsX; ++x) + for (uint32 y = 0; y < vertsY; ++y) + { + vert = Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); + vert = vert * rotation * scale + position; + vert.x *= -1.f; + vert.y *= -1.f; + liqVerts.push_back(vert); + } + + int idx1, idx2, idx3, idx4; + uint32 square; + for (uint32 x = 0; x < tilesX; ++x) + for (uint32 y = 0; y < tilesY; ++y) + if ((flags[x+y*tilesX] & 0x0f) != 0x0f) + { + square = x * tilesY + y; + idx1 = square+x; + idx2 = square+1+x; + idx3 = square+tilesY+1+1+x; + idx4 = square+tilesY+1+x; + + // top triangle + liqTris.push_back(idx3); + liqTris.push_back(idx2); + liqTris.push_back(idx1); + // bottom triangle + liqTris.push_back(idx4); + liqTris.push_back(idx3); + liqTris.push_back(idx1); + } + + uint32 liqOffset = meshData.liquidVerts.size() / 3; + for (uint32 i = 0; i < liqVerts.size(); ++i) + meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); + + for (uint32 i = 0; i < liqTris.size() / 3; ++i) + { + meshData.liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset); + meshData.liquidType.append(type); + } + } + } + } + } + while (false); + + vmapManager->unloadMap(mapID, tileX, tileY); + delete vmapManager; + + return retval; + } + + /**************************************************************************/ + void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + // apply tranform, then mirror along the horizontal axes + Vector3 v((*it) * rotation * scale + position); + v.x *= -1.f; + v.y *= -1.f; + transformedVertices.push_back(v); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).y); + dest.push_back((*it).z); + dest.push_back((*it).x); + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + { + if (flip) + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx2+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx0+offset); + } + } + else + { + for (vector::iterator it = source.begin(); it != source.end(); ++it) + { + dest.push_back((*it).idx0+offset); + dest.push_back((*it).idx1+offset); + dest.push_back((*it).idx2+offset); + } + } + } + + /**************************************************************************/ + void TerrainBuilder::copyIndices(G3D::Array &source, G3D::Array &dest, int offset) + { + int* src = source.getCArray(); + for (int32 i = 0; i < source.size(); ++i) + dest.append(src[i] + offset); + } + + /**************************************************************************/ + void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) + { + map vertMap; + + int* t = tris.getCArray(); + float* v = verts.getCArray(); + + // collect all the vertex indices from triangle + for (int i = 0; i < tris.size(); ++i) + { + if (vertMap.find(t[i]) != vertMap.end()) + continue; + + vertMap.insert(std::pair(t[i], 0)); + } + + // collect the vertices + G3D::Array cleanVerts; + int index, count = 0; + for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) + { + index = (*it).first; + (*it).second = count; + cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + count++; + } + verts.fastClear(); + verts.append(cleanVerts); + cleanVerts.clear(); + + // update triangles to use new indices + for (int i = 0; i < tris.size(); ++i) + { + map::iterator it; + if ((it = vertMap.find(t[i])) == vertMap.end()) + continue; + + t[i] = (*it).second; + } + + vertMap.clear(); + } + + /**************************************************************************/ + void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath) + { + // no meshfile input given? + if (offMeshFilePath == NULL) + return; + + FILE* fp = fopen(offMeshFilePath, "rb"); + if (!fp) + { + printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath); + return; + } + + // pretty silly thing, as we parse entire file and load only the tile we need + // but we don't expect this file to be too large + char* buf = new char[512]; + while(fgets(buf, 512, fp)) + { + float p0[3], p1[3]; + int mid, tx, ty; + float size; + if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + continue; + + if (mapID == mid, tileX == tx, tileY == ty) + { + meshData.offMeshConnections.append(p0[1]); + meshData.offMeshConnections.append(p0[2]); + meshData.offMeshConnections.append(p0[0]); + + meshData.offMeshConnections.append(p1[1]); + meshData.offMeshConnections.append(p1[2]); + meshData.offMeshConnections.append(p1[0]); + + meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided + meshData.offMeshConnectionRads.append(size); // agent size equivalent + // can be used same way as polygon flags + meshData.offMeshConnectionsAreas.append((unsigned char)0xFF); + meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path + } + + } + + delete [] buf; + fclose(fp); + } +} diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h new file mode 100644 index 00000000000..a7f21883af2 --- /dev/null +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#ifndef _MMAP_TERRAIN_BUILDER_H +#define _MMAP_TERRAIN_BUILDER_H + +#include "PathCommon.h" +#include "Map.h" +#include "SharedDefines.h" + +#include "WorldModel.h" + +#include "G3D/Array.h" +#include "G3D/Vector3.h" +#include "G3D/Matrix3.h" + +using namespace Trinity; + +namespace MMAP +{ + enum Spot + { + TOP = 1, + RIGHT = 2, + LEFT = 3, + BOTTOM = 4, + ENTIRE = 5 + }; + + enum Grid + { + GRID_V8, + GRID_V9 + }; + + static const int V9_SIZE = 129; + static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE; + static const int V8_SIZE = 128; + static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE; + static const float GRID_SIZE = 533.33333f; + static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE; + + // see contrib/extractor/system.cpp, CONF_use_minHeight + static const float INVALID_MAP_LIQ_HEIGHT = -500.f; + static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f; + + // see following files: + // contrib/extractor/system.cpp + // src/game/Map.cpp + static char const* MAP_VERSION_MAGIC = "v1.2"; + + struct MeshData + { + G3D::Array solidVerts; + G3D::Array solidTris; + + G3D::Array liquidVerts; + G3D::Array liquidTris; + G3D::Array liquidType; + + // offmesh connection data + G3D::Array offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection + G3D::Array offMeshConnectionRads; + G3D::Array offMeshConnectionDirs; + G3D::Array offMeshConnectionsAreas; + G3D::Array offMeshConnectionsFlags; + }; + + class TerrainBuilder + { + public: + TerrainBuilder(bool skipLiquid); + ~TerrainBuilder(); + + void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData); + void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath); + + bool usesLiquids() { return !m_skipLiquid; } + + // vert and triangle methods + static void transform(vector &original, vector &transformed, + float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); + static void copyVertices(vector &source, G3D::Array &dest); + static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); + static void cleanVertices(G3D::Array &verts, G3D::Array &tris); + private: + /// Loads a portion of a map's terrain + bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion); + + /// Sets loop variables for selecting only certain parts of a map's terrain + void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc); + + /// Controls whether liquids are loaded + bool m_skipLiquid; + + /// Load the map terrain from file + bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array &vertices, G3D::Array &triangles, Spot portion); + + /// Get the vector coordinate for a specific position + void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); + + /// Get the triangle's vector indices for a specific position + void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); + + /// Determines if the specific position's triangles should be rendered + bool isHole(int square, const uint16 holes[16][16]); + + /// Get the liquid vector coordinate for a specific position + void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); + + /// Get the liquid type for a specific position + uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); + + // hide parameterless and copy constructor + TerrainBuilder(); + TerrainBuilder(const TerrainBuilder &tb); + }; +} + +#endif + diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp new file mode 100644 index 00000000000..4f203e11c21 --- /dev/null +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2005-2011 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, see . + */ + +#include +#include "MapTree.h" +#include "VMapManager2.h" +#include "WorldModel.h" +#include "ModelInstance.h" + +using namespace std; + +namespace VMAP +{ + // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator + // maybe add MapBuilder as friend to all of the below classes would be better? + + // declared in src/shared/vmap/MapTree.h + void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) + { + models = iTreeValues; + count = iNTreeValues; + } + + // declared in src/shared/vmap/VMapManager2.h + void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree) + { + instanceMapTree = iInstanceMapTrees; + } + + // declared in src/shared/vmap/WorldModel.h + void WorldModel::getGroupModels(vector &groupModels) + { + groupModels = this->groupModels; + } + + // declared in src/shared/vmap/WorldModel.h + void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + { + vertices = this->vertices; + triangles = this->triangles; + liquid = iLiquid; + } + + // declared in src/shared/vmap/ModelInstance.h + WorldModel* const ModelInstance::getWorldModel() + { + return iModel; + } + + // declared in src/shared/vmap/WorldModel.h + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + { + tilesX = iTilesX; + tilesY = iTilesY; + corner = iCorner; + } +} -- cgit v1.2.3 From 119a3ff5fc33eafdc8ab13c6dfaedda52b66ee77 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 16:11:17 +0200 Subject: movementgenerator mmaps usage. Signed-off-by: Venugh --- .../FleeingMovementGenerator.cpp | 280 +++------------------ .../MovementGenerators/FleeingMovementGenerator.h | 12 - .../MovementGenerators/HomeMovementGenerator.cpp | 22 +- .../MovementGenerators/PointMovementGenerator.cpp | 19 +- .../MovementGenerators/PointMovementGenerator.h | 7 +- 5 files changed, 70 insertions(+), 270 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 08e27abf050..1b32bb16b2c 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -20,6 +20,7 @@ #include "CreatureAI.h" #include "MapManager.h" #include "FleeingMovementGenerator.h" +#include "PathFinderMovementGenerator.h" #include "ObjectAccessor.h" #include "MoveSplineInit.h" #include "MoveSpline.h" @@ -36,19 +37,26 @@ void FleeingMovementGenerator::_setTargetLocation(T &owner) if (owner.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) return; - if (!_setMoveData(owner)) - return; - float x, y, z; if (!_getPoint(owner, x, y, z)) return; owner.AddUnitState(UNIT_STATE_FLEEING_MOVE); + PathFinderMovementGenerator path(&owner); + path.setPathLengthLimit(30.0f); + path.calculate(x, y, z); + if (path.getPathType() & PATHFIND_NOPATH) + { + i_nextCheckTime.Reset(urand(1000, 1500)); + return; + } + Movement::MoveSplineInit init(owner); - init.MoveTo(x,y,z); + init.MovebyPath(path.getPath()); init.SetWalk(false); - init.Launch(); + int32 traveltime = init.Launch(); + i_nextCheckTime.Reset(traveltime + urand(800, 1500)); } template @@ -57,221 +65,46 @@ bool FleeingMovementGenerator::_getPoint(T &owner, float &x, float &y, float if (!&owner) return false; - x = owner.GetPositionX(); - y = owner.GetPositionY(); - z = owner.GetPositionZ(); - - float temp_x, temp_y, angle; - const Map* _map = owner.GetBaseMap(); - // primitive path-finding - for (uint8 i = 0; i < 18; ++i) - { - if (i_only_forward && i > 2) - break; - - float distance = 5.0f; - - switch (i) - { - case 0: - angle = i_cur_angle; - break; - case 1: - angle = i_cur_angle; - distance /= 2; - break; - case 2: - angle = i_cur_angle; - distance /= 4; - break; - case 3: - angle = i_cur_angle + static_cast(M_PI/4); - break; - case 4: - angle = i_cur_angle - static_cast(M_PI/4); - break; - case 5: - angle = i_cur_angle + static_cast(M_PI/4); - distance /= 2; - break; - case 6: - angle = i_cur_angle - static_cast(M_PI/4); - distance /= 2; - break; - case 7: - angle = i_cur_angle + static_cast(M_PI/2); - break; - case 8: - angle = i_cur_angle - static_cast(M_PI/2); - break; - case 9: - angle = i_cur_angle + static_cast(M_PI/2); - distance /= 2; - break; - case 10: - angle = i_cur_angle - static_cast(M_PI/2); - distance /= 2; - break; - case 11: - angle = i_cur_angle + static_cast(M_PI/4); - distance /= 4; - break; - case 12: - angle = i_cur_angle - static_cast(M_PI/4); - distance /= 4; - break; - case 13: - angle = i_cur_angle + static_cast(M_PI/2); - distance /= 4; - break; - case 14: - angle = i_cur_angle - static_cast(M_PI/2); - distance /= 4; - break; - case 15: - angle = i_cur_angle + static_cast(3*M_PI/4); - distance /= 2; - break; - case 16: - angle = i_cur_angle - static_cast(3*M_PI/4); - distance /= 2; - break; - case 17: - angle = i_cur_angle + static_cast(M_PI); - distance /= 2; - break; - } - temp_x = x + distance * cos(angle); - temp_y = y + distance * sin(angle); - Trinity::NormalizeMapCoord(temp_x); - Trinity::NormalizeMapCoord(temp_y); - if (owner.IsWithinLOS(temp_x, temp_y, z)) - { - bool is_water_now = _map->IsInWater(x,y,z); - - if (is_water_now && _map->IsInWater(temp_x,temp_y,z)) - { - x = temp_x; - y = temp_y; - return true; - } - float new_z = _map->GetHeight(owner.GetPhaseMask(), temp_x, temp_y, z, true); - - if (new_z <= INVALID_HEIGHT) - continue; - - bool is_water_next = _map->IsInWater(temp_x, temp_y, new_z); - - if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok)) - continue; - - if (!(new_z - z) || distance / fabs(new_z - z) > 1.0f) - { - float new_z_left = _map->GetHeight(owner.GetPhaseMask(), temp_x + 1.0f*cos(angle+static_cast(M_PI/2)),temp_y + 1.0f*sin(angle+static_cast(M_PI/2)),z,true); - float new_z_right = _map->GetHeight(owner.GetPhaseMask(), temp_x + 1.0f*cos(angle-static_cast(M_PI/2)),temp_y + 1.0f*sin(angle-static_cast(M_PI/2)),z,true); - if (fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f) - { - x = temp_x; - y = temp_y; - z = new_z; - return true; - } - } - } - } - i_to_distance_from_caster = 0.0f; - i_nextCheckTime.Reset(urand(500,1000)); - return false; -} - -template -bool FleeingMovementGenerator::_setMoveData(T &owner) -{ - float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z); - - if (i_to_distance_from_caster > 0.0f) - { - if ((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) || - // if we reach lower distance - (i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) || - // if we can't be close - (i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) || - // if we reach bigger distance - (cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far - (i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE)) - // if we leave 'quiet zone' - { - // we are very far or too close, stopping - i_to_distance_from_caster = 0.0f; - i_nextCheckTime.Reset(urand(500,1000)); - return false; - } - else - { - // now we are running, continue - i_last_distance_from_caster = cur_dist_xyz; - return true; - } - } - - float cur_dist; - float angle_to_caster; - + float dist_from_caster, angle_to_caster; if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGUID)) { - cur_dist = fright->GetDistance(&owner); - if (cur_dist < cur_dist_xyz) - { - i_caster_x = fright->GetPositionX(); - i_caster_y = fright->GetPositionY(); - i_caster_z = fright->GetPositionZ(); + dist_from_caster = fright->GetDistance(&owner); + if (dist_from_caster > 0.2f) angle_to_caster = fright->GetAngle(&owner); - } else - { - cur_dist = cur_dist_xyz; - angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + static_cast(M_PI); - } + angle_to_caster = frand(0, 2*M_PI_F); } else { - cur_dist = cur_dist_xyz; - angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + static_cast(M_PI); + dist_from_caster = 0.0f; + angle_to_caster = frand(0, 2*M_PI_F); } - // if we too close may use 'path-finding' else just stop - i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3; - - //get angle and 'distance from caster' to run - float angle; - - if (i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time - { - angle = (float)rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * static_cast(M_PI/3) + (float)rand_norm()*static_cast(M_PI*2/3); - i_to_distance_from_caster = MIN_QUIET_DISTANCE; - i_only_forward = true; - } - else if (cur_dist < MIN_QUIET_DISTANCE) + float dist, angle; + if (dist_from_caster < MIN_QUIET_DISTANCE) { - angle = static_cast(M_PI/6) + (float)rand_norm()*static_cast(M_PI*2/3); - i_to_distance_from_caster = cur_dist*2/3 + (float)rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3); + dist = frand(0.4f, 1.3f)*(MIN_QUIET_DISTANCE - dist_from_caster); + angle = angle_to_caster + frand(-M_PI_F/8, M_PI_F/8); } - else if (cur_dist > MAX_QUIET_DISTANCE) + else if(dist_from_caster > MAX_QUIET_DISTANCE) { - angle = (float)rand_norm()*static_cast(M_PI/3) + static_cast(M_PI*2/3); - i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + (float)rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f); + dist = frand(0.4f, 1.0f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); + angle = -angle_to_caster + frand(-M_PI_F/4, M_PI_F/4); } - else + else // we are inside quiet range { - angle = (float)rand_norm()*static_cast(M_PI); - i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + (float)rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f); + dist = frand(0.6f, 1.2f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); + angle = frand(0, 2*M_PI_F); } - int8 sign = (float)rand_norm() > 0.5f ? 1 : -1; - i_cur_angle = sign*angle + angle_to_caster; + float curr_x, curr_y, curr_z; + owner.GetPosition(curr_x, curr_y, curr_z); - // current distance - i_last_distance_from_caster = cur_dist; + x = curr_x + dist*cos(angle); + y = curr_y + dist*sin(angle); + z = curr_z; + + owner.UpdateAllowedPositionZ(x, y, z); return true; } @@ -285,44 +118,10 @@ void FleeingMovementGenerator::Initialize(T &owner) owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); owner.AddUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - _Init(owner); - - if (Unit *fright = ObjectAccessor::GetUnit(owner, i_frightGUID)) - { - i_caster_x = fright->GetPositionX(); - i_caster_y = fright->GetPositionY(); - i_caster_z = fright->GetPositionZ(); - } - else - { - i_caster_x = owner.GetPositionX(); - i_caster_y = owner.GetPositionY(); - i_caster_z = owner.GetPositionZ(); - } - - i_only_forward = true; - i_cur_angle = 0.0f; - i_last_distance_from_caster = 0.0f; - i_to_distance_from_caster = 0.0f; - _setTargetLocation(owner); -} - -template<> -void FleeingMovementGenerator::_Init(Creature &owner) -{ - if (!&owner) + if (owner.GetTypeId() == TYPEID_UNIT) return; - //owner.SetTargetGuid(ObjectGuid()); - is_water_ok = owner.canSwim(); - is_land_ok = owner.canWalk(); -} - -template<> -void FleeingMovementGenerator::_Init(Player &) -{ - is_water_ok = true; - is_land_ok = true; + _setTargetLocation(owner); } template<> @@ -330,6 +129,7 @@ void FleeingMovementGenerator::Finalize(Player &owner) { owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); owner.ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); + owner.StopMoving(); } template<> @@ -367,8 +167,6 @@ bool FleeingMovementGenerator::Update(T &owner, const uint32 &time_diff) template void FleeingMovementGenerator::Initialize(Player &); template void FleeingMovementGenerator::Initialize(Creature &); -template bool FleeingMovementGenerator::_setMoveData(Player &); -template bool FleeingMovementGenerator::_setMoveData(Creature &); template bool FleeingMovementGenerator::_getPoint(Player &, float &, float &, float &); template bool FleeingMovementGenerator::_getPoint(Creature &, float &, float &, float &); template void FleeingMovementGenerator::_setTargetLocation(Player &); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index aec93ad3375..cb3bd1cb69a 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -37,19 +37,7 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem private: void _setTargetLocation(T &owner); bool _getPoint(T &owner, float &x, float &y, float &z); - bool _setMoveData(T &owner); - void _Init(T &); - bool is_water_ok :1; - bool is_land_ok :1; - bool i_only_forward:1; - - float i_caster_x; - float i_caster_y; - float i_caster_z; - float i_last_distance_from_caster; - float i_to_distance_from_caster; - float i_cur_angle; uint64 i_frightGUID; TimeTracker i_nextCheckTime; }; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 311b69c06b7..eaf48150a13 100755 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -25,10 +25,22 @@ void HomeMovementGenerator::Initialize(Creature & owner) { + owner.SetWalk(false); owner.AddUnitState(UNIT_STATE_EVADE); _setTargetLocation(owner); } +void HomeMovementGenerator::Finalize(Creature& owner) +{ + if (arrived) + { + owner.ClearUnitState(UNIT_STAT_EVADE); + owner.SetWalk(true); + owner.LoadCreaturesAddon(true); + owner.AI()->JustReachedHome(); + } +} + void HomeMovementGenerator::Reset(Creature &) { } @@ -41,11 +53,11 @@ void HomeMovementGenerator::_setTargetLocation(Creature & owner) Movement::MoveSplineInit init(owner); float x, y, z, o; // at apply we can select more nice return points base at current movegen - //if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->top()->GetResetPosition(owner,x,y,z)) - //{ - owner.GetHomePosition(x, y, z, o); - init.SetFacing(o); - //} + if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->top()->GetResetPosition(owner,x,y,z)) + { + owner.GetHomePosition(x, y, z, o); + init.SetFacing(o); + } init.MoveTo(x,y,z); init.SetWalk(false); init.Launch(); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index a922c937b5f..f6f8b1fbafd 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -34,7 +34,7 @@ void PointMovementGenerator::Initialize(T &unit) unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(unit); - init.MoveTo(i_x, i_y, i_z); + init.MoveTo(i_x, i_y, i_z, m_generatePath); if (speed > 0.0f) init.SetVelocity(speed); init.Launch(); @@ -59,7 +59,8 @@ bool PointMovementGenerator::Update(T &unit, const uint32 & /*diff*/) template void PointMovementGenerator::Finalize(T &unit) { - unit.ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + if (unit.HasUnitState(UNIT_STAT_CHARGING)) + unit.ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); if (unit.movespline->Finalized()) MovementInform(unit); @@ -120,11 +121,11 @@ void EffectMovementGenerator::Finalize(Unit &unit) if (((Creature&)unit).AI()) ((Creature&)unit).AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); // Need restore previous movement since we have no proper states system - //if (unit.isAlive() && !unit.HasUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_FLEEING)) - //{ - // if (Unit * victim = unit.getVictim()) - // unit.GetMotionMaster()->MoveChase(victim); - // else - // unit.GetMotionMaster()->Initialize(); - //} + if (unit.isAlive() && !unit.HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING)) + { + if (Unit* victim = unit.getVictim()) + unit.GetMotionMaster()->MoveChase(victim); + else + unit.GetMotionMaster()->Initialize(); + } } diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 13be9fee77b..404d3362bab 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -26,8 +26,8 @@ template class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator > { public: - PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f) : id(_id), - i_x(_x), i_y(_y), i_z(_z), speed(_speed) {} + PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), + i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed) {} void Initialize(T &); void Finalize(T &); @@ -43,13 +43,14 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG uint32 id; float i_x, i_y, i_z; float speed; + bool m_generatePath; }; class AssistanceMovementGenerator : public PointMovementGenerator { public: AssistanceMovementGenerator(float _x, float _y, float _z) : - PointMovementGenerator(0, _x, _y, _z) {} + PointMovementGenerator(0, _x, _y, _z, true) {} MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_MOTION_TYPE; } void Finalize(Unit &); -- cgit v1.2.3 From c8f708f9ad0bcc91bf35fab67f4ce7d7eda39b0c Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 16:20:22 +0200 Subject: remove useless pathfinding code. --- .../TargetedMovementGenerator.cpp | 50 ++-- .../MovementGenerators/TargetedMovementGenerator.h | 8 +- .../WaypointMovementGenerator.cpp | 328 --------------------- 3 files changed, 31 insertions(+), 355 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index eb61db8b4ba..5c0e24be440 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -26,8 +26,6 @@ #include "MoveSpline.h" #include "Player.h" -#include - template void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) { @@ -65,30 +63,27 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) i_target->GetClosePoint(x, y, z, owner.GetObjectSize(), i_offset, i_angle); } - /* - We MUST not check the distance difference and avoid setting the new location for smaller distances. - By that we risk having far too many GetContactPoint() calls freezing the whole system. - In TargetedMovementGenerator::Update() we check the distance to the target and at - some range we calculate a new position. The calculation takes some processor cycles due to vmaps. - If the distance to the target it too large to ignore, - but the distance to the new contact point is short enough to be ignored, - we will calculate a new contact point each update loop, but will never move to it. - The system will freeze. - ralf - - //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize - float bothObjectSize = i_target->GetObjectBoundingRadius() + owner.GetObjectBoundingRadius() + CONTACT_DISTANCE; - if ( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) - return; - */ + if (!i_path) + i_path = new PathFinderMovementGenerator(&owner); + // allow pets following their master to cheat while generating paths + bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet() + && owner.HasUnitState(UNIT_STAT_FOLLOW)); + i_path->calculate(x, y, z, forceDest); + if (i_path->getPathType() & PATHFIND_NOPATH) + return; D::_addUnitStateMove(owner); i_targetReached = false; i_recalculateTravel = false; + owner.AddUnitState(UNIT_STATE_CHASE); Movement::MoveSplineInit init(owner); - init.MoveTo(x,y,z); + if (!i_target->IsInWater()) + init.MovebyPath(i_path->getPath()); + else + init.MoveTo(i_target->GetPositionX(), i_target->GetPositionY(), i_target->GetPositionZ(), false, false); + init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } @@ -125,7 +120,7 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ if (!i_target.isValid() || !i_target->IsInWorld()) return false; - if (!owner.isAlive()) + if (!&owner || !owner.isAlive()) return true; if (owner.HasUnitState(UNIT_STATE_NOT_MOVE)) @@ -152,11 +147,18 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ i_recheckDistance.Update(time_diff); if (i_recheckDistance.Passed()) { - i_recheckDistance.Reset(50); + i_recheckDistance.Reset(100); //More distance let have better performance, less distance let have more sensitive reaction at target move. - float allowed_dist = i_target->GetObjectSize() + owner.GetObjectSize() + MELEE_RANGE - 0.5f; - float dist = (owner.movespline->FinalDestination() - G3D::Vector3(i_target->GetPositionX(),i_target->GetPositionY(),i_target->GetPositionZ())).squaredLength(); - if (dist >= allowed_dist * allowed_dist) + float allowed_dist = owner.GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE); + G3D::Vector3 dest = owner.movespline->FinalDestination(); + + bool targetMoved = false; + if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) + targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); + else + targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); + + if (targetMoved) _setTargetLocation(owner); } diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 29fd73624e1..28893c44cfb 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -23,6 +23,7 @@ #include "FollowerReference.h" #include "Timer.h" #include "Unit.h" +#include "PathFinderMovementGenerator.h" class TargetedMovementGeneratorBase { @@ -38,12 +39,12 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, { protected: TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) : - TargetedMovementGeneratorBase(target), i_recheckDistance(0), + TargetedMovementGeneratorBase(target), i_recheckDistance(0),, i_path(NULL), i_offset(offset), i_angle(angle), i_recalculateTravel(false), i_targetReached(false) { } - ~TargetedMovementGeneratorMedium() {} + ~TargetedMovementGeneratorMedium() { delete i_path; } public: bool Update(T &, const uint32 &); @@ -51,7 +52,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, void unitSpeedChanged() { i_recalculateTravel=true; } void UpdateFinalDistance(float fDistance); - + bool IsReachable() const { return (i_path) ? (i_path->getPathType() & PATHFIND_NORMAL) : true; } protected: void _setTargetLocation(T &); @@ -60,6 +61,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, float i_angle; bool i_recalculateTravel : 1; bool i_targetReached : 1; + PathFinderMovementGenerator* i_path; }; template diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 81fe1606ede..6d060668e4c 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -319,331 +319,3 @@ void FlightPathMovementGenerator::PreloadEndGrid() else sLog->outDetail("Unable to determine map to preload flightmaster grid"); } - - -// -// Unique1's ASTAR Pathfinding Code... For future use & reference... -// - -#ifdef __PATHFINDING__ - -int GetFCost(int to, int num, int parentNum, float *gcost); // Below... - -int ShortenASTARRoute(short int *pathlist, int number) -{ // Wrote this to make the routes a little smarter (shorter)... No point looping back to the same places... Unique1 - short int temppathlist[MAX_PATHLIST_NODES]; - int count = 0; - // int count2 = 0; - int temp, temp2; - int link; - int upto = 0; - - for (temp = number; temp >= 0; temp--) - { - qboolean shortened = qfalse; - - for (temp2 = 0; temp2 < temp; temp2++) - { - for (link = 0; link < nodes[pathlist[temp]].enodenum; link++) - { - if (nodes[pathlist[temp]].links[link].flags & PATH_BLOCKED) - continue; - - //if ((bot->client->ps.eFlags & EF_TANK) && nodes[bot->current_node].links[link].flags & PATH_NOTANKS) //if this path is blocked, skip it - // continue; - - //if (nodes[nodes[pathlist[temp]].links[link].targetNode].origin[2] > nodes[pathlist[temp]].origin[2] + 32) - // continue; - - if (nodes[pathlist[temp]].links[link].targetNode == pathlist[temp2]) - { // Found a shorter route... - //if (OrgVisible(nodes[pathlist[temp2]].origin, nodes[pathlist[temp]].origin, -1)) - { - temppathlist[count] = pathlist[temp2]; - temp = temp2; - ++count; - shortened = qtrue; - } - } - } - } - - if (!shortened) - { - temppathlist[count] = pathlist[temp]; - ++count; - } - } - - upto = count; - - for (temp = 0; temp < count; temp++) - { - pathlist[temp] = temppathlist[upto]; - --upto; - } - - G_Printf("ShortenASTARRoute: Path size reduced from %i to %i nodes...n", number, count); - return count; -} - -/* -=========================================================================== -CreatePathAStar -This function uses the A* pathfinding algorithm to determine the -shortest path between any two nodes. -It's fairly complex, so I'm not really going to explain it much. -Look up A* and binary heaps for more info. -pathlist stores the ideal path between the nodes, in reverse order, -and the return value is the number of nodes in that path -=========================================================================== -*/ -int CreatePathAStar(gentity_t *bot, int from, int to, short int *pathlist) -{ - //all the data we have to hold...since we can't do dynamic allocation, has to be MAX_NODES - //we can probably lower this later - eg, the open list should never have more than at most a few dozen items on it - short int openlist[MAX_NODES+1]; //add 1 because it's a binary heap, and they don't use 0 - 1 is the first used index - float gcost[MAX_NODES]; - int fcost[MAX_NODES]; - char list[MAX_NODES]; //0 is neither, 1 is open, 2 is closed - char because it's the smallest data type - short int parent[MAX_NODES]; - - short int numOpen = 0; - short int atNode, temp, newnode=-1; - qboolean found = qfalse; - int count = -1; - float gc; - int i, u, v, m; - vec3_t vec; - - //clear out all the arrays - memset(openlist, 0, sizeof(short int)*(MAX_NODES+1)); - memset(fcost, 0, sizeof(int)*MAX_NODES); - memset(list, 0, sizeof(char)*MAX_NODES); - memset(parent, 0, sizeof(short int)*MAX_NODES); - memset(gcost, -1, sizeof(float)*MAX_NODES); - - //make sure we have valid data before calculating everything - if ((from == NODE_INVALID) || (to == NODE_INVALID) || (from >= MAX_NODES) || (to >= MAX_NODES) || (from == to)) - return -1; - - openlist[1] = from; //add the starting node to the open list - ++numOpen; - gcost[from] = 0; //its f and g costs are obviously 0 - fcost[from] = 0; - - while (1) - { - if (numOpen != 0) //if there are still items in the open list - { - //pop the top item off of the list - atNode = openlist[1]; - list[atNode] = 2; //put the node on the closed list so we don't check it again - --numOpen; - - openlist[1] = openlist[numOpen+1]; //move the last item in the list to the top position - v = 1; - - //this while loop reorders the list so that the new lowest fcost is at the top again - while (1) - { - u = v; - if ((2*u+1) < numOpen) //if both children exist - { - if (fcost[openlist[u]] >= fcost[openlist[2*u]]) - v = 2*u; - if (fcost[openlist[v]] >= fcost[openlist[2*u+1]]) - v = 2*u+1; - } - else - { - if ((2*u) < numOpen) //if only one child exists - { - if (fcost[openlist[u]] >= fcost[openlist[2*u]]) - v = 2*u; - } - } - - if (u != v) //if they're out of order, swap this item with its parent - { - temp = openlist[u]; - openlist[u] = openlist[v]; - openlist[v] = temp; - } - else - break; - } - - for (i = 0; i < nodes[atNode].enodenum; ++i) //loop through all the links for this node - { - newnode = nodes[atNode].links[i].targetNode; - - //if this path is blocked, skip it - if (nodes[atNode].links[i].flags & PATH_BLOCKED) - continue; - //if this path is blocked, skip it - if (bot->client && (bot->client->ps.eFlags & EF_TANK) && nodes[atNode].links[i].flags & PATH_NOTANKS) - continue; - //skip any unreachable nodes - if (bot->client && (nodes[newnode].type & NODE_ALLY_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_ALLIES)) - continue; - if (bot->client && (nodes[newnode].type & NODE_AXIS_UNREACHABLE) && (bot->client->sess.sessionTeam == TEAM_AXIS)) - continue; - - if (list[newnode] == 2) //if this node is on the closed list, skip it - continue; - - if (list[newnode] != 1) //if this node is not already on the open list - { - openlist[++numOpen] = newnode; //add the new node to the open list - list[newnode] = 1; - parent[newnode] = atNode; //record the node's parent - - if (newnode == to) //if we've found the goal, don't keep computing paths! - break; //this will break the 'for' and go all the way to 'if (list[to] == 1)' - - //store it's f cost value - fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost); - - //this loop re-orders the heap so that the lowest fcost is at the top - m = numOpen; - while (m != 1) //while this item isn't at the top of the heap already - { - //if it has a lower fcost than its parent - if (fcost[openlist[m]] <= fcost[openlist[m/2]]) - { - temp = openlist[m/2]; - openlist[m/2] = openlist[m]; - openlist[m] = temp; //swap them - m /= 2; - } - else - break; - } - } - else //if this node is already on the open list - { - gc = gcost[atNode]; - VectorSubtract(nodes[newnode].origin, nodes[atNode].origin, vec); - gc += VectorLength(vec); //calculate what the gcost would be if we reached this node along the current path - - if (gc < gcost[newnode]) //if the new gcost is less (ie, this path is shorter than what we had before) - { - parent[newnode] = atNode; //set the new parent for this node - gcost[newnode] = gc; //and the new g cost - - for (i = 1; i < numOpen; ++i) //loop through all the items on the open list - { - if (openlist[i] == newnode) //find this node in the list - { - //calculate the new fcost and store it - fcost[newnode] = GetFCost(to, newnode, parent[newnode], gcost); - - //reorder the list again, with the lowest fcost item on top - m = i; - while (m != 1) - { - //if the item has a lower fcost than it's parent - if (fcost[openlist[m]] < fcost[openlist[m/2]]) - { - temp = openlist[m/2]; - openlist[m/2] = openlist[m]; - openlist[m] = temp; //swap them - m /= 2; - } - else - break; - } - break; //exit the 'for' loop because we already changed this node - } //if - } //for - } //if (gc < gcost[newnode]) - } //if (list[newnode] != 1) --> else - } //for (loop through links) - } //if (numOpen != 0) - else - { - found = qfalse; //there is no path between these nodes - break; - } - - if (list[to] == 1) //if the destination node is on the open list, we're done - { - found = qtrue; - break; - } - } //while (1) - - if (found == qtrue) //if we found a path - { - //G_Printf("%s - path found!n", bot->client->pers.netname); - count = 0; - - temp = to; //start at the end point - while (temp != from) //travel along the path (backwards) until we reach the starting point - { - pathlist[count++] = temp; //add the node to the pathlist and increment the count - temp = parent[temp]; //move to the parent of this node to continue the path - } - - pathlist[count++] = from; //add the beginning node to the end of the pathlist - - #ifdef __BOT_SHORTEN_ROUTING__ - count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1 - #endif //__BOT_SHORTEN_ROUTING__ - } - else - { - //G_Printf("^1*** ^4BOT DEBUG^5: (CreatePathAStar) There is no route between node ^7%i^5 and node ^7%i^5.n", from, to); - count = CreateDumbRoute(from, to, pathlist); - - if (count > 0) - { - #ifdef __BOT_SHORTEN_ROUTING__ - count = ShortenASTARRoute(pathlist, count); // This isn't working... Dunno why.. Unique1 - #endif //__BOT_SHORTEN_ROUTING__ - return count; - } - } - - return count; //return the number of nodes in the path, -1 if not found -} - -/* -=========================================================================== -GetFCost -Utility function used by A* pathfinding to calculate the -cost to move between nodes towards a goal. Using the A* -algorithm F = G + H, G here is the distance along the node -paths the bot must travel, and H is the straight-line distance -to the goal node. -Returned as an int because more precision is unnecessary and it -will slightly speed up heap access -=========================================================================== -*/ -int GetFCost(int to, int num, int parentNum, float *gcost) -{ - float gc = 0; - float hc = 0; - vec3_t v; - - if (gcost[num] == -1) - { - if (parentNum != -1) - { - gc = gcost[parentNum]; - VectorSubtract(nodes[num].origin, nodes[parentNum].origin, v); - gc += VectorLength(v); - } - gcost[num] = gc; - } - else - gc = gcost[num]; - - VectorSubtract(nodes[to].origin, nodes[num].origin, v); - hc = VectorLength(v); - - return (int)(gc + hc); -} -#endif //__PATHFINDING__ - -- cgit v1.2.3 From f478e6be2b5dd67cc1d26948d324045d75d6fdb1 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 16:38:05 +0200 Subject: spline changes for mmaps. --- src/server/game/Movement/Spline/MoveSplineInit.cpp | 6 +++-- src/server/game/Movement/Spline/MoveSplineInit.h | 28 +++++++++++++++------- src/server/game/World/World.cpp | 1 + 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index e586cb4f4f9..924db9ad726 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -54,7 +54,7 @@ namespace Movement return MOVE_RUN; } - void MoveSplineInit::Launch() + int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit.movespline; @@ -86,7 +86,7 @@ namespace Movement args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate()) - return; + return 0; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; @@ -98,6 +98,8 @@ namespace Movement data.append(unit.GetPackGUID()); PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data,true); + + return move_spline.Duration(); } MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 7ef6cd7a120..24563f28c4f 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -20,6 +20,7 @@ #define TRINITYSERVER_MOVESPLINEINIT_H #include "MoveSplineInitArgs.h" +#include "PathFinderMovementGenerator.h" class Unit; @@ -43,7 +44,7 @@ namespace Movement /* Final pass of initialization that launches spline movement. */ - void Launch(); + int32 Launch(); /* Adds movement by parabolic trajectory * @param amplitude - the maximum height of parabola, value could be negative and positive @@ -72,8 +73,8 @@ namespace Movement /* Initializes simple A to B mition, A is current unit's position, B is destination */ - void MoveTo(const Vector3& destination); - void MoveTo(float x, float y, float z); + void MoveTo(const Vector3& destination, bool generatePath = false, bool forceDestination = false); + void MoveTo(float x, float y, float z, bool generatePath = false, bool forceDestination = false); /* Sets Id of fisrt point of the path. When N-th path point will be done ILisener will notify that pointId + N done * Needed for waypoint movement where path splitten into parts @@ -133,17 +134,26 @@ namespace Movement args.path.assign(controls.begin(),controls.end()); } - inline void MoveSplineInit::MoveTo(float x, float y, float z) + inline void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination) { Vector3 v(x,y,z); - MoveTo(v); + MoveTo(v, generatePath, forceDestination); } - inline void MoveSplineInit::MoveTo(const Vector3& dest) + inline void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) { - args.path_Idx_offset = 0; - args.path.resize(2); - args.path[1] = dest; + if (generatePath) + { + PathFinderMovementGenerator path(&unit); + path.calculate(dest.x, dest.y, dest.z, forceDestination); + MovebyPath(path.getPath()); + } + else + { + args.path_Idx_offset = 0; + args.path.resize(2); + args.path[1] = dest; + } } inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 3870a108d57..90d4ce3604a 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -136,6 +136,7 @@ World::~World() delete command; VMAP::VMapFactory::clear(); + MMAP::MMapFactory::clear(); //TODO free addSessQueue } -- cgit v1.2.3 From 8452fd0dbd293a807da563f3203d2cad4985932a Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 17:05:32 +0200 Subject: fixed errors. --- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 30 +++++++++++++ src/server/game/Movement/MotionMaster.cpp | 4 +- .../ConfusedMovementGenerator.cpp | 52 ++-------------------- .../MovementGenerators/ConfusedMovementGenerator.h | 2 +- .../FleeingMovementGenerator.cpp | 10 ++--- .../MovementGenerators/HomeMovementGenerator.cpp | 13 +----- .../PathFinderMovementGenerator.cpp | 8 ++-- .../MovementGenerators/PointMovementGenerator.cpp | 4 +- .../TargetedMovementGenerator.cpp | 4 +- .../MovementGenerators/TargetedMovementGenerator.h | 2 +- src/server/game/Movement/Spline/MoveSpline.h | 3 +- 12 files changed, 53 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 52269199146..69c2961691a 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -366,7 +366,7 @@ bool Unit::haveOffhandWeapon() const return m_canDualWield; } -void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed) +void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath, bool forceDestination) { Movement::MoveSplineInit init(*this); init.MoveTo(x,y,z); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 1ddf80484e2..16821834669 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -19,6 +19,7 @@ #ifndef TRINITY_SHAREDDEFINES_H #define TRINITY_SHAREDDEFINES_H +#include "DetourNavMesh.h" #include "Define.h" #include @@ -3524,4 +3525,33 @@ enum CalendarError // Calendar - end +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 3 + +struct MmapTileHeader +{ + uint32 mmapMagic; + uint32 dtVersion; + uint32 mmapVersion; + uint32 size; + bool usesLiquids : 1; + + MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), + mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} +}; + +enum NavTerrain +{ + NAV_EMPTY = 0x00, + NAV_GROUND = 0x01, + NAV_MAGMA = 0x02, + NAV_SLIME = 0x04, + NAV_WATER = 0x08, + NAV_UNUSED1 = 0x10, + NAV_UNUSED2 = 0x20, + NAV_UNUSED3 = 0x40, + NAV_UNUSED4 = 0x80 + // we only have 8 bits +}; + #endif diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index b0ac0b710c1..fca0260eb87 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -285,13 +285,13 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z) if (_owner->GetTypeId() == TYPEID_PLAYER) { sLog->outStaticDebug("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), id, x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z), MOTION_SLOT_ACTIVE); + Mutate(new PointMovementGenerator(id, x, y, z, true), MOTION_SLOT_ACTIVE); } else { sLog->outStaticDebug("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), _owner->GetGUIDLow(), id, x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z), MOTION_SLOT_ACTIVE); + Mutate(new PointMovementGenerator(id, x, y, z, true), MOTION_SLOT_ACTIVE); } } diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index caf81a0a141..bad45f65178 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -33,51 +33,6 @@ template void ConfusedMovementGenerator::Initialize(T &unit) { - float const wander_distance = 4; - float x = unit.GetPositionX(); - float y = unit.GetPositionY(); - float z = unit.GetPositionZ(); - - Map const* map = unit.GetBaseMap(); - - i_nextMove = 1; - - bool is_water_ok, is_land_ok; - for (uint8 idx = 0; idx < MAX_CONF_WAYPOINTS + 1; ++idx) - { - float wanderX = x + (wander_distance * (float)rand_norm() - wander_distance/2); - float wanderY = y + (wander_distance * (float)rand_norm() - wander_distance/2); - - // prevent invalid coordinates generation - Trinity::NormalizeMapCoord(wanderX); - Trinity::NormalizeMapCoord(wanderY); - - if (unit.IsWithinLOS(wanderX, wanderY, z)) - { - bool is_water = map->IsInWater(wanderX, wanderY, z); - - if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) - { - //! Cannot use coordinates outside our InhabitType. Use the current or previous position. - wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; - wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; - } - } - else - { - //! Trying to access path outside line of sight. Skip this by using the current or previous position. - wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; - wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; - } - - unit.UpdateAllowedPositionZ(wanderX, wanderY, z); - - //! Positions are fine - apply them to this waypoint - i_waypoints[idx][0] = wanderX; - i_waypoints[idx][1] = wanderY; - i_waypoints[idx][2] = z; - } - unit.GetPosition(i_x, i_y, i_z); unit.StopMoving(); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); @@ -115,10 +70,9 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) // start moving unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); - ASSERT(i_nextMove <= MAX_CONF_WAYPOINTS); - float x = i_waypoints[i_nextMove][0]; - float y = i_waypoints[i_nextMove][1]; - float z = i_waypoints[i_nextMove][2]; + float x = i_x + 10.0f*((float)rand_norm() - 0.5f); + float y = i_y + 10.0f*((float)rand_norm() - 0.5f); + float z = i_z; unit.UpdateAllowedPositionZ(x, y, z); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index c390892d0d0..72ffd7b734b 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -36,7 +36,7 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } private: TimeTracker i_nextMoveTime; - float i_waypoints[24+1][3]; + float i_x, i_y, i_z; }; #endif diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 1b32bb16b2c..9d99e0ef000 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -72,29 +72,29 @@ bool FleeingMovementGenerator::_getPoint(T &owner, float &x, float &y, float if (dist_from_caster > 0.2f) angle_to_caster = fright->GetAngle(&owner); else - angle_to_caster = frand(0, 2*M_PI_F); + angle_to_caster = frand(0, 2 * static_cast(M_PI)); } else { dist_from_caster = 0.0f; - angle_to_caster = frand(0, 2*M_PI_F); + angle_to_caster = frand(0, 2 * static_cast(M_PI)); } float dist, angle; if (dist_from_caster < MIN_QUIET_DISTANCE) { dist = frand(0.4f, 1.3f)*(MIN_QUIET_DISTANCE - dist_from_caster); - angle = angle_to_caster + frand(-M_PI_F/8, M_PI_F/8); + angle = angle_to_caster + frand(-static_cast(M_PI)/8, static_cast(M_PI)/8); } else if(dist_from_caster > MAX_QUIET_DISTANCE) { dist = frand(0.4f, 1.0f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); - angle = -angle_to_caster + frand(-M_PI_F/4, M_PI_F/4); + angle = -angle_to_caster + frand(-static_cast(M_PI)/4, static_cast(M_PI)/4); } else // we are inside quiet range { dist = frand(0.6f, 1.2f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); - angle = frand(0, 2*M_PI_F); + angle = frand(0, 2*static_cast(M_PI)); } float curr_x, curr_y, curr_z; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index eaf48150a13..216721360c6 100755 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -34,7 +34,7 @@ void HomeMovementGenerator::Finalize(Creature& owner) { if (arrived) { - owner.ClearUnitState(UNIT_STAT_EVADE); + owner.ClearUnitState(UNIT_STATE_EVADE); owner.SetWalk(true); owner.LoadCreaturesAddon(true); owner.AI()->JustReachedHome(); @@ -71,14 +71,3 @@ bool HomeMovementGenerator::Update(Creature &owner, const uint32 /*tim arrived = owner.movespline->Finalized(); return !arrived; } - -void HomeMovementGenerator::Finalize(Creature& owner) -{ - if (arrived) - { - owner.ClearUnitState(UNIT_STATE_EVADE); - owner.SetWalk(true); - owner.LoadCreaturesAddon(true); - owner.AI()->JustReachedHome(); - } -} diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 686c57cb634..4894b5eb841 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -71,7 +71,7 @@ bool PathFinderMovementGenerator::calculate(float destX, float destY, float dest // make sure navMesh works - we can run on map w/o mmap // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) - if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STAT_IGNORE_PATHFINDING) || + if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || !HaveTile(start) || !HaveTile(dest)) { BuildShortcut(); @@ -186,7 +186,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); BuildShortcut(); - m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->canFly()) + m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->CanFly()) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; return; } @@ -212,7 +212,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V else { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n"); - if (owner->canFly()) + if (owner->CanFly()) buildShotrcut = true; } } @@ -532,7 +532,7 @@ NavTerrain PathFinderMovementGenerator::getNavTerrain(float x, float y, float z) LiquidData data; m_sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); - switch (data.type) + switch (data.type_flags) { case MAP_LIQUID_TYPE_WATER: case MAP_LIQUID_TYPE_OCEAN: diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index f6f8b1fbafd..7a8ad4584b0 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -59,8 +59,8 @@ bool PointMovementGenerator::Update(T &unit, const uint32 & /*diff*/) template void PointMovementGenerator::Finalize(T &unit) { - if (unit.HasUnitState(UNIT_STAT_CHARGING)) - unit.ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + if (unit.HasUnitState(UNIT_STATE_CHARGING)) + unit.ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); if (unit.movespline->Finalized()) MovementInform(unit); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 5c0e24be440..63e3ebfd378 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -68,7 +68,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) // allow pets following their master to cheat while generating paths bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet() - && owner.HasUnitState(UNIT_STAT_FOLLOW)); + && owner.HasUnitState(UNIT_STATE_FOLLOW)); i_path->calculate(x, y, z, forceDest); if (i_path->getPathType() & PATHFIND_NOPATH) return; @@ -153,7 +153,7 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ G3D::Vector3 dest = owner.movespline->FinalDestination(); bool targetMoved = false; - if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) + if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->CanFly()) targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 28893c44cfb..d855dfa1875 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -39,7 +39,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, { protected: TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) : - TargetedMovementGeneratorBase(target), i_recheckDistance(0),, i_path(NULL), + TargetedMovementGeneratorBase(target), i_recheckDistance(0), i_path(NULL), i_offset(offset), i_angle(angle), i_recalculateTravel(false), i_targetReached(false) { diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index d4b19b21634..4ec8d2c78ac 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -77,7 +77,6 @@ namespace Movement UpdateResult _updateState(int32& ms_time_diff); int32 next_timestamp() const { return spline.length(point_Idx+1);} int32 segment_time_elapsed() const { return next_timestamp()-time_passed;} - int32 Duration() const { return spline.length();} int32 timeElapsed() const { return Duration() - time_passed;} int32 timePassed() const { return time_passed;} @@ -88,7 +87,7 @@ namespace Movement void _Interrupt() { splineflags.done = true;} public: - + int32 Duration() const { return spline.length();} void Initialize(const MoveSplineInitArgs&); bool Initialized() const { return !spline.empty();} -- cgit v1.2.3 From 9ac2255fbcee4049ed4067fc18c8cabccef1047e Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 17:10:54 +0200 Subject: fix all build errors, only 1 linking error. --- src/server/shared/Memory.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/server/shared/Memory.h (limited to 'src') diff --git a/src/server/shared/Memory.h b/src/server/shared/Memory.h new file mode 100644 index 00000000000..ac697f7a1af --- /dev/null +++ b/src/server/shared/Memory.h @@ -0,0 +1,17 @@ + + +#ifndef _MEMORY_H +#define _MEMORY_H + +// memory management +inline void* dtCustomAlloc(int size, dtAllocHint /*hint*/) +{ + return (void*)new unsigned char[size]; +} + +inline void dtCustomFree(void* ptr) +{ + delete [] (unsigned char*)ptr; +} + +#endif \ No newline at end of file -- cgit v1.2.3 From d06c09271295f8199fa45ae9b7d8e2eb600bbe26 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 17:17:31 +0200 Subject: fix linker error. --- src/tools/mmaps_generator/MapBuilder.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 3ca158f0127..2987e6596dd 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -28,6 +28,11 @@ // These make the linker happy. LoginDatabaseWorkerPool LoginDatabase; +uint32 GetLiquidFlags(uint32 liquidType) +{ + return 0; +} + #include "DisableMgr.h" namespace DisableMgr { -- cgit v1.2.3 From 8368112f453cc20672943dac533da1ee8ff933a3 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 18:05:35 +0200 Subject: Try to check existance of mmaps folder. --- src/server/collision/Management/MMapManager.cpp | 9 +++------ src/server/collision/Management/MMapManager.h | 2 +- src/server/game/Maps/Map.cpp | 2 +- src/server/game/World/World.cpp | 4 +++- 4 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index aac5647a6de..449abcb967d 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -82,10 +82,10 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles - if(!loadMapData(mapId)) + if (!loadMapData(mapId)) return false; // get this mmap data @@ -95,10 +95,7 @@ namespace MMAP // check if we already have this tile loaded uint32 packedGridPos = packTileID(x, y); if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end()) - { - //sLog->outError("MMAP:loadMap: Asked to load already loaded navmesh tile. %03u%02i%02i.mmtile", mapId, y, x); return false; - } // load this tile :: mmaps/MMMXXYY.mmtile uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1; @@ -136,7 +133,7 @@ namespace MMAP ASSERT(data); size_t result = fread(data, fileHeader.size, 1, file); - if(!result) + if (!result) { sLog->outError("MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); fclose(file); diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h index 8af452032d1..23b7d5fc6f8 100644 --- a/src/server/collision/Management/MMapManager.h +++ b/src/server/collision/Management/MMapManager.h @@ -61,7 +61,7 @@ namespace MMAP MMapManager() : loadedTiles(0) {} ~MMapManager(); - bool loadMap(uint32 mapId, int32 x, int32 y); + bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); bool unloadMapInstance(uint32 mapId, uint32 instanceId); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c3732769d04..a9fc3f3350f 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -124,7 +124,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { // DONT CHANGE "gy" and "gx" - Its necessary ! - int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(GetId(), gy, gx); + int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); switch (mmapLoadResult) { case MMAP::MMAP_LOAD_RESULT_OK: diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 90d4ce3604a..a5ec6be10d4 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1123,8 +1123,10 @@ void World::LoadConfigSettings(bool reload) sLog->outString("Using DataDir %s", m_dataPath.c_str()); } - m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); + sLog->outString("WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); + + m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true); bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", true); -- cgit v1.2.3 From abc33c7b5d830c96b17ff2a0473702f8a5b31b87 Mon Sep 17 00:00:00 2001 From: Venugh Date: Mon, 9 Apr 2012 18:36:45 +0200 Subject: Core/Movement: Correct MotionMaster and fix a crash. --- src/server/game/Movement/MotionMaster.cpp | 12 ++++++------ src/server/game/Movement/MotionMaster.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index fca0260eb87..7e8020b7863 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -280,18 +280,18 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo } } -void MotionMaster::MovePoint(uint32 id, float x, float y, float z) +void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generatePath) { if (_owner->GetTypeId() == TYPEID_PLAYER) { sLog->outStaticDebug("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), id, x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, true), MOTION_SLOT_ACTIVE); + Mutate(new PointMovementGenerator(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE); } else { sLog->outStaticDebug("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), _owner->GetGUIDLow(), id, x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, true), MOTION_SLOT_ACTIVE); + Mutate(new PointMovementGenerator(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE); } } @@ -396,7 +396,7 @@ void MotionMaster::MoveFall(uint32 id/*=0*/) Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } -void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id) +void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, bool generatePath) { if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE) return; @@ -404,13 +404,13 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id) if (_owner->GetTypeId() == TYPEID_PLAYER) { sLog->outStaticDebug("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, speed), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED); } else { sLog->outStaticDebug("Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetEntry(), _owner->GetGUIDLow(), x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, speed), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED); } } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index d6144bfcc3a..a96a3e6391a 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -154,13 +154,13 @@ class MotionMaster //: private std::stack void MoveFleeing(Unit* enemy, uint32 time = 0); void MovePoint(uint32 id, const Position &pos) { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); } - void MovePoint(uint32 id, float x, float y, float z); + void MovePoint(uint32 id, float x, float y, float z, bool generatePath = false); // These two movement types should only be used with creatures having landing/takeoff animations void MoveLand(uint32 id, Position const& pos, float speed); void MoveTakeoff(uint32 id, Position const& pos, float speed); - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0); -- cgit v1.2.3 From 5061fa626a72fa7c2632a4b2cef318633c56d85b Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 17:39:25 -0500 Subject: Core/Mmaps: * Unload instanced mmaps before unloading the base map * Load only mmaps for base map on map creation * Extractor: Somewhat speed improvement --- src/server/game/Maps/Map.cpp | 9 +- src/server/game/Movement/MotionMaster.h | 4 +- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 105 +++++++++++++++-------- src/tools/mmaps_generator/MapBuilder.h | 1 + src/tools/mmaps_generator/PathGenerator.cpp | 17 +++- src/tools/mmaps_generator/TerrainBuilder.cpp | 23 +++-- 7 files changed, 106 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b38f89eab8f..5e3699146f2 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -71,8 +71,8 @@ Map::~Map() if (!m_scriptSchedule.empty()) sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); - MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); } bool Map::ExistMap(uint32 mapid, int gx, int gy) @@ -206,9 +206,12 @@ void Map::LoadMap(int gx, int gy, bool reload) void Map::LoadMapAndVMap(int gx, int gy) { LoadMap(gx, gy); - LoadMMap(gx, gy); + // Only load the data for the base map if (i_InstanceId == 0) - LoadVMap(gx, gy); // Only load the data for the base map + { + LoadVMap(gx, gy); + LoadMMap(gx, gy); + } } void Map::InitStateMachine() diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index f10c6569cad..918896a5a81 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -154,13 +154,13 @@ class MotionMaster //: private std::stack void MoveFleeing(Unit* enemy, uint32 time = 0); void MovePoint(uint32 id, const Position &pos) { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); } - void MovePoint(uint32 id, float x, float y, float z, bool generatePath = false); + void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true); // These two movement types should only be used with creatures having landing/takeoff animations void MoveLand(uint32 id, Position const& pos); void MoveTakeoff(uint32 id, Position const& pos); - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = true); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0); diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index 9eefb1e65f0..b473d6472a0 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -202,7 +202,7 @@ namespace MMAP void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) { char objFileName[255]; - sprintf(objFileName, "meshes/map%03u.obj", mapID); + sprintf(objFileName, "meshes/map%03u%02u%02u.obj", mapID, tileY, tileX); FILE* objFile = fopen(objFileName, "wb"); if (!objFile) diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 2987e6596dd..e47b2e5b44f 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -24,6 +24,7 @@ #include "LoginDatabase.h" #include "DetourNavMeshBuilder.h" +#include "DetourNavMesh.h" #include "DetourCommon.h" // These make the linker happy. @@ -206,6 +207,56 @@ namespace MMAP minX = 32 - bmax[0] / GRID_SIZE; minY = 32 - bmax[2] / GRID_SIZE; } + + void MapBuilder::buildMeshFromFile(char* name) + { + FILE* file = fopen(name, "rb"); + if (!file) + return; + + printf("Building mesh from file\n"); + int tileX, tileY, mapId; + fread(&mapId, sizeof(int), 1, file); + fread(&tileX, sizeof(int), 1, file); + fread(&tileY, sizeof(int), 1, file); + + dtNavMesh* navMesh = NULL; + buildNavMesh(mapId, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + fclose(file); + return; + } + + + int verticesCount, indicesCount; + fread(&verticesCount, sizeof(int), 1, file); + fread(&indicesCount, sizeof(int), 1, file); + + float* verts = new float[verticesCount]; + int* inds = new int[indicesCount]; + + fread(verts, sizeof(float), verticesCount, file); + fread(inds, sizeof(int), indicesCount, file); + + MeshData data; + + for (int i = 0; i < verticesCount; ++i) + data.solidVerts.append(verts[i]); + + for (int i = 0; i < indicesCount; ++i) + data.solidTris.append(inds[i]); + + TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); + // get bounds of current tile + float bmin[3], bmax[3]; + getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax); + + // build navmesh tile + buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh); + fclose(file); + } /**************************************************************************/ void MapBuilder::buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY) @@ -451,17 +502,32 @@ namespace MMAP Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; // Initialize per tile config. - rcConfig tileCfg; - memcpy(&tileCfg, &config, sizeof(rcConfig)); + rcConfig tileCfg = config; tileCfg.width = config.tileSize + config.borderSize*2; tileCfg.height = config.tileSize + config.borderSize*2; + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; + if (!pmmerge) + { + printf("%s alloc pmmerge FIALED! \r", tileString); + return; + } + + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + if (!dmmerge) + { + printf("%s alloc dmmerge FIALED! \r", tileString); + return; + } + + int nmerge = 0; // build all tiles for (int y = 0; y < TILES_PER_MAP; ++y) { for (int x = 0; x < TILES_PER_MAP; ++x) { - Tile& tile = tiles[x + y*TILES_PER_MAP]; + Tile& tile = tiles[x + y * TILES_PER_MAP]; // Calculate the per tile bounding box. tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; @@ -469,12 +535,6 @@ namespace MMAP tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; - float tbmin[2], tbmax[2]; - tbmin[0] = tileCfg.bmin[0]; - tbmin[1] = tileCfg.bmin[2]; - tbmax[0] = tileCfg.bmax[0]; - tbmax[1] = tileCfg.bmax[2]; - // build heightfield tile.solid = rcAllocHeightfield(); if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) @@ -488,7 +548,7 @@ namespace MMAP memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); - delete [] triFlags; + delete[] triFlags; rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); @@ -554,30 +614,7 @@ namespace MMAP tile.chf = NULL; rcFreeContourSet(tile.cset); tile.cset = NULL; - } - } - - // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; - if (!pmmerge) - { - printf("%s alloc pmmerge FIALED! \r", tileString); - return; - } - - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; - if (!dmmerge) - { - printf("%s alloc dmmerge FIALED! \r", tileString); - return; - } - - int nmerge = 0; - for (int y = 0; y < TILES_PER_MAP; ++y) - { - for (int x = 0; x < TILES_PER_MAP; ++x) - { - Tile& tile = tiles[x + y*TILES_PER_MAP]; + if (tile.pmesh) { pmmerge[nmerge] = tile.pmesh; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index d0f33ce9a79..20789bf9bff 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -74,6 +74,7 @@ namespace MMAP // builds all mmap tiles for the specified map id (ignores skip settings) void buildMap(uint32 mapID); + void buildMeshFromFile(char* name); // builds an mmap tile for the specified map and its mesh void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 2eb2c6545c4..7d9f59ed138 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -70,7 +70,8 @@ bool handleArgs(int argc, char** argv, bool &debugOutput, bool &silent, bool &bigBaseUnit, - char* &offMeshInputPath) + char* &offMeshInputPath, + char* &file) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -87,6 +88,13 @@ bool handleArgs(int argc, char** argv, else printf("invalid option for '--maxAngle', using default\n"); } + else if (strcmp(argv[i], "--file") == 0) + { + param = argv[++i]; + if (!param) + return false; + file = param; + } else if (strcmp(argv[i], "--tile") == 0) { param = argv[++i]; @@ -235,11 +243,12 @@ int main(int argc, char** argv) silent = false, bigBaseUnit = false; char* offMeshInputPath = NULL; + char* file = NULL; bool validParam = handleArgs(argc, argv, mapnum, tileX, tileY, maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath); + debugOutput, silent, bigBaseUnit, offMeshInputPath, file); if (!validParam) return silent ? -1 : finish("You have specified invalid parameters", -1); @@ -262,7 +271,9 @@ int main(int argc, char** argv) MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); - if (tileX > -1 && tileY > -1 && mapnum >= 0) + if (file) + builder.buildMeshFromFile(file); + else if (tileX > -1 && tileY > -1 && mapnum >= 0) builder.buildSingleTile(mapnum, tileX, tileY); else if (mapnum >= 0) builder.buildMap(uint32(mapnum)); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index c696f6017a5..e16dd16707b 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -767,25 +767,24 @@ namespace MMAP int* t = tris.getCArray(); float* v = verts.getCArray(); + G3D::Array cleanVerts; + int index, count = 0; // collect all the vertex indices from triangle for (int i = 0; i < tris.size(); ++i) { if (vertMap.find(t[i]) != vertMap.end()) continue; - - vertMap.insert(std::pair(t[i], 0)); - } - - // collect the vertices - G3D::Array cleanVerts; - int index, count = 0; - for (map::iterator it = vertMap.begin(); it != vertMap.end(); ++it) - { - index = (*it).first; - (*it).second = count; - cleanVerts.append(v[index*3], v[index*3+1], v[index*3+2]); + std::pair val; + val.first = t[i]; + + index = val.first; + val.second = count; + + vertMap.insert(val); + cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]); count++; } + verts.fastClear(); verts.append(cleanVerts); cleanVerts.clear(); -- cgit v1.2.3 From 4273690478ccdc74528fa6ea6698cfa2062fa2fc Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 17:42:05 -0500 Subject: Core/Mmaps: Allow disabling pathfinding for specific maps in the config --- src/server/game/World/World.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 928a8184d5d..0d55d7a52e8 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1126,6 +1126,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); sLog->outString("WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); + MMap::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); -- cgit v1.2.3 From c3f75cdf1d8c686a3061ef6c8b63a92bae5954c8 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 17:47:58 -0500 Subject: Core/MMaps: Do not allow creatures that cant fly to take off the land, even when building shorcut paths. --- src/server/game/Entities/Unit/Unit.cpp | 2 +- .../MovementGenerators/PathFinderMovementGenerator.cpp | 10 ++++++++++ .../Movement/MovementGenerators/PathFinderMovementGenerator.h | 2 ++ .../Movement/MovementGenerators/TargetedMovementGenerator.cpp | 9 ++++----- src/server/game/Movement/Spline/MoveSplineInit.h | 6 +++--- 5 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2ba3b4e8c06..183eddfcae4 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -373,7 +373,7 @@ bool Unit::haveOffhandWeapon() const void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath, bool forceDestination) { Movement::MoveSplineInit init(*this); - init.MoveTo(x,y,z); + init.MoveTo(x, y, z, generatePath, forceDestination); init.SetVelocity(speed); init.Launch(); } diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 4894b5eb841..3172deb210e 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -443,6 +443,8 @@ void PathFinderMovementGenerator::BuildPointPath(const float *startPoint, const for (uint32 i = 0; i < pointCount; ++i) m_pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); + NormalizePath(); + // first point is always our current location - we need the next one setActualEndPosition(m_pathPoints[pointCount-1]); @@ -469,6 +471,12 @@ void PathFinderMovementGenerator::BuildPointPath(const float *startPoint, const sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength); } +void PathFinderMovementGenerator::NormalizePath() +{ + for (uint32 i = 0; i < m_pathPoints.size(); ++i) + m_sourceUnit->UpdateAllowedPositionZ(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z); +} + void PathFinderMovementGenerator::BuildShortcut() { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); @@ -482,6 +490,8 @@ void PathFinderMovementGenerator::BuildShortcut() m_pathPoints[0] = getStartPosition(); m_pathPoints[1] = getActualEndPosition(); + NormalizePath(); + m_type = PATHFIND_SHORTCUT; } diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h index f4edd1a1789..5dd2ad82a0a 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h @@ -98,6 +98,8 @@ class PathFinderMovementGenerator void setStartPosition(Vector3 point) { m_startPosition = point; } void setEndPosition(Vector3 point) { m_actualEndPosition = point; m_endPosition = point; } void setActualEndPosition(Vector3 point) { m_actualEndPosition = point; } + + void NormalizePath(); void clear() { diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 1680bfeb1d4..766fe0b8032 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -79,11 +79,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) owner.AddUnitState(UNIT_STATE_CHASE); Movement::MoveSplineInit init(owner); - if (!i_target->IsInWater()) - init.MovebyPath(i_path->getPath()); - else - init.MoveTo(i_target->GetPositionX(), i_target->GetPositionY(), i_target->GetPositionZ(), false, false); - + init.MovebyPath(i_path->getPath()); init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } @@ -128,6 +124,9 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ D::_clearUnitStateMove(owner); return true; } + + if (owner.GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor((const Creature*)&owner)) + return false; // prevent movement while casting spells with cast time or channel time if (owner.HasUnitState(UNIT_STATE_CASTING)) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 4efde66fcd5..740914c59db 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -84,10 +84,10 @@ namespace Movement */ void MovebyPath(const PointsArray& path, int32 pointId = 0); - /* Initializes simple A to B mition, A is current unit's position, B is destination + /* Initializes simple A to B motion, A is current unit's position, B is destination */ - void MoveTo(const Vector3& destination, bool generatePath = false, bool forceDestination = false); - void MoveTo(float x, float y, float z, bool generatePath = false, bool forceDestination = false); + void MoveTo(const Vector3& destination, bool generatePath = true, bool forceDestination = false); + void MoveTo(float x, float y, float z, bool generatePath = true, bool forceDestination = false); /* Sets Id of fisrt point of the path. When N-th path point will be done ILisener will notify that pointId + N done * Needed for waypoint movement where path splitten into parts -- cgit v1.2.3 From 4c765aad3ddb0e8a890ee163cf3162d14c396d7e Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 18:00:58 -0500 Subject: Core/Maps: Reduce the output map file size in the maps extractor for maps that do not have any hole information Core/Mmaps: Fixed swimming creatures stuck in water. (Thanks Vlad and @Chevron ) Note: Re-extract maps --- src/server/game/Maps/Map.cpp | 33 ++++++++-------------- .../TargetedMovementGenerator.cpp | 3 -- src/tools/map_extractor/System.cpp | 19 +++++++++---- src/tools/mmaps_generator/TerrainBuilder.cpp | 11 +++++--- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 5e3699146f2..80668d23ed8 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -42,7 +42,7 @@ union u_map_magic }; u_map_magic MapMagic = { {'M','A','P','S'} }; -u_map_magic MapVersionMagic = { {'v','1','.','2'} }; +u_map_magic MapVersionMagic = { {'v','1','.','3'} }; u_map_magic MapAreaMagic = { {'A','R','E','A'} }; u_map_magic MapHeightMagic = { {'M','H','G','T'} }; u_map_magic MapLiquidMagic = { {'M','L','I','Q'} }; @@ -124,19 +124,12 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { // DONT CHANGE "gy" and "gx" - Its necessary ! - int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); - switch (mmapLoadResult) - { - case MMAP::MMAP_LOAD_RESULT_OK: - sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - case MMAP::MMAP_LOAD_RESULT_ERROR: - sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - case MMAP::MMAP_LOAD_RESULT_IGNORED: - sLog->outStaticDebug("Ignored MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); - break; - } + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); + + if (result) + sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + else + sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); } void Map::LoadVMap(int gx, int gy) @@ -187,18 +180,16 @@ void Map::LoadMap(int gx, int gy, bool reload) } // map file name - char *tmp=NULL; - int len = sWorld->GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1; + char* tmp = NULL; + int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1; tmp = new char[len]; - snprintf(tmp, len, (char *)(sWorld->GetDataPath()+"maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); + snprintf(tmp, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); sLog->outInfo(LOG_FILTER_MAPS, "Loading map %s", tmp); // loading data GridMaps[gx][gy] = new GridMap(); if (!GridMaps[gx][gy]->loadData(tmp)) - { sLog->outError(LOG_FILTER_MAPS, "Error loading map file: \n %s\n", tmp); - } - delete [] tmp; + delete[] tmp; sScriptMgr->OnLoadGridMap(this, GridMaps[gx][gy], gx, gy); } @@ -1094,7 +1085,7 @@ GridMap::~GridMap() unloadData(); } -bool GridMap::loadData(char *filename) +bool GridMap::loadData(char* filename) { // Unload old data if exist unloadData(); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 766fe0b8032..1fc2ab5a6cb 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -125,9 +125,6 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ return true; } - if (owner.GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor((const Creature*)&owner)) - return false; - // prevent movement while casting spells with cast time or channel time if (owner.HasUnitState(UNIT_STATE_CASTING)) { diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index e34bc4221e7..ad9a663ac27 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.2"; +static char const* MAP_VERSION_MAGIC = "v1.3"; static char const* MAP_AREA_MAGIC = "AREA"; static char const* MAP_HEIGHT_MAGIC = "MHGT"; static char const* MAP_LIQUID_MAGIC = "MLIQ"; @@ -836,8 +836,8 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, else map.holesOffset = map.heightMapOffset + map.heightMapSize; - map.holesSize = sizeof(holes); memset(holes, 0, map.holesSize); + bool hasHoles = false; for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) { @@ -847,12 +847,19 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, if (!cell) continue; holes[i][j] = cell->holes; + if (!hasHoles && cell->holes != 0) + hasHoles = true; } } + + if (hasHoles) + map.holesSize = sizeof(holes); + else + map.holesSize = 0; // Ok all data prepared - store it - FILE *output=fopen(filename2, "wb"); - if(!output) + FILE* output = fopen(filename2, "wb"); + if (!output) { printf("Can't create the output file '%s'\n", filename2); return false; @@ -899,8 +906,10 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } + // store hole data - fwrite(holes, map.holesSize, 1, output); + if (hasHoles) + fwrite(holes, map.holesSize, 1, output); fclose(output); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index e16dd16707b..7ee4dc7f46c 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -159,9 +159,12 @@ namespace MMAP } // hole data - memset(holes, 0, fheader.holesSize); - fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); + if (fheader.holesSize != 0) + { + memset(holes, 0, fheader.holesSize); + fseek(mapFile, fheader.holesOffset, SEEK_SET); + fread(holes, fheader.holesSize, 1, mapFile); + } int count = meshData.solidVerts.size() / 3; float xoffset = (float(tileX)-32)*GRID_SIZE; @@ -379,7 +382,7 @@ namespace MMAP } // if there is a hole here, don't use the terrain - if (useTerrain) + if (useTerrain && fheader.holesSize != 0) useTerrain = !isHole(i, holes); // we use only one terrain kind per quad - pick higher one -- cgit v1.2.3 From 45fc80736dbb733628537612b478d9a5415aeb9e Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 22 Aug 2012 18:03:01 -0500 Subject: Core/Mmaps: Allow swimming creatures to move underwater when there is a hole in the mesh --- .../PathFinderMovementGenerator.cpp | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 3172deb210e..82dcbc07648 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -180,14 +180,32 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly); // we have a hole in our mesh - // make shortcut path and mark it as NOPATH ( with flying exception ) + // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) // its up to caller how he will use this info if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF) { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); BuildShortcut(); - m_type = (m_sourceUnit->GetTypeId() == TYPEID_UNIT && ((Creature*)m_sourceUnit)->CanFly()) - ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; + bool path = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->CanFly(); + + bool waterPath = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->canSwim(); + if (waterPath) + { + // Check both start and end points, if they're both in water, then we can *safely* let the creature move + for (int i = 0; i < m_pathPoints.size(); ++i) + { + LiquidData data; + m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); + // One of the points is not in the water, cancel movement. + if (data.type_flags == MAP_LIQUID_TYPE_NO_WATER) + { + waterPath = false; + break; + } + } + } + + m_type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; return; } -- cgit v1.2.3 From 937518181f2513e4ef43700d5b856349ebb7c7e6 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 24 Aug 2012 11:38:39 -0500 Subject: Core/Mmaps: Fixed build after last merge --- src/server/collision/Management/MMapManager.cpp | 30 +++++++++++----------- src/server/game/Maps/Map.cpp | 6 ++--- .../PathFinderMovementGenerator.cpp | 6 ++--- src/server/game/Movement/Spline/MoveSplineInit.cpp | 21 ++++++++++----- src/server/game/Movement/Spline/MoveSplineInit.h | 18 +------------ src/server/game/World/World.cpp | 4 +-- src/tools/mmaps_generator/TerrainBuilder.h | 2 +- 7 files changed, 40 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 449abcb967d..0222f1a5995 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -60,14 +60,14 @@ namespace MMAP if (DT_SUCCESS != mesh->init(¶ms)) { dtFreeNavMesh(mesh); - sLog->outError("MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); delete [] fileName; return false; } delete [] fileName; - sLog->outDetail("MMAP:loadMapData: Loaded %03i.mmap", mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMapData: Loaded %03i.mmap", mapId); // store inside our map list MMapData* mmap_data = new MMapData(mesh); @@ -118,13 +118,13 @@ namespace MMAP if (fileHeader.mmapMagic != MMAP_MAGIC) { - sLog->outError("MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); return false; } if (fileHeader.mmapVersion != MMAP_VERSION) { - sLog->outError("MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION); return false; } @@ -135,7 +135,7 @@ namespace MMAP size_t result = fread(data, fileHeader.size, 1, file); if (!result) { - sLog->outError("MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); fclose(file); return false; } @@ -150,12 +150,12 @@ namespace MMAP { mmap->mmapLoadedTiles.insert(std::pair(packedGridPos, tileRef)); ++loadedTiles; - sLog->outDetail("MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); return true; } else { - sLog->outError("MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); dtFree(data); return false; } @@ -192,14 +192,14 @@ namespace MMAP // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used // we cannot recover from this error - assert out - sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); ASSERT(false); } else { mmap->mmapLoadedTiles.erase(packedGridPos); --loadedTiles; - sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); return true; } @@ -222,17 +222,17 @@ namespace MMAP uint32 x = (i->first >> 16); uint32 y = (i->first & 0x0000FFFF); if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL)) - sLog->outError("MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); else { --loadedTiles; - sLog->outDetail("MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); } } delete mmap; loadedMMaps.erase(mapId); - sLog->outDetail("MMAP:unloadMap: Unloaded %03i.mmap", mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded %03i.mmap", mapId); return true; } @@ -258,7 +258,7 @@ namespace MMAP dtFreeNavMeshQuery(query); mmap->navMeshQueries.erase(instanceId); - sLog->outDetail("MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); return true; } @@ -285,11 +285,11 @@ namespace MMAP if (DT_SUCCESS != query->init(mmap->navMesh, 1024)) { dtFreeNavMeshQuery(query); - sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + sLog->outError(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); return NULL; } - sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); mmap->navMeshQueries.insert(std::pair(instanceId, query)); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 80668d23ed8..c960d8123fe 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -126,10 +126,10 @@ void Map::LoadMMap(int gx, int gy) // DONT CHANGE "gy" and "gx" - Its necessary ! bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); - if (result) - sLog->outDetail("MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + if (mmapLoadResult) + sLog->outInfo(LOG_FILTER_MAPS, "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); else - sLog->outDetail("Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); + sLog->outInfo(LOG_FILTER_MAPS, "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); } void Map::LoadVMap(int gx, int gy) diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 82dcbc07648..8988aa599da 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -88,7 +88,7 @@ bool PathFinderMovementGenerator::calculate(float destX, float destY, float dest { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride - sLog->outStaticDebug("++ PathFinderMovementGenerator::calculate:: precalculated path\n"); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::calculate:: precalculated path\n"); m_pathPoints.erase(m_pathPoints.begin()); return false; @@ -367,7 +367,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix - sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); } sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); @@ -399,7 +399,7 @@ void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const V if (!m_polyLength || dtResult != DT_SUCCESS) { // only happens if we passed bad data to findPath(), or navmesh is messed up - sLog->outError("%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); BuildShortcut(); m_type = PATHFIND_NOPATH; return; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 5fca373503e..7452efc94ca 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -79,7 +79,7 @@ namespace Movement // should i do the things that user should do? - no. if (args.path.empty()) - return; + return 0; // corrent first vertex args.path[0] = real_position; @@ -148,12 +148,21 @@ namespace Movement args.flags.EnableFacingAngle(); } - void MoveSplineInit::MoveTo(Vector3 const& dest) + void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) { - args.path_Idx_offset = 0; - args.path.resize(2); - TransportPathTransform transform(unit, args.TransformForTransport); - args.path[1] = transform(dest); + if (generatePath) + { + PathFinderMovementGenerator path(&unit); + path.calculate(dest.x, dest.y, dest.z, forceDestination); + MovebyPath(path.getPath()); + } + else + { + args.path_Idx_offset = 0; + args.path.resize(2); + TransportPathTransform transform(unit, args.TransformForTransport); + args.path[1] = transform(dest); + } } Vector3 TransportPathTransform::operator()(Vector3 input) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 740914c59db..9130d2827e6 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -161,26 +161,10 @@ namespace Movement inline void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination) { - Vector3 v(x,y,z); + Vector3 v(x, y, z); MoveTo(v, generatePath, forceDestination); } - inline void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) - { - if (generatePath) - { - PathFinderMovementGenerator path(&unit); - path.calculate(dest.x, dest.y, dest.z, forceDestination); - MovebyPath(path.getPath()); - } - else - { - args.path_Idx_offset = 0; - args.path.resize(2); - args.path[1] = dest; - } - } - inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift) { args.time_perc = time_shift; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0d55d7a52e8..dee1b6dcdb8 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1125,8 +1125,8 @@ void World::LoadConfigSettings(bool reload) } m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); - sLog->outString("WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); - MMap::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); + MMAP::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index a7f21883af2..6d478753279 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -62,7 +62,7 @@ namespace MMAP // see following files: // contrib/extractor/system.cpp // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.2"; + static char const* MAP_VERSION_MAGIC = "v1.3"; struct MeshData { -- cgit v1.2.3 From 4351548c750f94425d8b7c24180a813acb6ac443 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 24 Aug 2012 15:33:38 -0500 Subject: Tools/MapExtractor: Fixed a crash caused by using a variable before it was initialized --- src/tools/map_extractor/System.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index ad9a663ac27..44e852b12b9 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -836,7 +836,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, else map.holesOffset = map.heightMapOffset + map.heightMapSize; - memset(holes, 0, map.holesSize); + memset(holes, 0, sizeof(holes)); bool hasHoles = false; for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) -- cgit v1.2.3 From 9698d295b234bcbda3a52c9a47e57f66a98e5335 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 24 Aug 2012 20:03:57 -0500 Subject: Core/Mmaps: Refactored some code --- src/server/game/Movement/MotionMaster.h | 2 +- .../game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp | 2 +- .../game/Movement/MovementGenerators/FleeingMovementGenerator.cpp | 2 +- .../Movement/MovementGenerators/PathFinderMovementGenerator.cpp | 6 +++--- .../game/Movement/MovementGenerators/PathFinderMovementGenerator.h | 4 ++-- .../game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 2 +- src/server/game/Movement/Spline/MoveSplineInit.cpp | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 918896a5a81..16accff2ab4 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -160,7 +160,7 @@ class MotionMaster //: private std::stack void MoveLand(uint32 id, Position const& pos); void MoveTakeoff(uint32 id, Position const& pos); - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = true); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index bad45f65178..a4f57a43701 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -78,7 +78,7 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) PathFinderMovementGenerator path(&unit); path.setPathLengthLimit(30.0f); - path.calculate(x, y, z); + path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 9d99e0ef000..4e96c641be7 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -45,7 +45,7 @@ void FleeingMovementGenerator::_setTargetLocation(T &owner) PathFinderMovementGenerator path(&owner); path.setPathLengthLimit(30.0f); - path.calculate(x, y, z); + path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) { i_nextCheckTime.Reset(urand(1000, 1500)); diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp index 8988aa599da..adfd32c50b3 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp @@ -50,7 +50,7 @@ PathFinderMovementGenerator::~PathFinderMovementGenerator() sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::~PathFinderMovementGenerator() for %u \n", m_sourceUnit->GetGUIDLow()); } -bool PathFinderMovementGenerator::calculate(float destX, float destY, float destZ, bool forceDest) +bool PathFinderMovementGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) { if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) @@ -67,7 +67,7 @@ bool PathFinderMovementGenerator::calculate(float destX, float destY, float dest m_forceDestination = forceDest; - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::calculate() for %u \n", m_sourceUnit->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::CalculatePath() for %u \n", m_sourceUnit->GetGUIDLow()); // make sure navMesh works - we can run on map w/o mmap // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) @@ -88,7 +88,7 @@ bool PathFinderMovementGenerator::calculate(float destX, float destY, float dest { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::calculate:: precalculated path\n"); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::CalculatePath:: precalculated path\n"); m_pathPoints.erase(m_pathPoints.begin()); return false; diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h index 5dd2ad82a0a..9029fc1804e 100644 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h @@ -59,10 +59,10 @@ class PathFinderMovementGenerator // Calculate the path from owner to given destination // return: true if new path was calculated, false otherwise (no change needed) - bool calculate(float destX, float destY, float destZ, bool forceDest = false); + bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); // option setters - use optional - void setUseStrightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; + void SetUseStraightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; void setPathLengthLimit(float distance) { m_pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; // result getters diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 1fc2ab5a6cb..1b14cd385e8 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -69,7 +69,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) // allow pets following their master to cheat while generating paths bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet() && owner.HasUnitState(UNIT_STATE_FOLLOW)); - i_path->calculate(x, y, z, forceDest); + i_path->CalculatePath(x, y, z, forceDest); if (i_path->getPathType() & PATHFIND_NOPATH) return; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 7452efc94ca..fa2197f815e 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -73,7 +73,7 @@ namespace Movement } // there is a big chance that current position is unknown if current state is not finalized, need compute it - // this also allows calculate spline position and update map position in much greater intervals + // this also allows CalculatePath spline position and update map position in much greater intervals if (!move_spline.Finalized()) real_position = move_spline.ComputePosition(); @@ -153,7 +153,7 @@ namespace Movement if (generatePath) { PathFinderMovementGenerator path(&unit); - path.calculate(dest.x, dest.y, dest.z, forceDestination); + path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); MovebyPath(path.getPath()); } else -- cgit v1.2.3 From f8cc38d65a3b8bca5f93f57e7f4cf7f93df2b38b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 11:38:33 -0500 Subject: Core/Mmaps: Make the mmaps_generator multithreaded, you can specify the max number of threads that are spawned at the same time (default 3) by using "--threads x" in the command line, where x is the number of threads you want. Core/Mmaps: Removed now useless sh script --- contrib/extract/extract_data.sh | 162 ---------------------------- contrib/extract/libmysql.dll | Bin 2316288 -> 0 bytes contrib/extract/mapextractor.exe | Bin 314368 -> 0 bytes contrib/extract/mmaps_generator.exe | Bin 2224128 -> 0 bytes contrib/extract/offmesh.txt | 3 - contrib/extract/only_extract_offmesh.sh | 158 --------------------------- contrib/extract/vmap4assembler.exe | Bin 1427456 -> 0 bytes contrib/extract/vmap4extractor.exe | Bin 321536 -> 0 bytes src/tools/mmaps_generator/MapBuilder.cpp | 74 ++++++++----- src/tools/mmaps_generator/MapBuilder.h | 20 +++- src/tools/mmaps_generator/PathGenerator.cpp | 17 ++- 11 files changed, 78 insertions(+), 356 deletions(-) delete mode 100644 contrib/extract/extract_data.sh delete mode 100644 contrib/extract/libmysql.dll delete mode 100644 contrib/extract/mapextractor.exe delete mode 100644 contrib/extract/mmaps_generator.exe delete mode 100644 contrib/extract/offmesh.txt delete mode 100644 contrib/extract/only_extract_offmesh.sh delete mode 100644 contrib/extract/vmap4assembler.exe delete mode 100644 contrib/extract/vmap4extractor.exe (limited to 'src') diff --git a/contrib/extract/extract_data.sh b/contrib/extract/extract_data.sh deleted file mode 100644 index d28c7b7d7f5..00000000000 --- a/contrib/extract/extract_data.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2005-2012 MaNGOS project -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -## Expected param 1 to be 'a' for all, else ask some questions - -## Normal log file (if not overwritten by second param -LOG_FILE="TrinityCoreExtractor.log" -## Detailed log file -DETAIL_LOG_FILE="TrinityCoreExtractor_detailed.log" - -## Change this to a value fitting for your sys! -NUM_CPU="2" - -## ! Use below only for finetuning or if you know what you are doing ! - -USE_MAPS="0" -USE_VMAPS="0" -USE_MMAPS="0" -USE_MMAPS_OFFMESH="0" - -if [ "$1" = "a" ] -then - ## extract all - USE_MAPS="1" - USE_VMAPS="1" - USE_MMAPS="1" -else - ## do some questioning! - echo - echo "Welcome to helper script to extract required dataz for TrinityCore!" - echo "Should all dataz (dbc, maps, vmaps and mmaps be extracted? (y/n)" - read line - if [ "$line" = "y" ] - then - ## extract all - USE_MAPS="1" - USE_VMAPS="1" - USE_MMAPS="1" - else - echo - echo "Should dbc and maps be extracted? (y/n)" - read line - if [ "$line" = "y" ]; then USE_MAPS="1"; fi - - echo - echo "Should vmaps be extracted? (y/n)" - read line - if [ "$line" = "y" ]; then USE_VMAPS="1"; fi - - echo - echo "Should mmaps be extracted? (y/n)" - echo "WARNING! This will take several hours!" - read line - if [ "$line" = "y" ] - then - USE_MMAPS="1"; - else - echo "Only reextract offmesh tiles for mmaps?" - read line - if [ "$line" = "y" ] - then - USE_MMAPS_OFFMESH="1"; - fi - fi - fi -fi - -## Special case: Only reextract offmesh tiles -if [ "$USE_MMAPS_OFFMESH" = "1" ] -then - echo "Only extracting offmesh meshes" - only_extract_offmesh.sh offmesh $LOG_FILE $DETAIL_LOG_FILE - exit 0 -fi - -## Obtain numbe ob processes -if [ "$USE_MMAPS" = "1" ] -then - echo "How many CPUs should be used for extracting mmaps? (1-4)" - read line - if [ "$line" -ge "1" -a "$line" -le "4" ] - then - NUM_CPU=$line - else - echo "Only number between 1 and 4 supported!" - exit 1 - fi -fi - -## Give some status -echo "Current Settings: Extract DBCs/maps: $USE_AD, Extract vmaps: $USE_VMAPS, Extract mmaps: $USE_MMAPS on $NUM_CPU processes" -if [ "$1" != "a" ] -then - echo "If you don't like this settings, interrupt with CTRL+C" - read line -fi - -echo "`date`: Start extracting dataz for TrinityCore" | tee $LOG_FILE - -## Handle log messages -if [ "$USE_AD" = "1" ]; -then - echo "DBC and map files will be extracted" | tee -a $LOG_FILE -else - echo "DBC and map files won't be extracted!" | tee -a $LOG_FILE -fi -if [ "$USE_VMAPS" = "1" ] -then - echo "Vmaps will be extracted" | tee -a $LOG_FILE -else - echo "Vmaps won't be extracted!" | tee -a $LOG_FILE -fi -if [ "$USE_MMAPS" = "1" ] -then - echo "Mmaps will be extracted with $NUM_CPU processes" | tee -a $LOG_FILE -else - echo "Mmaps files won't be extracted!" | tee -a $LOG_FILE -fi -echo | tee -a $LOG_FILE - -echo "`date`: Start extracting dataz for TrinityCore, DBCs/maps $USE_AD, vmaps $USE_VMAPS, mmaps $USE_MMAPS on $NUM_CPU processes" | tee $DETAIL_LOG_FILE -echo | tee -a $DETAIL_LOG_FILE - -## Extract dbcs and maps -if [ "$USE_AD" = "1" ] -then - echo "`date`: Start extraction of DBCs and map files..." | tee -a $LOG_FILE - ad | tee -a $DETAIL_LOG_FILE - echo "`date`: Extracting of DBCs and map files finished" | tee -a $LOG_FILE - echo | tee -a $LOG_FILE - echo | tee -a $DETAIL_LOG_FILE -fi - -## Extract vmaps -if [ "$USE_VMAPS" = "1" ] -then - echo "`date`: Start extraction of vmaps..." | tee -a $LOG_FILE - vmap4extractor | tee -a $DETAIL_LOG_FILE - echo "`date`: Extracting of vmaps finished" | tee -a $LOG_FILE - mkdir vmaps - echo "`date`: Start assembling of vmaps..." | tee -a $LOG_FILE - vmap4assembler.exe buildings vmaps | tee -a $DETAIL_LOG_FILE - echo "`date`: Assembling of vmaps finished" | tee -a $LOG_FILE - - echo | tee -a $LOG_FILE - echo | tee -a $DETAIL_LOG_FILE -fi - -## Extract mmaps -if [ "$USE_MMAPS" = "1" ] -then - only_extract_offmesh.sh $NUM_CPU $LOG_FILE $DETAIL_LOG_FILE -fi diff --git a/contrib/extract/libmysql.dll b/contrib/extract/libmysql.dll deleted file mode 100644 index 36de6064f98..00000000000 Binary files a/contrib/extract/libmysql.dll and /dev/null differ diff --git a/contrib/extract/mapextractor.exe b/contrib/extract/mapextractor.exe deleted file mode 100644 index ae6d150ba0e..00000000000 Binary files a/contrib/extract/mapextractor.exe and /dev/null differ diff --git a/contrib/extract/mmaps_generator.exe b/contrib/extract/mmaps_generator.exe deleted file mode 100644 index 8cd9ff65c26..00000000000 Binary files a/contrib/extract/mmaps_generator.exe and /dev/null differ diff --git a/contrib/extract/offmesh.txt b/contrib/extract/offmesh.txt deleted file mode 100644 index 10299a2c696..00000000000 --- a/contrib/extract/offmesh.txt +++ /dev/null @@ -1,3 +0,0 @@ -0 31,59 (-14429.889648 450.344452 15.430828) (-14424.218750 444.332855 12.773965) 2.5 // booty bay dock -562 31,20 (6234.545898 256.902100 11.075373) (6230.961914 252.127274 11.180979) 2.5 // Blade's Edge Arena -562 31,20 (6243.081543 266.918854 11.059557) (6246.507324 271.623505 11.230524) 2.5 // Blade's Edge Arena \ No newline at end of file diff --git a/contrib/extract/only_extract_offmesh.sh b/contrib/extract/only_extract_offmesh.sh deleted file mode 100644 index 700626856ee..00000000000 --- a/contrib/extract/only_extract_offmesh.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2005-2012 MaNGOS project -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -## Syntax of this helper -## First param must be number of to be used CPUs (only 1, 2, 3, 4 supported) or "offmesh" to recreate the special tiles from the OFFMESH_FILE -## Second param can be an additional filename for storing log -## Third param can be an addition filename for storing detailed log - -## Additional Parameters to be forwarded to MoveMapGen, see mmaps/readme for instructions -PARAMS="--silent" - -## Already a few map extracted, and don't care anymore -EXCLUDE_MAPS="" -#EXCLUDE_MAPS="0 1 530 571" # example to exclude the continents - -## Offmesh file -OFFMESH_FILE="offmesh.txt" - -## Normal log file (if not overwritten by second param -LOG_FILE="movemap.log" -## Detailed log file -DETAIL_LOG_FILE="movemap_detailed.log" - -## ! Use below only for finetuning or if you know what you are doing ! - -## All maps -MAP_LIST_A="1 37 543 595 289 572 529 562 531 269 47 649 650 599 548 559 429 230 573 349 13 25 409 229 43 48 546 553 547 604 545 90 576" -MAP_LIST_B="571 628 560 509 723 532 607 600 668 33 585 566 389 601 369 129 550 189 542 70 109 554 632 552 555 540 598 450 558 249 35 624 557" -MAP_LIST_C="0 631 609 534 533 619 469 602 329 580 615 578 36 556 44 565 544 34 617 608 618 449 616 42 451 582 584 586 587 588 589 590 591 592" -MAP_LIST_D="530 169 575 603 309 574 30 564 568 209 724 658 489 593 594 596 597 605 606 610 612 613 614 620 621 622 623 641 642 647 672 673 712 713 718" -MAP_LIST_D1="209 724 658 489 606 610 612 613 614 620 621" -MAP_LIST_D2="169 575 603 309 574 30 564 568 622 623 641 642 647 672 673 712 713 718" -MAP_LIST_D3="530 593 594 596 597 605" - -badParam() -{ - echo "ERROR! Bad arguments!" - echo "You can (re)extract mmaps with this helper script," - echo "or recreate only the tiles from the offmash file" - echo - echo "Call with number of processes (1 - 4) to create mmaps" - echo "Call with 'offmesh' to reextract the tiles from offmash file" - echo - echo "For further fine-tuning edit this helper script" - echo -} - -if [ "$#" = "3" ] -then - LOG_FILE=$2 - DETAIL_LOG_FILE=$3 -elif [ "$#" = "2" ] -then - LOG_FILE=$2 -fi - -# Offmesh file provided? -OFFMESH="" -if [ "$OFFMESH_FILE" != "" ] -then - if [ ! -f "$OFFMESH_FILE" ] - then - echo "ERROR! Offmesh file $OFFMESH_FILE could not be found." - echo "Provide valid file or none. You need to edit the script" - exit 1 - else - OFFMESH="--offMeshInput $OFFMESH_FILE" - fi -fi - -# Function to process a list -createMMaps() -{ - for i in $@ - do - for j in $EXCLUDE_MAPS - do - if [ "$i" = "$j" ] - then - continue 2 - fi - done - ./mmaps_generator $PARAMS $OFFMESH $i | tee -a $DETAIL_LOG_FILE - echo "`date`: (Re)created map $i" | tee -a $LOG_FILE - done -} - -createHeader() -{ - echo "`date`: Start creating mmaps_generator" | tee -a $LOG_FILE - echo "Used params: $PARAMS $OFFMESH" | tee -a $LOG_FILE - echo "Detailed log can be found in $DETAIL_LOG_FILE" | tee -a $LOG_FILE - echo "Start creating mmaps_generator" | tee -a $DETAIL_LOG_FILE - echo - echo "Be PATIENT - This will take a long time and might also have gaps between visible changes on the console." - echo "WAIT until you are informed that 'creating mmaps_generator' is 'finished'!" -} - -# Create mmaps directory if not exist -if [ ! -d mmaps ] -then - mkdir mmaps -fi - -# Param control -case "$1" in - "1" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_B $MAP_LIST_C $MAP_LIST_D & - ;; - "2" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_D & - createMMaps $MAP_LIST_B $MAP_LIST_C & - ;; - "3" ) - createHeader $1 - createMMaps $MAP_LIST_A $MAP_LIST_D1& - createMMaps $MAP_LIST_B $MAP_LIST_D2& - createMMaps $MAP_LIST_C $MAP_LIST_D3& - ;; - "4" ) - createHeader $1 - createMMaps $MAP_LIST_A & - createMMaps $MAP_LIST_B & - createMMaps $MAP_LIST_C & - createMMaps $MAP_LIST_D & - ;; - "offmesh" ) - echo "`date`: Recreate offmeshs from file $OFFMESH_FILE" | tee -a $LOG_FILE - echo "Recreate offmeshs from file $OFFMESH_FILE" | tee -a $DETAIL_LOG_FILE - while read map tile line - do - ./mmaps_generator $PARAMS $OFFMESH $map --tile $tile | tee -a $DETAIL_LOG_FILE - echo "`date`: Recreated $map $tile from $OFFMESH_FILE" | tee -a $LOG_FILE - done < $OFFMESH_FILE & - ;; - * ) - badParam - exit 1 - ;; -esac - -wait - -echo | tee -a $LOG_FILE -echo | tee -a $DETAIL_LOG_FILE -echo "`date`: Finished creating MoveMaps" | tee -a $LOG_FILE -echo "`date`: Finished creating MoveMaps" >> $DETAIL_LOG_FILE diff --git a/contrib/extract/vmap4assembler.exe b/contrib/extract/vmap4assembler.exe deleted file mode 100644 index e5331a5f70e..00000000000 Binary files a/contrib/extract/vmap4assembler.exe and /dev/null differ diff --git a/contrib/extract/vmap4extractor.exe b/contrib/extract/vmap4extractor.exe deleted file mode 100644 index 4866904d04f..00000000000 Binary files a/contrib/extract/vmap4extractor.exe and /dev/null differ diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index e47b2e5b44f..a0c40bc4392 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -158,13 +158,31 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::buildAllMaps() + void MapBuilder::buildAllMaps(int threads) { + int running = 0; for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { uint32 mapID = (*it).first; if (!shouldSkipMap(mapID)) - buildMap(mapID); + { + if (threads > 1) + { + BuilderThread* thread = new BuilderThread(this, mapID); + thread->activate(); + ++running; + // Do not allow more than {threads} threads running at the same time + if (running == threads) + { + // Wait for previous threads to finish + ACE_Thread_Manager::instance()->wait(); + // Reset the number of running threads + running = 0; + } + } + else + buildMap(mapID); + } } } @@ -306,7 +324,7 @@ namespace MMAP } // now start building mmtiles for each tile - printf("We have %u tiles. \n", (unsigned int)tiles->size()); + printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; @@ -415,10 +433,10 @@ namespace MMAP navMeshParams.maxPolys = maxPolysPerTile; navMesh = dtAllocNavMesh(); - printf("Creating navMesh... \r"); + printf("[Map %i] Creating navMesh...\n", mapID); if (!navMesh->init(&navMeshParams)) { - printf("Failed creating navmesh! \n"); + printf("[Map %i] Failed creating navmesh! \n", mapID); return; } @@ -430,7 +448,7 @@ namespace MMAP { dtFreeNavMesh(navMesh); char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); + sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName); perror(message); return; } @@ -446,9 +464,9 @@ namespace MMAP dtNavMesh* navMesh) { // console output - char tileString[10]; - sprintf(tileString, "[%02i,%02i]: ", tileX, tileY); - printf("%s Building movemap tiles... \r", tileString); + char tileString[20]; + sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY); + printf("%s Building movemap tiles...\n", tileString); IntermediateValues iv; @@ -510,14 +528,14 @@ namespace MMAP rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; if (!pmmerge) { - printf("%s alloc pmmerge FIALED! \r", tileString); + printf("%s alloc pmmerge FIALED!\n", tileString); return; } rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; if (!dmmerge) { - printf("%s alloc dmmerge FIALED! \r", tileString); + printf("%s alloc dmmerge FIALED!\n", tileString); return; } @@ -539,7 +557,7 @@ namespace MMAP tile.solid = rcAllocHeightfield(); if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) { - printf("%sFailed building heightfield! \n", tileString); + printf("%s Failed building heightfield! \n", tileString); continue; } @@ -560,33 +578,33 @@ namespace MMAP tile.chf = rcAllocCompactHeightfield(); if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) { - printf("%sFailed compacting heightfield! \n", tileString); + printf("%s Failed compacting heightfield! \n", tileString); continue; } // build polymesh intermediates if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) { - printf("%sFailed eroding area! \n", tileString); + printf("%s Failed eroding area! \n", tileString); continue; } if (!rcBuildDistanceField(m_rcContext, *tile.chf)) { - printf("%sFailed building distance field! \n", tileString); + printf("%s Failed building distance field! \n", tileString); continue; } if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) { - printf("%sFailed building regions! \n", tileString); + printf("%s Failed building regions! \n", tileString); continue; } tile.cset = rcAllocContourSet(); if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) { - printf("%sFailed building contours! \n", tileString); + printf("%s Failed building contours! \n", tileString); continue; } @@ -594,14 +612,14 @@ namespace MMAP tile.pmesh = rcAllocPolyMesh(); if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) { - printf("%sFailed building polymesh! \n", tileString); + printf("%s Failed building polymesh! \n", tileString); continue; } tile.dmesh = rcAllocPolyMeshDetail(); if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) { - printf("%sFailed building polymesh detail! \n", tileString); + printf("%s Failed building polymesh detail! \n", tileString); continue; } @@ -627,7 +645,7 @@ namespace MMAP iv.polyMesh = rcAllocPolyMesh(); if (!iv.polyMesh) { - printf("%s alloc iv.polyMesh FIALED! \r", tileString); + printf("%s alloc iv.polyMesh FIALED!\n", tileString); return; } rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); @@ -635,16 +653,16 @@ namespace MMAP iv.polyMeshDetail = rcAllocPolyMeshDetail(); if (!iv.polyMeshDetail) { - printf("%s alloc m_dmesh FIALED! \r", tileString); + printf("%s alloc m_dmesh FIALED!\n", tileString); return; } rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); // free things up - delete [] pmmerge; - delete [] dmmerge; + delete[] pmmerge; + delete[] dmmerge; - delete [] tiles; + delete[] tiles; // remove padding for extraction for (int i = 0; i < iv.polyMesh->nverts; ++i) @@ -736,7 +754,7 @@ namespace MMAP continue; } - printf("%s Building navmesh tile... \r", tileString); + printf("%s Building navmesh tile...\n", tileString); if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) { printf("%s Failed building navmesh tile! \n", tileString); @@ -744,7 +762,7 @@ namespace MMAP } dtTileRef tileRef = 0; - printf("%s Adding tile to navmesh... \r", tileString); + printf("%s Adding tile to navmesh...\n", tileString); // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile // is removed via removeTile() dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef); @@ -761,13 +779,13 @@ namespace MMAP if (!file) { char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", fileName); + sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName); perror(message); navMesh->removeTile(tileRef, NULL, NULL); continue; } - printf("%s Writing to file... \r", tileString); + printf("%s Writing to file...\n", tileString); // write header MmapTileHeader header; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 20789bf9bff..0c9dce05992 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -32,6 +32,8 @@ #include "Recast.h" #include "DetourNavMesh.h" +#include "ace/Task.h" + using namespace std; using namespace VMAP; @@ -80,7 +82,7 @@ namespace MMAP void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); // builds list of maps, then builds all of mmap tiles (based on the skip settings) - void buildAllMaps(); + void buildAllMaps(int threads); private: // detect maps and tiles @@ -125,6 +127,22 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; + + class BuilderThread : public ACE_Task + { + private: + MapBuilder* _builder; + uint32 _mapId; + public: + BuilderThread(MapBuilder* builder, uint32 mapId) : _builder(builder), _mapId(mapId) {} + + int svc() + { + if (_builder) + _builder->buildMap(_mapId); + return 0; + } + }; } #endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 7d9f59ed138..45d0aff958c 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -71,7 +71,8 @@ bool handleArgs(int argc, char** argv, bool &silent, bool &bigBaseUnit, char* &offMeshInputPath, - char* &file) + char* &file, + int& threads) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -88,6 +89,14 @@ bool handleArgs(int argc, char** argv, else printf("invalid option for '--maxAngle', using default\n"); } + else if (strcmp(argv[i], "--threads") == 0) + { + param = argv[++i]; + if (!param) + return false; + threads = atoi(param); + printf("Using %i threads to extract mmaps\n", threads); + } else if (strcmp(argv[i], "--file") == 0) { param = argv[++i]; @@ -232,7 +241,7 @@ int finish(const char* message, int returnValue) int main(int argc, char** argv) { - int mapnum = -1; + int threads = 3, mapnum = -1; float maxAngle = 60.0f; int tileX = -1, tileY = -1; bool skipLiquid = false, @@ -248,7 +257,7 @@ int main(int argc, char** argv) bool validParam = handleArgs(argc, argv, mapnum, tileX, tileY, maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath, file); + debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads); if (!validParam) return silent ? -1 : finish("You have specified invalid parameters", -1); @@ -278,7 +287,7 @@ int main(int argc, char** argv) else if (mapnum >= 0) builder.buildMap(uint32(mapnum)); else - builder.buildAllMaps(); + builder.buildAllMaps(threads); return silent ? 1 : finish("Movemap build is complete!", 1); } -- cgit v1.2.3 From 35437149e210ed713b04e01bf7607aa1475e158f Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 12:27:48 -0500 Subject: Core/Mmaps: Added some corrections to the logs in the mmaps_generator --- src/tools/mmaps_generator/MapBuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index a0c40bc4392..3b7a3e8d99d 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -294,7 +294,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildMap(uint32 mapID) { - printf("Building map %03u:\n", mapID); + printf("[Thread %i] Building map %03u:\n", ACE_Thread::self(), mapID); set* tiles = getTileList(mapID); @@ -340,7 +340,7 @@ namespace MMAP dtFreeNavMesh(navMesh); - printf("Complete! \n\n"); + printf("[Map %i] Complete!\n", mapID); } /**************************************************************************/ -- cgit v1.2.3 From c44601379179ad368bb2c80d371232c48f366f90 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 12:40:04 -0500 Subject: Core/Mmaps: Added elapsed time to the mmaps_generator --- src/tools/mmaps_generator/PathGenerator.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 45d0aff958c..4da90fd153a 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -18,6 +18,7 @@ #include "PathCommon.h" #include "MapBuilder.h" +#include "Timer.h" using namespace MMAP; @@ -280,6 +281,7 @@ int main(int argc, char** argv) MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); + uint32 start = getMSTime(); if (file) builder.buildMeshFromFile(file); else if (tileX > -1 && tileY > -1 && mapnum >= 0) @@ -289,5 +291,7 @@ int main(int argc, char** argv) else builder.buildAllMaps(threads); - return silent ? 1 : finish("Movemap build is complete!", 1); + if (!silent) + printf("Finished. MMAPS were built in %u ms!", GetMSTimeDiffToNow(start)); + return 1; } -- cgit v1.2.3 From f0473777e2751ce53790d5b2628f00c287540691 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 14:32:52 -0500 Subject: Core/Mmaps: Fixed jump effects (like Death Grip ). They should not use a path --- src/server/game/Movement/MotionMaster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index dd053534c8a..07d3760cf40 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -370,7 +370,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee float max_height = -Movement::computeFallElevation(moveTimeHalf,false,-speedZ); Movement::MoveSplineInit init(*_owner); - init.MoveTo(x,y,z); + init.MoveTo(x, y, z, false); init.SetParabolic(max_height,0); init.SetVelocity(speedXY); init.Launch(); -- cgit v1.2.3 From 92e72b2a5cd79c82625ceb6cc83125c546e7f1ab Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 17:37:15 -0500 Subject: Core/Mmaps: Fixed a few mistakes in the mmaps_generator, should be somewhat faster now --- src/tools/mmaps_generator/MapBuilder.cpp | 82 +++++++++++++++++++------------- src/tools/mmaps_generator/MapBuilder.h | 8 +++- 2 files changed, 56 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 3b7a3e8d99d..b04300994f9 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -160,30 +160,46 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildAllMaps(int threads) { - int running = 0; + std::vector _threads; + + for (int i = 0; i < threads; ++i) + _threads.push_back(new BuilderThread(this)); + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { - uint32 mapID = (*it).first; + uint32 mapID = it->first; if (!shouldSkipMap(mapID)) { if (threads > 1) { - BuilderThread* thread = new BuilderThread(this, mapID); - thread->activate(); - ++running; - // Do not allow more than {threads} threads running at the same time - if (running == threads) + bool next = false; + while (!next) { - // Wait for previous threads to finish - ACE_Thread_Manager::instance()->wait(); - // Reset the number of running threads - running = 0; + for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + { + if ((*_th)->Free) + { + printf("Thread is free for map %03i\n", mapID); + (*_th)->SetMapId(mapID); + (*_th)->activate(); + next = true; + break; + } + } + // Wait for 20 seconds + ACE_OS::sleep(ACE_Time_Value (0, 20000)); } } else buildMap(mapID); } } + // Wait for all threads to finish before closing down + ACE_Thread_Manager::instance()->wait(); + + // Free memory + for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + delete *_th; } /**************************************************************************/ @@ -311,34 +327,34 @@ namespace MMAP tiles->insert(StaticMapTree::packTileID(i, j)); } - if (!tiles->size()) - return; - - // build navMesh - dtNavMesh* navMesh = NULL; - buildNavMesh(mapID, navMesh); - if (!navMesh) + if (!tiles->empty()) { - printf("Failed creating navmesh! \n"); - return; - } + // build navMesh + dtNavMesh* navMesh = NULL; + buildNavMesh(mapID, navMesh); + if (!navMesh) + { + printf("Failed creating navmesh! \n"); + return; + } - // now start building mmtiles for each tile - printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) - { - uint32 tileX, tileY; + // now start building mmtiles for each tile + printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); + for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + { + uint32 tileX, tileY; - // unpack tile coords - StaticMapTree::unpackTileID((*it), tileX, tileY); + // unpack tile coords + StaticMapTree::unpackTileID((*it), tileX, tileY); - if (shouldSkipTile(mapID, tileX, tileY)) - continue; + if (shouldSkipTile(mapID, tileX, tileY)) + continue; - buildTile(mapID, tileX, tileY, navMesh); - } + buildTile(mapID, tileX, tileY, navMesh); + } - dtFreeNavMesh(navMesh); + dtFreeNavMesh(navMesh); + } printf("[Map %i] Complete!\n", mapID); } diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 0c9dce05992..61a71ff6d5b 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -134,14 +134,20 @@ namespace MMAP MapBuilder* _builder; uint32 _mapId; public: - BuilderThread(MapBuilder* builder, uint32 mapId) : _builder(builder), _mapId(mapId) {} + BuilderThread(MapBuilder* builder) : _builder(builder), Free(true) {} + + void SetMapId(uint32 mapId) { _mapId = mapId; } int svc() { + Free = false; if (_builder) _builder->buildMap(_mapId); + Free = true; return 0; } + + bool Free; }; } -- cgit v1.2.3 From e0abbfd86c3ce23daa9bccbb9c181bfe08c2d0c4 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 21:55:03 -0500 Subject: Core/MMaps: Renamed PathFinderMovementGenerator to PathGenerator, since its not a MovementGenerator, and moved out of the MovementGenerators folder --- .../ConfusedMovementGenerator.cpp | 4 +- .../FleeingMovementGenerator.cpp | 4 +- .../PathFinderMovementGenerator.cpp | 808 --------------------- .../PathFinderMovementGenerator.h | 137 ---- .../TargetedMovementGenerator.cpp | 2 +- .../MovementGenerators/TargetedMovementGenerator.h | 4 +- src/server/game/Movement/PathGenerator.cpp | 808 +++++++++++++++++++++ src/server/game/Movement/PathGenerator.h | 137 ++++ src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 +- src/server/game/Movement/Spline/MoveSplineInit.h | 2 +- 10 files changed, 954 insertions(+), 954 deletions(-) delete mode 100644 src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp delete mode 100644 src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h create mode 100644 src/server/game/Movement/PathGenerator.cpp create mode 100644 src/server/game/Movement/PathGenerator.h (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index a4f57a43701..b9b69baf0f8 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -19,7 +19,7 @@ #include "Creature.h" #include "MapManager.h" #include "ConfusedMovementGenerator.h" -#include "PathFinderMovementGenerator.h" +#include "PathGenerator.h" #include "VMapFactory.h" #include "MoveSplineInit.h" #include "MoveSpline.h" @@ -76,7 +76,7 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) unit.UpdateAllowedPositionZ(x, y, z); - PathFinderMovementGenerator path(&unit); + PathGenerator path(&unit); path.setPathLengthLimit(30.0f); path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 4e96c641be7..ae1e89c8562 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -20,7 +20,7 @@ #include "CreatureAI.h" #include "MapManager.h" #include "FleeingMovementGenerator.h" -#include "PathFinderMovementGenerator.h" +#include "PathGenerator.h" #include "ObjectAccessor.h" #include "MoveSplineInit.h" #include "MoveSpline.h" @@ -43,7 +43,7 @@ void FleeingMovementGenerator::_setTargetLocation(T &owner) owner.AddUnitState(UNIT_STATE_FLEEING_MOVE); - PathFinderMovementGenerator path(&owner); + PathGenerator path(&owner); path.setPathLengthLimit(30.0f); path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp deleted file mode 100644 index adfd32c50b3..00000000000 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.cpp +++ /dev/null @@ -1,808 +0,0 @@ -/* - * Copyright (C) 2005-2011 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 "PathFinderMovementGenerator.h" -#include "Map.h" -#include "Creature.h" -#include "MMapFactory.h" -#include "MMapManager.h" -#include "Log.h" - -#include "DetourCommon.h" -#include "DetourNavMeshQuery.h" - -////////////////// PathFinderMovementGenerator ////////////////// -PathFinderMovementGenerator::PathFinderMovementGenerator(const Unit* owner) : - m_polyLength(0), m_type(PATHFIND_BLANK), - m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), - m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL) -{ - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::PathFinderMovementGenerator for %u \n", m_sourceUnit->GetGUIDLow()); - - uint32 mapId = m_sourceUnit->GetMapId(); - if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) - { - MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); - m_navMesh = mmap->GetNavMesh(mapId); - m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId()); - } - - createFilter(); -} - -PathFinderMovementGenerator::~PathFinderMovementGenerator() -{ - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::~PathFinderMovementGenerator() for %u \n", m_sourceUnit->GetGUIDLow()); -} - -bool PathFinderMovementGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) -{ - if (!Trinity::IsValidMapCoord(destX, destY, destZ) || - !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) - return false; - - Vector3 oldDest = getEndPosition(); - Vector3 dest(destX, destY, destZ); - setEndPosition(dest); - - float x, y, z; - m_sourceUnit->GetPosition(x, y, z); - Vector3 start(x, y, z); - setStartPosition(start); - - m_forceDestination = forceDest; - - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::CalculatePath() for %u \n", m_sourceUnit->GetGUIDLow()); - - // make sure navMesh works - we can run on map w/o mmap - // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) - if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || - !HaveTile(start) || !HaveTile(dest)) - { - BuildShortcut(); - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); - return true; - } - - updateFilter(); - - // check if destination moved - if not we can optimize something here - // we are following old, precalculated path? - float dist = m_sourceUnit->GetObjectSize(); - if (inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) - { - // our target is not moving - we just coming closer - // we are moving on precalculated path - enjoy the ride - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::CalculatePath:: precalculated path\n"); - - m_pathPoints.erase(m_pathPoints.begin()); - return false; - } - else - { - // target moved, so we need to update the poly path - BuildPolyPath(start, dest); - return true; - } -} - -dtPolyRef PathFinderMovementGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance) const -{ - if (!polyPath || !polyPathSize) - return INVALID_POLYREF; - - dtPolyRef nearestPoly = INVALID_POLYREF; - float minDist2d = FLT_MAX; - float minDist3d = 0.0f; - - for (uint32 i = 0; i < polyPathSize; ++i) - { - float closestPoint[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)) - continue; - - float d = dtVdist2DSqr(point, closestPoint); - if (d < minDist2d) - { - minDist2d = d; - nearestPoly = polyPath[i]; - minDist3d = dtVdistSqr(point, closestPoint); - } - - if(minDist2d < 1.0f) // shortcut out - close enough for us - break; - } - - if (distance) - *distance = dtSqrt(minDist3d); - - return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF; -} - -dtPolyRef PathFinderMovementGenerator::getPolyByLocation(const float* point, float *distance) const -{ - // first we check the current path - // if the current path doesn't contain the current poly, - // we need to use the expensive navMesh.findNearestPoly - dtPolyRef polyRef = getPathPolyByPosition(m_pathPolyRefs, m_polyLength, point, distance); - if (polyRef != INVALID_POLYREF) - return polyRef; - - // we don't have it in our old path - // try to get it by findNearestPoly() - // first try with low search box - float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area - float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f}; - dtStatus result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); - if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) - { - *distance = dtVdist(closestPoint, point); - return polyRef; - } - - // still nothing .. - // try with bigger search box - extents[1] = 200.0f; - result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); - if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) - { - *distance = dtVdist(closestPoint, point); - return polyRef; - } - - return INVALID_POLYREF; -} - -void PathFinderMovementGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos) -{ - // *** getting start/end poly logic *** - - float distToStartPoly, distToEndPoly; - float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x}; - float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x}; - - dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly); - dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly); - - // we have a hole in our mesh - // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) - // its up to caller how he will use this info - if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); - BuildShortcut(); - bool path = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->CanFly(); - - bool waterPath = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->canSwim(); - if (waterPath) - { - // Check both start and end points, if they're both in water, then we can *safely* let the creature move - for (int i = 0; i < m_pathPoints.size(); ++i) - { - LiquidData data; - m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); - // One of the points is not in the water, cancel movement. - if (data.type_flags == MAP_LIQUID_TYPE_NO_WATER) - { - waterPath = false; - break; - } - } - } - - m_type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; - return; - } - - // we may need a better number here - bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); - if (farFromPoly) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly); - - bool buildShotrcut = false; - if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) - { - Creature* owner = (Creature*)m_sourceUnit; - - Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos; - if (m_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n"); - if (owner->canSwim()) - buildShotrcut = true; - } - else - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n"); - if (owner->CanFly()) - buildShotrcut = true; - } - } - - if (buildShotrcut) - { - BuildShortcut(); - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); - return; - } - else - { - float closestPoint[VERTEX_SIZE]; - // we may want to use closestPointOnPolyBoundary instead - if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)) - { - dtVcopy(endPoint, closestPoint); - setActualEndPosition(Vector3(endPoint[2],endPoint[0],endPoint[1])); - } - - m_type = PATHFIND_INCOMPLETE; - } - } - - // *** poly path generating logic *** - - // start and end are on same polygon - // just need to move in straight line - if (startPoly == endPoly) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == endPoly)\n"); - - BuildShortcut(); - - m_pathPolyRefs[0] = startPoly; - m_polyLength = 1; - - m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", m_type); - return; - } - - // look for startPoly/endPoly in current path - // TODO: we can merge it with getPathPolyByPosition() loop - bool startPolyFound = false; - bool endPolyFound = false; - uint32 pathStartIndex, pathEndIndex; - - if (m_polyLength) - { - for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex) - { - // here to carch few bugs - ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); - - if (m_pathPolyRefs[pathStartIndex] == startPoly) - { - startPolyFound = true; - break; - } - } - - for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) - if (m_pathPolyRefs[pathEndIndex] == endPoly) - { - endPolyFound = true; - break; - } - } - - if (startPolyFound && endPolyFound) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n"); - - // we moved along the path and the target did not move out of our old poly-path - // our path is a simple subpath case, we have all the data we need - // just "cut" it out - - m_polyLength = pathEndIndex - pathStartIndex + 1; - memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef)); - } - else if (startPolyFound && !endPolyFound) - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n"); - - // we are moving on the old path but target moved out - // so we have atleast part of poly-path ready - - m_polyLength -= pathStartIndex; - - // try to adjust the suffix of the path instead of recalculating entire length - // at given interval the target cannot get too far from its last location - // thus we have less poly to cover - // sub-path of optimal path is optimal - - // take ~80% of the original length - // TODO : play with the values here - uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f); - memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef)); - - dtPolyRef suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; - - // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data - float suffixEndPoint[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) - { - // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that - // try to recover by using prev polyref - --prefixPolyLength; - suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) - { - // suffixStartPoly is still invalid, error state - BuildShortcut(); - m_type = PATHFIND_NOPATH; - return; - } - } - - // generate suffix - uint32 suffixPolyLength = 0; - dtStatus dtResult = m_navMeshQuery->findPath( - suffixStartPoly, // start polygon - endPoly, // end polygon - suffixEndPoint, // start position - endPoint, // end position - &m_filter, // polygon search filter - m_pathPolyRefs + prefixPolyLength - 1, // [out] path - (int*)&suffixPolyLength, - MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path - - if (!suffixPolyLength || dtResult != DT_SUCCESS) - { - // this is probably an error state, but we'll leave it - // and hopefully recover on the next Update - // we still need to copy our preffix - sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); - } - - sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); - - // new path = prefix + suffix - overlap - m_polyLength = prefixPolyLength + suffixPolyLength - 1; - } - else - { - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n"); - - // either we have no path at all -> first run - // or something went really wrong -> we aren't moving along the path to the target - // just generate new path - - // free and invalidate old path data - clear(); - - dtStatus dtResult = m_navMeshQuery->findPath( - startPoly, // start polygon - endPoly, // end polygon - startPoint, // start position - endPoint, // end position - &m_filter, // polygon search filter - m_pathPolyRefs, // [out] path - (int*)&m_polyLength, - MAX_PATH_LENGTH); // max number of polygons in output path - - if (!m_polyLength || dtResult != DT_SUCCESS) - { - // only happens if we passed bad data to findPath(), or navmesh is messed up - sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); - BuildShortcut(); - m_type = PATHFIND_NOPATH; - return; - } - } - - // by now we know what type of path we can get - if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE)) - m_type = PATHFIND_NORMAL; - else - m_type = PATHFIND_INCOMPLETE; - - // generate the point-path out of our up-to-date poly-path - BuildPointPath(startPoint, endPoint); -} - -void PathFinderMovementGenerator::BuildPointPath(const float *startPoint, const float *endPoint) -{ - float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE]; - uint32 pointCount = 0; - dtStatus dtResult = DT_FAILURE; - if (m_useStraightPath) - { - dtResult = m_navMeshQuery->findStraightPath( - startPoint, // start position - endPoint, // end position - m_pathPolyRefs, // current path - m_polyLength, // lenth of current path - pathPoints, // [out] path corner points - NULL, // [out] flags - NULL, // [out] shortened path - (int*)&pointCount, - m_pointPathLimit); // maximum number of points/polygons to use - } - else - { - dtResult = findSmoothPath( - startPoint, // start position - endPoint, // end position - m_pathPolyRefs, // current path - m_polyLength, // length of current path - pathPoints, // [out] path corner points - (int*)&pointCount, - m_pointPathLimit); // maximum number of points - } - - if (pointCount < 2 || dtResult != DT_SUCCESS) - { - // only happens if pass bad data to findStraightPath or navmesh is broken - // single point paths can be generated here - // TODO : check the exact cases - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount); - BuildShortcut(); - m_type = PATHFIND_NOPATH; - return; - } - - m_pathPoints.resize(pointCount); - for (uint32 i = 0; i < pointCount; ++i) - m_pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); - - NormalizePath(); - - // first point is always our current location - we need the next one - setActualEndPosition(m_pathPoints[pointCount-1]); - - // force the given destination, if needed - if(m_forceDestination && - (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f))) - { - // we may want to keep partial subpath - if(dist3DSqr(getActualEndPosition(), getEndPosition()) < - 0.3f * dist3DSqr(getStartPosition(), getEndPosition())) - { - setActualEndPosition(getEndPosition()); - m_pathPoints[m_pathPoints.size()-1] = getEndPosition(); - } - else - { - setActualEndPosition(getEndPosition()); - BuildShortcut(); - } - - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); - } - - sLog->outDebug(LOG_FILTER_MAPS, "++ PathFinderMovementGenerator::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength); -} - -void PathFinderMovementGenerator::NormalizePath() -{ - for (uint32 i = 0; i < m_pathPoints.size(); ++i) - m_sourceUnit->UpdateAllowedPositionZ(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z); -} - -void PathFinderMovementGenerator::BuildShortcut() -{ - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); - - clear(); - - // make two point path, our curr pos is the start, and dest is the end - m_pathPoints.resize(2); - - // set start and a default next position - m_pathPoints[0] = getStartPosition(); - m_pathPoints[1] = getActualEndPosition(); - - NormalizePath(); - - m_type = PATHFIND_SHORTCUT; -} - -void PathFinderMovementGenerator::createFilter() -{ - uint16 includeFlags = 0; - uint16 excludeFlags = 0; - - if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) - { - Creature* creature = (Creature*)m_sourceUnit; - if (creature->canWalk()) - includeFlags |= NAV_GROUND; // walk - - // creatures don't take environmental damage - if (creature->canSwim()) - includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim - } - else if (m_sourceUnit->GetTypeId() == TYPEID_PLAYER) - { - // perfect support not possible, just stay 'safe' - includeFlags |= (NAV_GROUND | NAV_WATER); - } - - m_filter.setIncludeFlags(includeFlags); - m_filter.setExcludeFlags(excludeFlags); - - updateFilter(); -} - -void PathFinderMovementGenerator::updateFilter() -{ - // allow creatures to cheat and use different movement types if they are moved - // forcefully into terrain they can't normally move in - if (m_sourceUnit->IsInWater() || m_sourceUnit->IsUnderWater()) - { - uint16 includedFlags = m_filter.getIncludeFlags(); - includedFlags |= getNavTerrain(m_sourceUnit->GetPositionX(), - m_sourceUnit->GetPositionY(), - m_sourceUnit->GetPositionZ()); - - m_filter.setIncludeFlags(includedFlags); - } -} - -NavTerrain PathFinderMovementGenerator::getNavTerrain(float x, float y, float z) -{ - LiquidData data; - m_sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); - - switch (data.type_flags) - { - case MAP_LIQUID_TYPE_WATER: - case MAP_LIQUID_TYPE_OCEAN: - return NAV_WATER; - case MAP_LIQUID_TYPE_MAGMA: - return NAV_MAGMA; - case MAP_LIQUID_TYPE_SLIME: - return NAV_SLIME; - default: - return NAV_GROUND; - } -} - -bool PathFinderMovementGenerator::HaveTile(const Vector3 &p) const -{ - int tx, ty; - float point[VERTEX_SIZE] = {p.y, p.z, p.x}; - - m_navMesh->calcTileLoc(point, &tx, &ty); - return (m_navMesh->getTileAt(tx, ty) != NULL); -} - -uint32 PathFinderMovementGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, - const dtPolyRef* visited, uint32 nvisited) -{ - int32 furthestPath = -1; - int32 furthestVisited = -1; - - // Find furthest common polygon. - for (int32 i = npath-1; i >= 0; --i) - { - bool found = false; - for (int32 j = nvisited-1; j >= 0; --j) - { - if (path[i] == visited[j]) - { - furthestPath = i; - furthestVisited = j; - found = true; - } - } - if (found) - break; - } - - // If no intersection found just return current path. - if (furthestPath == -1 || furthestVisited == -1) - return npath; - - // Concatenate paths. - - // Adjust beginning of the buffer to include the visited. - uint32 req = nvisited - furthestVisited; - uint32 orig = uint32(furthestPath+1) < npath ? furthestPath+1 : npath; - uint32 size = npath-orig > 0 ? npath-orig : 0; - if (req+size > maxPath) - size = maxPath-req; - - if (size) - memmove(path+req, path+orig, size*sizeof(dtPolyRef)); - - // Store visited - for (uint32 i = 0; i < req; ++i) - path[i] = visited[(nvisited-1)-i]; - - return req+size; -} - -bool PathFinderMovementGenerator::getSteerTarget(const float* startPos, const float* endPos, - float minTargetDist, const dtPolyRef* path, uint32 pathSize, - float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef) -{ - // Find steer target. - static const uint32 MAX_STEER_POINTS = 3; - float steerPath[MAX_STEER_POINTS*VERTEX_SIZE]; - unsigned char steerPathFlags[MAX_STEER_POINTS]; - dtPolyRef steerPathPolys[MAX_STEER_POINTS]; - uint32 nsteerPath = 0; - dtStatus dtResult = m_navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, - steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS); - if (!nsteerPath || DT_SUCCESS != dtResult) - return false; - - // Find vertex far enough to steer to. - uint32 ns = 0; - while (ns < nsteerPath) - { - // Stop at Off-Mesh link or when point is further than slop away. - if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || - !inRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) - break; - ns++; - } - // Failed to find good point to steer to. - if (ns >= nsteerPath) - return false; - - dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]); - steerPos[1] = startPos[1]; // keep Z value - steerPosFlag = steerPathFlags[ns]; - steerPosRef = steerPathPolys[ns]; - - return true; -} - -dtStatus PathFinderMovementGenerator::findSmoothPath(const float* startPos, const float* endPos, - const dtPolyRef* polyPath, uint32 polyPathSize, - float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize) -{ - *smoothPathSize = 0; - uint32 nsmoothPath = 0; - - dtPolyRef polys[MAX_PATH_LENGTH]; - memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize); - uint32 npolys = polyPathSize; - - float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)) - return DT_FAILURE; - - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)) - return DT_FAILURE; - - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - - // Move towards target a small advancement at a time until target reached or - // when ran out of memory to store the path. - while (npolys && nsmoothPath < maxSmoothPathSize) - { - // Find location to steer towards. - float steerPos[VERTEX_SIZE]; - unsigned char steerPosFlag; - dtPolyRef steerPosRef = INVALID_POLYREF; - - if (!getSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) - break; - - bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END); - bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION); - - // Find movement delta. - float delta[VERTEX_SIZE]; - dtVsub(delta, steerPos, iterPos); - float len = dtSqrt(dtVdot(delta,delta)); - // If the steer target is end of path or off-mesh link, do not move past the location. - if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE) - len = 1.0f; - else - len = SMOOTH_PATH_STEP_SIZE / len; - - float moveTgt[VERTEX_SIZE]; - dtVmad(moveTgt, iterPos, delta, len); - - // Move - float result[VERTEX_SIZE]; - const static uint32 MAX_VISIT_POLY = 16; - dtPolyRef visited[MAX_VISIT_POLY]; - - uint32 nvisited = 0; - m_navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); - npolys = fixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); - - m_navMeshQuery->getPolyHeight(polys[0], result, &result[1]); - result[1] += 0.5f; - dtVcopy(iterPos, result); - - // Handle end of path and off-mesh links when close enough. - if (endOfPath && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) - { - // Reached end of path. - dtVcopy(iterPos, targetPos); - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - } - break; - } - else if (offMeshConnection && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) - { - // Advance the path up to and over the off-mesh connection. - dtPolyRef prevRef = INVALID_POLYREF; - dtPolyRef polyRef = polys[0]; - uint32 npos = 0; - while (npos < npolys && polyRef != steerPosRef) - { - prevRef = polyRef; - polyRef = polys[npos]; - npos++; - } - - for (uint32 i = npos; i < npolys; ++i) - polys[i-npos] = polys[i]; - - npolys -= npos; - - // Handle the connection. - float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; - if (DT_SUCCESS == m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) - { - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos); - nsmoothPath++; - } - // Move position at the other side of the off-mesh link. - dtVcopy(iterPos, endPos); - m_navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); - iterPos[1] += 0.5f; - } - } - - // Store results. - if (nsmoothPath < maxSmoothPathSize) - { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); - nsmoothPath++; - } - } - - *smoothPathSize = nsmoothPath; - - // this is most likely a loop - return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; -} - -bool PathFinderMovementGenerator::inRangeYZX(const float* v1, const float* v2, float r, float h) const -{ - const float dx = v2[0] - v1[0]; - const float dy = v2[1] - v1[1]; // elevation - const float dz = v2[2] - v1[2]; - return (dx*dx + dz*dz) < r*r && fabsf(dy) < h; -} - -bool PathFinderMovementGenerator::inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const -{ - Vector3 d = p1-p2; - return (d.x*d.x + d.y*d.y) < r*r && fabsf(d.z) < h; -} - -float PathFinderMovementGenerator::dist3DSqr(const Vector3 &p1, const Vector3 &p2) const -{ - return (p1-p2).squaredLength(); -} diff --git a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h deleted file mode 100644 index 9029fc1804e..00000000000 --- a/src/server/game/Movement/MovementGenerators/PathFinderMovementGenerator.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2005-2011 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 _PATH_INFO_H -#define _PATH_INFO_H - -#include "SharedDefines.h" -#include "DetourNavMesh.h" -#include "DetourNavMeshQuery.h" -#include "MoveSplineInitArgs.h" - -using Movement::Vector3; -using Movement::PointsArray; - -class Unit; - -// 74*4.0f=296y number_of_points*interval = max_path_len -// this is way more than actual evade range -// I think we can safely cut those down even more -#define MAX_PATH_LENGTH 74 -#define MAX_POINT_PATH_LENGTH 74 - -#define SMOOTH_PATH_STEP_SIZE 4.0f -#define SMOOTH_PATH_SLOP 0.3f - -#define VERTEX_SIZE 3 -#define INVALID_POLYREF 0 - -enum PathType -{ - PATHFIND_BLANK = 0x0000, // path not built yet - PATHFIND_NORMAL = 0x0001, // normal path - PATHFIND_SHORTCUT = 0x0002, // travel through obstacles, terrain, air, etc (old behavior) - PATHFIND_INCOMPLETE = 0x0004, // we have partial path to follow - getting closer to target - PATHFIND_NOPATH = 0x0008, // no valid path at all or error in generating one - PATHFIND_NOT_USING_PATH = 0x0010 // used when we are either flying/swiming or on map w/o mmaps -}; - -class PathFinderMovementGenerator -{ - public: - PathFinderMovementGenerator(Unit const* owner); - ~PathFinderMovementGenerator(); - - // Calculate the path from owner to given destination - // return: true if new path was calculated, false otherwise (no change needed) - bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); - - // option setters - use optional - void SetUseStraightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; - void setPathLengthLimit(float distance) { m_pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; - - // result getters - Vector3 getStartPosition() const { return m_startPosition; } - Vector3 getEndPosition() const { return m_endPosition; } - Vector3 getActualEndPosition() const { return m_actualEndPosition; } - - PointsArray& getPath() { return m_pathPoints; } - PathType getPathType() const { return m_type; } - - private: - - dtPolyRef m_pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references - uint32 m_polyLength; // number of polygons in the path - - PointsArray m_pathPoints; // our actual (x,y,z) path to the target - PathType m_type; // tells what kind of path this is - - bool m_useStraightPath; // type of path will be generated - bool m_forceDestination; // when set, we will always arrive at given point - uint32 m_pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) - - Vector3 m_startPosition; // {x, y, z} of current location - Vector3 m_endPosition; // {x, y, z} of the destination - Vector3 m_actualEndPosition;// {x, y, z} of the closest possible point to given destination - - const Unit* const m_sourceUnit; // the unit that is moving - const dtNavMesh* m_navMesh; // the nav mesh - const dtNavMeshQuery* m_navMeshQuery; // the nav mesh query used to find the path - - dtQueryFilter m_filter; // use single filter for all movements, update it when needed - - void setStartPosition(Vector3 point) { m_startPosition = point; } - void setEndPosition(Vector3 point) { m_actualEndPosition = point; m_endPosition = point; } - void setActualEndPosition(Vector3 point) { m_actualEndPosition = point; } - - void NormalizePath(); - - void clear() - { - m_polyLength = 0; - m_pathPoints.clear(); - } - - bool inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const; - float dist3DSqr(const Vector3 &p1, const Vector3 &p2) const; - bool inRangeYZX(const float* v1, const float* v2, float r, float h) const; - - dtPolyRef getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance = NULL) const; - dtPolyRef getPolyByLocation(const float* point, float *distance) const; - bool HaveTile(const Vector3 &p) const; - - void BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos); - void BuildPointPath(const float *startPoint, const float *endPoint); - void BuildShortcut(); - - NavTerrain getNavTerrain(float x, float y, float z); - void createFilter(); - void updateFilter(); - - // smooth path aux functions - uint32 fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, - const dtPolyRef* visited, uint32 nvisited); - bool getSteerTarget(const float* startPos, const float* endPos, float minTargetDist, - const dtPolyRef* path, uint32 pathSize, float* steerPos, - unsigned char& steerPosFlag, dtPolyRef& steerPosRef); - dtStatus findSmoothPath(const float* startPos, const float* endPos, - const dtPolyRef* polyPath, uint32 polyPathSize, - float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize); -}; - -#endif diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 1b14cd385e8..6d322a56a80 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -64,7 +64,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) } if (!i_path) - i_path = new PathFinderMovementGenerator(&owner); + i_path = new PathGenerator(&owner); // allow pets following their master to cheat while generating paths bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet() diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index d855dfa1875..db5e05c7b23 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -23,7 +23,7 @@ #include "FollowerReference.h" #include "Timer.h" #include "Unit.h" -#include "PathFinderMovementGenerator.h" +#include "PathGenerator.h" class TargetedMovementGeneratorBase { @@ -61,7 +61,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, float i_angle; bool i_recalculateTravel : 1; bool i_targetReached : 1; - PathFinderMovementGenerator* i_path; + PathGenerator* i_path; }; template diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp new file mode 100644 index 00000000000..4d7707020e1 --- /dev/null +++ b/src/server/game/Movement/PathGenerator.cpp @@ -0,0 +1,808 @@ +/* + * Copyright (C) 2005-2011 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 "PathGenerator.h" +#include "Map.h" +#include "Creature.h" +#include "MMapFactory.h" +#include "MMapManager.h" +#include "Log.h" + +#include "DetourCommon.h" +#include "DetourNavMeshQuery.h" + +////////////////// PathGenerator ////////////////// +PathGenerator::PathGenerator(const Unit* owner) : + m_polyLength(0), m_type(PATHFIND_BLANK), + m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), + m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL) +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", m_sourceUnit->GetGUIDLow()); + + uint32 mapId = m_sourceUnit->GetMapId(); + if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) + { + MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); + m_navMesh = mmap->GetNavMesh(mapId); + m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId()); + } + + createFilter(); +} + +PathGenerator::~PathGenerator() +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::~PathGenerator() for %u \n", m_sourceUnit->GetGUIDLow()); +} + +bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) +{ + if (!Trinity::IsValidMapCoord(destX, destY, destZ) || + !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) + return false; + + Vector3 oldDest = getEndPosition(); + Vector3 dest(destX, destY, destZ); + setEndPosition(dest); + + float x, y, z; + m_sourceUnit->GetPosition(x, y, z); + Vector3 start(x, y, z); + setStartPosition(start); + + m_forceDestination = forceDest; + + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath() for %u \n", m_sourceUnit->GetGUIDLow()); + + // make sure navMesh works - we can run on map w/o mmap + // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) + if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || + !HaveTile(start) || !HaveTile(dest)) + { + BuildShortcut(); + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + return true; + } + + updateFilter(); + + // check if destination moved - if not we can optimize something here + // we are following old, precalculated path? + float dist = m_sourceUnit->GetObjectSize(); + if (inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) + { + // our target is not moving - we just coming closer + // we are moving on precalculated path - enjoy the ride + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath:: precalculated path\n"); + + m_pathPoints.erase(m_pathPoints.begin()); + return false; + } + else + { + // target moved, so we need to update the poly path + BuildPolyPath(start, dest); + return true; + } +} + +dtPolyRef PathGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance) const +{ + if (!polyPath || !polyPathSize) + return INVALID_POLYREF; + + dtPolyRef nearestPoly = INVALID_POLYREF; + float minDist2d = FLT_MAX; + float minDist3d = 0.0f; + + for (uint32 i = 0; i < polyPathSize; ++i) + { + float closestPoint[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)) + continue; + + float d = dtVdist2DSqr(point, closestPoint); + if (d < minDist2d) + { + minDist2d = d; + nearestPoly = polyPath[i]; + minDist3d = dtVdistSqr(point, closestPoint); + } + + if(minDist2d < 1.0f) // shortcut out - close enough for us + break; + } + + if (distance) + *distance = dtSqrt(minDist3d); + + return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF; +} + +dtPolyRef PathGenerator::getPolyByLocation(const float* point, float *distance) const +{ + // first we check the current path + // if the current path doesn't contain the current poly, + // we need to use the expensive navMesh.findNearestPoly + dtPolyRef polyRef = getPathPolyByPosition(m_pathPolyRefs, m_polyLength, point, distance); + if (polyRef != INVALID_POLYREF) + return polyRef; + + // we don't have it in our old path + // try to get it by findNearestPoly() + // first try with low search box + float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area + float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f}; + dtStatus result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) + { + *distance = dtVdist(closestPoint, point); + return polyRef; + } + + // still nothing .. + // try with bigger search box + extents[1] = 200.0f; + result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) + { + *distance = dtVdist(closestPoint, point); + return polyRef; + } + + return INVALID_POLYREF; +} + +void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos) +{ + // *** getting start/end poly logic *** + + float distToStartPoly, distToEndPoly; + float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x}; + float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x}; + + dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly); + dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly); + + // we have a hole in our mesh + // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) + // its up to caller how he will use this info + if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); + BuildShortcut(); + bool path = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->CanFly(); + + bool waterPath = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->canSwim(); + if (waterPath) + { + // Check both start and end points, if they're both in water, then we can *safely* let the creature move + for (int i = 0; i < m_pathPoints.size(); ++i) + { + LiquidData data; + m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); + // One of the points is not in the water, cancel movement. + if (data.type_flags == MAP_LIQUID_TYPE_NO_WATER) + { + waterPath = false; + break; + } + } + } + + m_type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; + return; + } + + // we may need a better number here + bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); + if (farFromPoly) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly); + + bool buildShotrcut = false; + if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + { + Creature* owner = (Creature*)m_sourceUnit; + + Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos; + if (m_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n"); + if (owner->canSwim()) + buildShotrcut = true; + } + else + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n"); + if (owner->CanFly()) + buildShotrcut = true; + } + } + + if (buildShotrcut) + { + BuildShortcut(); + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + return; + } + else + { + float closestPoint[VERTEX_SIZE]; + // we may want to use closestPointOnPolyBoundary instead + if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)) + { + dtVcopy(endPoint, closestPoint); + setActualEndPosition(Vector3(endPoint[2],endPoint[0],endPoint[1])); + } + + m_type = PATHFIND_INCOMPLETE; + } + } + + // *** poly path generating logic *** + + // start and end are on same polygon + // just need to move in straight line + if (startPoly == endPoly) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == endPoly)\n"); + + BuildShortcut(); + + m_pathPolyRefs[0] = startPoly; + m_polyLength = 1; + + m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", m_type); + return; + } + + // look for startPoly/endPoly in current path + // TODO: we can merge it with getPathPolyByPosition() loop + bool startPolyFound = false; + bool endPolyFound = false; + uint32 pathStartIndex, pathEndIndex; + + if (m_polyLength) + { + for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex) + { + // here to carch few bugs + ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); + + if (m_pathPolyRefs[pathStartIndex] == startPoly) + { + startPolyFound = true; + break; + } + } + + for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) + if (m_pathPolyRefs[pathEndIndex] == endPoly) + { + endPolyFound = true; + break; + } + } + + if (startPolyFound && endPolyFound) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n"); + + // we moved along the path and the target did not move out of our old poly-path + // our path is a simple subpath case, we have all the data we need + // just "cut" it out + + m_polyLength = pathEndIndex - pathStartIndex + 1; + memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef)); + } + else if (startPolyFound && !endPolyFound) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n"); + + // we are moving on the old path but target moved out + // so we have atleast part of poly-path ready + + m_polyLength -= pathStartIndex; + + // try to adjust the suffix of the path instead of recalculating entire length + // at given interval the target cannot get too far from its last location + // thus we have less poly to cover + // sub-path of optimal path is optimal + + // take ~80% of the original length + // TODO : play with the values here + uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f); + memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef)); + + dtPolyRef suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; + + // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data + float suffixEndPoint[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + { + // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that + // try to recover by using prev polyref + --prefixPolyLength; + suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + { + // suffixStartPoly is still invalid, error state + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + } + + // generate suffix + uint32 suffixPolyLength = 0; + dtStatus dtResult = m_navMeshQuery->findPath( + suffixStartPoly, // start polygon + endPoly, // end polygon + suffixEndPoint, // start position + endPoint, // end position + &m_filter, // polygon search filter + m_pathPolyRefs + prefixPolyLength - 1, // [out] path + (int*)&suffixPolyLength, + MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path + + if (!suffixPolyLength || dtResult != DT_SUCCESS) + { + // this is probably an error state, but we'll leave it + // and hopefully recover on the next Update + // we still need to copy our preffix + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + } + + sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); + + // new path = prefix + suffix - overlap + m_polyLength = prefixPolyLength + suffixPolyLength - 1; + } + else + { + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n"); + + // either we have no path at all -> first run + // or something went really wrong -> we aren't moving along the path to the target + // just generate new path + + // free and invalidate old path data + clear(); + + dtStatus dtResult = m_navMeshQuery->findPath( + startPoly, // start polygon + endPoly, // end polygon + startPoint, // start position + endPoint, // end position + &m_filter, // polygon search filter + m_pathPolyRefs, // [out] path + (int*)&m_polyLength, + MAX_PATH_LENGTH); // max number of polygons in output path + + if (!m_polyLength || dtResult != DT_SUCCESS) + { + // only happens if we passed bad data to findPath(), or navmesh is messed up + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + } + + // by now we know what type of path we can get + if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE)) + m_type = PATHFIND_NORMAL; + else + m_type = PATHFIND_INCOMPLETE; + + // generate the point-path out of our up-to-date poly-path + BuildPointPath(startPoint, endPoint); +} + +void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoint) +{ + float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE]; + uint32 pointCount = 0; + dtStatus dtResult = DT_FAILURE; + if (m_useStraightPath) + { + dtResult = m_navMeshQuery->findStraightPath( + startPoint, // start position + endPoint, // end position + m_pathPolyRefs, // current path + m_polyLength, // lenth of current path + pathPoints, // [out] path corner points + NULL, // [out] flags + NULL, // [out] shortened path + (int*)&pointCount, + m_pointPathLimit); // maximum number of points/polygons to use + } + else + { + dtResult = findSmoothPath( + startPoint, // start position + endPoint, // end position + m_pathPolyRefs, // current path + m_polyLength, // length of current path + pathPoints, // [out] path corner points + (int*)&pointCount, + m_pointPathLimit); // maximum number of points + } + + if (pointCount < 2 || dtResult != DT_SUCCESS) + { + // only happens if pass bad data to findStraightPath or navmesh is broken + // single point paths can be generated here + // TODO : check the exact cases + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount); + BuildShortcut(); + m_type = PATHFIND_NOPATH; + return; + } + + m_pathPoints.resize(pointCount); + for (uint32 i = 0; i < pointCount; ++i) + m_pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); + + NormalizePath(); + + // first point is always our current location - we need the next one + setActualEndPosition(m_pathPoints[pointCount-1]); + + // force the given destination, if needed + if(m_forceDestination && + (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f))) + { + // we may want to keep partial subpath + if(dist3DSqr(getActualEndPosition(), getEndPosition()) < + 0.3f * dist3DSqr(getStartPosition(), getEndPosition())) + { + setActualEndPosition(getEndPosition()); + m_pathPoints[m_pathPoints.size()-1] = getEndPosition(); + } + else + { + setActualEndPosition(getEndPosition()); + BuildShortcut(); + } + + m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + } + + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength); +} + +void PathGenerator::NormalizePath() +{ + for (uint32 i = 0; i < m_pathPoints.size(); ++i) + m_sourceUnit->UpdateAllowedPositionZ(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z); +} + +void PathGenerator::BuildShortcut() +{ + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); + + clear(); + + // make two point path, our curr pos is the start, and dest is the end + m_pathPoints.resize(2); + + // set start and a default next position + m_pathPoints[0] = getStartPosition(); + m_pathPoints[1] = getActualEndPosition(); + + NormalizePath(); + + m_type = PATHFIND_SHORTCUT; +} + +void PathGenerator::createFilter() +{ + uint16 includeFlags = 0; + uint16 excludeFlags = 0; + + if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + { + Creature* creature = (Creature*)m_sourceUnit; + if (creature->canWalk()) + includeFlags |= NAV_GROUND; // walk + + // creatures don't take environmental damage + if (creature->canSwim()) + includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim + } + else if (m_sourceUnit->GetTypeId() == TYPEID_PLAYER) + { + // perfect support not possible, just stay 'safe' + includeFlags |= (NAV_GROUND | NAV_WATER); + } + + m_filter.setIncludeFlags(includeFlags); + m_filter.setExcludeFlags(excludeFlags); + + updateFilter(); +} + +void PathGenerator::updateFilter() +{ + // allow creatures to cheat and use different movement types if they are moved + // forcefully into terrain they can't normally move in + if (m_sourceUnit->IsInWater() || m_sourceUnit->IsUnderWater()) + { + uint16 includedFlags = m_filter.getIncludeFlags(); + includedFlags |= getNavTerrain(m_sourceUnit->GetPositionX(), + m_sourceUnit->GetPositionY(), + m_sourceUnit->GetPositionZ()); + + m_filter.setIncludeFlags(includedFlags); + } +} + +NavTerrain PathGenerator::getNavTerrain(float x, float y, float z) +{ + LiquidData data; + m_sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); + + switch (data.type_flags) + { + case MAP_LIQUID_TYPE_WATER: + case MAP_LIQUID_TYPE_OCEAN: + return NAV_WATER; + case MAP_LIQUID_TYPE_MAGMA: + return NAV_MAGMA; + case MAP_LIQUID_TYPE_SLIME: + return NAV_SLIME; + default: + return NAV_GROUND; + } +} + +bool PathGenerator::HaveTile(const Vector3 &p) const +{ + int tx, ty; + float point[VERTEX_SIZE] = {p.y, p.z, p.x}; + + m_navMesh->calcTileLoc(point, &tx, &ty); + return (m_navMesh->getTileAt(tx, ty) != NULL); +} + +uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, + const dtPolyRef* visited, uint32 nvisited) +{ + int32 furthestPath = -1; + int32 furthestVisited = -1; + + // Find furthest common polygon. + for (int32 i = npath-1; i >= 0; --i) + { + bool found = false; + for (int32 j = nvisited-1; j >= 0; --j) + { + if (path[i] == visited[j]) + { + furthestPath = i; + furthestVisited = j; + found = true; + } + } + if (found) + break; + } + + // If no intersection found just return current path. + if (furthestPath == -1 || furthestVisited == -1) + return npath; + + // Concatenate paths. + + // Adjust beginning of the buffer to include the visited. + uint32 req = nvisited - furthestVisited; + uint32 orig = uint32(furthestPath+1) < npath ? furthestPath+1 : npath; + uint32 size = npath-orig > 0 ? npath-orig : 0; + if (req+size > maxPath) + size = maxPath-req; + + if (size) + memmove(path+req, path+orig, size*sizeof(dtPolyRef)); + + // Store visited + for (uint32 i = 0; i < req; ++i) + path[i] = visited[(nvisited-1)-i]; + + return req+size; +} + +bool PathGenerator::getSteerTarget(const float* startPos, const float* endPos, + float minTargetDist, const dtPolyRef* path, uint32 pathSize, + float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef) +{ + // Find steer target. + static const uint32 MAX_STEER_POINTS = 3; + float steerPath[MAX_STEER_POINTS*VERTEX_SIZE]; + unsigned char steerPathFlags[MAX_STEER_POINTS]; + dtPolyRef steerPathPolys[MAX_STEER_POINTS]; + uint32 nsteerPath = 0; + dtStatus dtResult = m_navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, + steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS); + if (!nsteerPath || DT_SUCCESS != dtResult) + return false; + + // Find vertex far enough to steer to. + uint32 ns = 0; + while (ns < nsteerPath) + { + // Stop at Off-Mesh link or when point is further than slop away. + if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || + !inRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) + break; + ns++; + } + // Failed to find good point to steer to. + if (ns >= nsteerPath) + return false; + + dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]); + steerPos[1] = startPos[1]; // keep Z value + steerPosFlag = steerPathFlags[ns]; + steerPosRef = steerPathPolys[ns]; + + return true; +} + +dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPos, + const dtPolyRef* polyPath, uint32 polyPathSize, + float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize) +{ + *smoothPathSize = 0; + uint32 nsmoothPath = 0; + + dtPolyRef polys[MAX_PATH_LENGTH]; + memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize); + uint32 npolys = polyPathSize; + + float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)) + return DT_FAILURE; + + if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)) + return DT_FAILURE; + + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + + // Move towards target a small advancement at a time until target reached or + // when ran out of memory to store the path. + while (npolys && nsmoothPath < maxSmoothPathSize) + { + // Find location to steer towards. + float steerPos[VERTEX_SIZE]; + unsigned char steerPosFlag; + dtPolyRef steerPosRef = INVALID_POLYREF; + + if (!getSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) + break; + + bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END); + bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION); + + // Find movement delta. + float delta[VERTEX_SIZE]; + dtVsub(delta, steerPos, iterPos); + float len = dtSqrt(dtVdot(delta,delta)); + // If the steer target is end of path or off-mesh link, do not move past the location. + if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE) + len = 1.0f; + else + len = SMOOTH_PATH_STEP_SIZE / len; + + float moveTgt[VERTEX_SIZE]; + dtVmad(moveTgt, iterPos, delta, len); + + // Move + float result[VERTEX_SIZE]; + const static uint32 MAX_VISIT_POLY = 16; + dtPolyRef visited[MAX_VISIT_POLY]; + + uint32 nvisited = 0; + m_navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); + npolys = fixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); + + m_navMeshQuery->getPolyHeight(polys[0], result, &result[1]); + result[1] += 0.5f; + dtVcopy(iterPos, result); + + // Handle end of path and off-mesh links when close enough. + if (endOfPath && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + { + // Reached end of path. + dtVcopy(iterPos, targetPos); + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + } + break; + } + else if (offMeshConnection && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + { + // Advance the path up to and over the off-mesh connection. + dtPolyRef prevRef = INVALID_POLYREF; + dtPolyRef polyRef = polys[0]; + uint32 npos = 0; + while (npos < npolys && polyRef != steerPosRef) + { + prevRef = polyRef; + polyRef = polys[npos]; + npos++; + } + + for (uint32 i = npos; i < npolys; ++i) + polys[i-npos] = polys[i]; + + npolys -= npos; + + // Handle the connection. + float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; + if (DT_SUCCESS == m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) + { + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos); + nsmoothPath++; + } + // Move position at the other side of the off-mesh link. + dtVcopy(iterPos, endPos); + m_navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); + iterPos[1] += 0.5f; + } + } + + // Store results. + if (nsmoothPath < maxSmoothPathSize) + { + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); + nsmoothPath++; + } + } + + *smoothPathSize = nsmoothPath; + + // this is most likely a loop + return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; +} + +bool PathGenerator::inRangeYZX(const float* v1, const float* v2, float r, float h) const +{ + const float dx = v2[0] - v1[0]; + const float dy = v2[1] - v1[1]; // elevation + const float dz = v2[2] - v1[2]; + return (dx*dx + dz*dz) < r*r && fabsf(dy) < h; +} + +bool PathGenerator::inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const +{ + Vector3 d = p1-p2; + return (d.x*d.x + d.y*d.y) < r*r && fabsf(d.z) < h; +} + +float PathGenerator::dist3DSqr(const Vector3 &p1, const Vector3 &p2) const +{ + return (p1-p2).squaredLength(); +} diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h new file mode 100644 index 00000000000..a0d925cb11f --- /dev/null +++ b/src/server/game/Movement/PathGenerator.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2011 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 _PATH_INFO_H +#define _PATH_INFO_H + +#include "SharedDefines.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" +#include "MoveSplineInitArgs.h" + +using Movement::Vector3; +using Movement::PointsArray; + +class Unit; + +// 74*4.0f=296y number_of_points*interval = max_path_len +// this is way more than actual evade range +// I think we can safely cut those down even more +#define MAX_PATH_LENGTH 74 +#define MAX_POINT_PATH_LENGTH 74 + +#define SMOOTH_PATH_STEP_SIZE 4.0f +#define SMOOTH_PATH_SLOP 0.3f + +#define VERTEX_SIZE 3 +#define INVALID_POLYREF 0 + +enum PathType +{ + PATHFIND_BLANK = 0x0000, // path not built yet + PATHFIND_NORMAL = 0x0001, // normal path + PATHFIND_SHORTCUT = 0x0002, // travel through obstacles, terrain, air, etc (old behavior) + PATHFIND_INCOMPLETE = 0x0004, // we have partial path to follow - getting closer to target + PATHFIND_NOPATH = 0x0008, // no valid path at all or error in generating one + PATHFIND_NOT_USING_PATH = 0x0010 // used when we are either flying/swiming or on map w/o mmaps +}; + +class PathGenerator +{ + public: + PathGenerator(Unit const* owner); + ~PathGenerator(); + + // Calculate the path from owner to given destination + // return: true if new path was calculated, false otherwise (no change needed) + bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); + + // option setters - use optional + void SetUseStraightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; + void setPathLengthLimit(float distance) { m_pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; + + // result getters + Vector3 getStartPosition() const { return m_startPosition; } + Vector3 getEndPosition() const { return m_endPosition; } + Vector3 getActualEndPosition() const { return m_actualEndPosition; } + + PointsArray& getPath() { return m_pathPoints; } + PathType getPathType() const { return m_type; } + + private: + + dtPolyRef m_pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references + uint32 m_polyLength; // number of polygons in the path + + PointsArray m_pathPoints; // our actual (x,y,z) path to the target + PathType m_type; // tells what kind of path this is + + bool m_useStraightPath; // type of path will be generated + bool m_forceDestination; // when set, we will always arrive at given point + uint32 m_pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) + + Vector3 m_startPosition; // {x, y, z} of current location + Vector3 m_endPosition; // {x, y, z} of the destination + Vector3 m_actualEndPosition;// {x, y, z} of the closest possible point to given destination + + const Unit* const m_sourceUnit; // the unit that is moving + const dtNavMesh* m_navMesh; // the nav mesh + const dtNavMeshQuery* m_navMeshQuery; // the nav mesh query used to find the path + + dtQueryFilter m_filter; // use single filter for all movements, update it when needed + + void setStartPosition(Vector3 point) { m_startPosition = point; } + void setEndPosition(Vector3 point) { m_actualEndPosition = point; m_endPosition = point; } + void setActualEndPosition(Vector3 point) { m_actualEndPosition = point; } + + void NormalizePath(); + + void clear() + { + m_polyLength = 0; + m_pathPoints.clear(); + } + + bool inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const; + float dist3DSqr(const Vector3 &p1, const Vector3 &p2) const; + bool inRangeYZX(const float* v1, const float* v2, float r, float h) const; + + dtPolyRef getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance = NULL) const; + dtPolyRef getPolyByLocation(const float* point, float *distance) const; + bool HaveTile(const Vector3 &p) const; + + void BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos); + void BuildPointPath(const float *startPoint, const float *endPoint); + void BuildShortcut(); + + NavTerrain getNavTerrain(float x, float y, float z); + void createFilter(); + void updateFilter(); + + // smooth path aux functions + uint32 fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, + const dtPolyRef* visited, uint32 nvisited); + bool getSteerTarget(const float* startPos, const float* endPos, float minTargetDist, + const dtPolyRef* path, uint32 pathSize, float* steerPos, + unsigned char& steerPosFlag, dtPolyRef& steerPosRef); + dtStatus findSmoothPath(const float* startPos, const float* endPos, + const dtPolyRef* polyPath, uint32 polyPathSize, + float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize); +}; + +#endif diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index fa2197f815e..c5e314a8636 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -152,7 +152,7 @@ namespace Movement { if (generatePath) { - PathFinderMovementGenerator path(&unit); + PathGenerator path(&unit); path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); MovebyPath(path.getPath()); } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 9130d2827e6..759fc73d7fd 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -20,7 +20,7 @@ #define TRINITYSERVER_MOVESPLINEINIT_H #include "MoveSplineInitArgs.h" -#include "PathFinderMovementGenerator.h" +#include "PathGenerator.h" class Unit; -- cgit v1.2.3 From 97c3e2e6c105e3dd563ba1064e86f5503d3f22f6 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Aug 2012 22:57:55 -0500 Subject: Core/Movement: Make MovementGenerators use pointers instead of references. cleanup --- src/server/game/Entities/Unit/Unit.cpp | 8 +- src/server/game/Entities/Vehicle/Vehicle.cpp | 2 +- src/server/game/Handlers/MovementHandler.cpp | 2 +- src/server/game/Movement/MotionMaster.cpp | 40 +++--- src/server/game/Movement/MovementGenerator.h | 37 ++--- .../ConfusedMovementGenerator.cpp | 60 ++++---- .../MovementGenerators/ConfusedMovementGenerator.h | 8 +- .../FleeingMovementGenerator.cpp | 108 +++++++-------- .../MovementGenerators/FleeingMovementGenerator.h | 16 +-- .../MovementGenerators/HomeMovementGenerator.cpp | 30 ++-- .../MovementGenerators/HomeMovementGenerator.h | 10 +- .../MovementGenerators/IdleMovementGenerator.cpp | 54 ++++---- .../MovementGenerators/IdleMovementGenerator.h | 26 ++-- .../MovementGenerators/PointMovementGenerator.cpp | 92 ++++++------- .../MovementGenerators/PointMovementGenerator.h | 22 +-- .../MovementGenerators/RandomMovementGenerator.cpp | 52 +++---- .../MovementGenerators/RandomMovementGenerator.h | 12 +- .../TargetedMovementGenerator.cpp | 152 ++++++++++----------- .../MovementGenerators/TargetedMovementGenerator.h | 52 +++---- .../WaypointMovementGenerator.cpp | 96 ++++++------- .../MovementGenerators/WaypointMovementGenerator.h | 32 ++--- src/server/game/Movement/Spline/MoveSplineInit.cpp | 48 +++---- src/server/game/Movement/Spline/MoveSplineInit.h | 10 +- .../Ulduar/Ulduar/boss_algalon_the_observer.cpp | 2 +- 24 files changed, 487 insertions(+), 484 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 183eddfcae4..b9396122bb1 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -372,7 +372,7 @@ bool Unit::haveOffhandWeapon() const void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath, bool forceDestination) { - Movement::MoveSplineInit init(*this); + Movement::MoveSplineInit init(this); init.MoveTo(x, y, z, generatePath, forceDestination); init.SetVelocity(speed); init.Launch(); @@ -14750,7 +14750,7 @@ void Unit::StopMoving() if (!IsInWorld()) return; - Movement::MoveSplineInit init(*this); + Movement::MoveSplineInit init(this); init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); init.SetFacing(GetOrientation()); init.Launch(); @@ -17152,7 +17152,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) SendMessageToSet(&data, false); } - Movement::MoveSplineInit init(*this); + Movement::MoveSplineInit init(this); init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); init.SetFacing(GetOrientation()); init.SetTransportExit(); @@ -17562,7 +17562,7 @@ void Unit::SetInFront(Unit const* target) void Unit::SetFacingTo(float ori) { - Movement::MoveSplineInit init(*this); + Movement::MoveSplineInit init(this); init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); init.SetFacing(ori); init.Launch(); diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 710821f2f24..61e3fd877b4 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -365,7 +365,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT - Movement::MoveSplineInit init(*unit); + Movement::MoveSplineInit init(unit); init.DisableTransportPathTransformations(); init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); init.SetFacing(0.0f); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 27b1f2eca3f..ca80921a7b2 100755 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -125,7 +125,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); - flight->Initialize(*GetPlayer()); + flight->Initialize(GetPlayer()); return; } diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 07d3760cf40..2ad8028ca4f 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -86,7 +86,7 @@ void MotionMaster::UpdateMotion(uint32 diff) ASSERT(!empty()); _cleanFlag |= MMCF_UPDATE; - if (!top()->Update(*_owner, diff)) + if (!top()->Update(_owner, diff)) { _cleanFlag &= ~MMCF_UPDATE; MovementExpired(); @@ -110,7 +110,7 @@ void MotionMaster::UpdateMotion(uint32 diff) else if (needInitTop()) InitTop(); else if (_cleanFlag & MMCF_RESET) - top()->Reset(*_owner); + top()->Reset(_owner); _cleanFlag &= ~MMCF_RESET; } @@ -131,7 +131,7 @@ void MotionMaster::DirectClean(bool reset) if (needInitTop()) InitTop(); else if (reset) - top()->Reset(*_owner); + top()->Reset(_owner); } void MotionMaster::DelayedClean() @@ -162,7 +162,7 @@ void MotionMaster::DirectExpire(bool reset) else if (needInitTop()) InitTop(); else if (reset) - top()->Reset(*_owner); + top()->Reset(_owner); } void MotionMaster::DelayedExpire() @@ -198,19 +198,19 @@ void MotionMaster::MoveTargetedHome() { Clear(false); - if (_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)_owner)->GetCharmerOrOwnerGUID()) + if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID()) { sLog->outDebug(LOG_FILTER_GENERAL, "Creature (Entry: %u GUID: %u) targeted home", _owner->GetEntry(), _owner->GetGUIDLow()); Mutate(new HomeMovementGenerator(), MOTION_SLOT_ACTIVE); } - else if (_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)_owner)->GetCharmerOrOwnerGUID()) + else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID()) { sLog->outDebug(LOG_FILTER_GENERAL, "Pet or controlled creature (Entry: %u GUID: %u) targeting home", _owner->GetEntry(), _owner->GetGUIDLow()); - Unit *target = ((Creature*)_owner)->GetCharmerOrOwner(); + Unit* target = _owner->ToCreature()->GetCharmerOrOwner(); if (target) { sLog->outDebug(LOG_FILTER_GENERAL, "Following %s (GUID: %u)", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow()); - Mutate(new FollowMovementGenerator(*target,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE); + Mutate(new FollowMovementGenerator(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE); } } else @@ -247,7 +247,7 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle) _owner->GetGUIDLow(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); - Mutate(new ChaseMovementGenerator(*target,dist,angle), MOTION_SLOT_ACTIVE); + Mutate(new ChaseMovementGenerator(target, dist, angle), MOTION_SLOT_ACTIVE); } else { @@ -255,7 +255,7 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle) _owner->GetEntry(), _owner->GetGUIDLow(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); - Mutate(new ChaseMovementGenerator(*target,dist,angle), MOTION_SLOT_ACTIVE); + Mutate(new ChaseMovementGenerator(target, dist, angle), MOTION_SLOT_ACTIVE); } } @@ -271,7 +271,7 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo sLog->outDebug(LOG_FILTER_GENERAL, "Player (GUID: %u) follow to %s (GUID: %u)", _owner->GetGUIDLow(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); - Mutate(new FollowMovementGenerator(*target,dist,angle), slot); + Mutate(new FollowMovementGenerator(target, dist, angle), slot); } else { @@ -279,7 +279,7 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo _owner->GetEntry(), _owner->GetGUIDLow(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); - Mutate(new FollowMovementGenerator(*target,dist,angle), slot); + Mutate(new FollowMovementGenerator(target, dist, angle), slot); } } @@ -305,7 +305,7 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos) sLog->outDebug(LOG_FILTER_GENERAL, "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z); - Movement::MoveSplineInit init(*_owner); + Movement::MoveSplineInit init(_owner); init.MoveTo(x,y,z); init.SetAnimation(Movement::ToGround); init.Launch(); @@ -319,7 +319,7 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos) sLog->outDebug(LOG_FILTER_GENERAL, "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z); - Movement::MoveSplineInit init(*_owner); + Movement::MoveSplineInit init(_owner); init.MoveTo(x,y,z); init.SetAnimation(Movement::ToFly); init.Launch(); @@ -339,7 +339,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + M_PI); - Movement::MoveSplineInit init(*_owner); + Movement::MoveSplineInit init(_owner); init.MoveTo(x,y,z); init.SetParabolic(max_height,0); init.SetOrientationFixed(true); @@ -369,7 +369,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee float moveTimeHalf = speedZ / Movement::gravity; float max_height = -Movement::computeFallElevation(moveTimeHalf,false,-speedZ); - Movement::MoveSplineInit init(*_owner); + Movement::MoveSplineInit init(_owner); init.MoveTo(x, y, z, false); init.SetParabolic(max_height,0); init.SetVelocity(speedXY); @@ -398,7 +398,7 @@ void MotionMaster::MoveFall(uint32 id/*=0*/) _owner->m_movementInfo.SetFallTime(0); } - Movement::MoveSplineInit init(*_owner); + Movement::MoveSplineInit init(_owner); init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz); init.SetFall(); init.Launch(); @@ -545,7 +545,7 @@ void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot) else { _needInit[slot] = false; - m->Initialize(*_owner); + m->Initialize(_owner); } } @@ -613,7 +613,7 @@ MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const void MotionMaster::InitTop() { - top()->Initialize(*_owner); + top()->Initialize(_owner); _needInit[_top] = false; } @@ -621,7 +621,7 @@ void MotionMaster::DirectDelete(_Ty curr) { if (isStatic(curr)) return; - curr->Finalize(*_owner); + curr->Finalize(_owner); delete curr; } diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 85e1fec0c2d..ee8dfb51cce 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -33,51 +33,54 @@ class MovementGenerator public: virtual ~MovementGenerator(); - virtual void Initialize(Unit &) = 0; - virtual void Finalize(Unit &) = 0; + virtual void Initialize(Unit*) = 0; + virtual void Finalize(Unit*) = 0; - virtual void Reset(Unit &) = 0; + virtual void Reset(Unit*) = 0; - virtual bool Update(Unit &, const uint32& time_diff) = 0; + virtual bool Update(Unit*, const uint32& time_diff) = 0; virtual MovementGeneratorType GetMovementGeneratorType() = 0; virtual void unitSpeedChanged() { } // used by Evade code for select point to evade with expected restart default movement - virtual bool GetResetPosition(Unit &, float& /*x*/, float& /*y*/, float& /*z*/) { return false; } + virtual bool GetResetPosition(Unit*, float& /*x*/, float& /*y*/, float& /*z*/) { return false; } }; template class MovementGeneratorMedium : public MovementGenerator { public: - void Initialize(Unit &u) + void Initialize(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Initialize(*((T*)&u)); + (static_cast(this))->Initialize(static_cast(u)); } - void Finalize(Unit &u) + + void Finalize(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Finalize(*((T*)&u)); + (static_cast(this))->Finalize(static_cast(u)); } - void Reset(Unit &u) + + void Reset(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Reset(*((T*)&u)); + (static_cast(this))->Reset(static_cast(u)); } - bool Update(Unit &u, const uint32& time_diff) + + bool Update(Unit* u, const uint32& time_diff) { //u->AssertIsType(); - return (static_cast(this))->Update(*((T*)&u), time_diff); + return (static_cast(this))->Update(static_cast(u), time_diff); } public: // will not link if not overridden in the generators - void Initialize(T &u); - void Finalize(T &u); - void Reset(T &u); - bool Update(T &u, const uint32& time_diff); + void Initialize(T* u); + void Finalize(T* u); + void Reset(T* u); + bool Update(T* u, const uint32& time_diff); }; struct SelectableMovement : public FactoryHolder diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index b9b69baf0f8..f1d1d8cf04a 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -31,34 +31,34 @@ #endif template -void ConfusedMovementGenerator::Initialize(T &unit) +void ConfusedMovementGenerator::Initialize(T* unit) { - unit.GetPosition(i_x, i_y, i_z); - unit.StopMoving(); - unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + unit->GetPosition(i_x, i_y, i_z); + unit->StopMoving(); + unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); + unit->AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } template -void ConfusedMovementGenerator::Reset(T &unit) +void ConfusedMovementGenerator::Reset(T* unit) { i_nextMoveTime.Reset(0); - unit.StopMoving(); - unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + unit->StopMoving(); + unit->AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } template -bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) +bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) { - if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) + if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location - unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); + unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); - if (unit.movespline->Finalized()) + if (unit->movespline->Finalized()) i_nextMoveTime.Reset(urand(800, 1500)); } else @@ -68,15 +68,15 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) if (i_nextMoveTime.Passed()) { // start moving - unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); + unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); float x = i_x + 10.0f*((float)rand_norm() - 0.5f); float y = i_y + 10.0f*((float)rand_norm() - 0.5f); float z = i_z; - unit.UpdateAllowedPositionZ(x, y, z); + unit->UpdateAllowedPositionZ(x, y, z); - PathGenerator path(&unit); + PathGenerator path(unit); path.setPathLengthLimit(30.0f); path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) @@ -96,26 +96,26 @@ bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) } template<> -void ConfusedMovementGenerator::Finalize(Player &unit) +void ConfusedMovementGenerator::Finalize(Player* unit) { - unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); - unit.StopMoving(); + unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); + unit->ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + unit->StopMoving(); } template<> -void ConfusedMovementGenerator::Finalize(Creature &unit) +void ConfusedMovementGenerator::Finalize(Creature* unit) { - unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); - if (unit.getVictim()) - unit.SetTarget(unit.getVictim()->GetGUID()); + unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); + unit->ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + if (unit->getVictim()) + unit->SetTarget(unit->getVictim()->GetGUID()); } -template void ConfusedMovementGenerator::Initialize(Player &player); -template void ConfusedMovementGenerator::Initialize(Creature &creature); -template void ConfusedMovementGenerator::Reset(Player &player); -template void ConfusedMovementGenerator::Reset(Creature &creature); -template bool ConfusedMovementGenerator::Update(Player &player, const uint32 &diff); -template bool ConfusedMovementGenerator::Update(Creature &creature, const uint32 &diff); +template void ConfusedMovementGenerator::Initialize(Player*); +template void ConfusedMovementGenerator::Initialize(Creature*); +template void ConfusedMovementGenerator::Reset(Player*); +template void ConfusedMovementGenerator::Reset(Creature*); +template bool ConfusedMovementGenerator::Update(Player*, const uint32&); +template bool ConfusedMovementGenerator::Update(Creature*, const uint32&); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index 72ffd7b734b..5b535e2d47d 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -28,10 +28,10 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov public: explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {} - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - bool Update(T &, const uint32 &); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + bool Update(T*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } private: diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index ae1e89c8562..e04f7b6fcbc 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -29,21 +29,21 @@ #define MAX_QUIET_DISTANCE 43.0f template -void FleeingMovementGenerator::_setTargetLocation(T &owner) +void FleeingMovementGenerator::_setTargetLocation(T* owner) { - if (!&owner) + if (!owner) return; - if (owner.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) return; float x, y, z; if (!_getPoint(owner, x, y, z)) return; - owner.AddUnitState(UNIT_STATE_FLEEING_MOVE); + owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); - PathGenerator path(&owner); + PathGenerator path(owner); path.setPathLengthLimit(30.0f); path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) @@ -60,17 +60,17 @@ void FleeingMovementGenerator::_setTargetLocation(T &owner) } template -bool FleeingMovementGenerator::_getPoint(T &owner, float &x, float &y, float &z) +bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float &z) { - if (!&owner) + if (!owner) return false; float dist_from_caster, angle_to_caster; - if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGUID)) + if (Unit* fright = ObjectAccessor::GetUnit(*owner, i_frightGUID)) { - dist_from_caster = fright->GetDistance(&owner); + dist_from_caster = fright->GetDistance(owner); if (dist_from_caster > 0.2f) - angle_to_caster = fright->GetAngle(&owner); + angle_to_caster = fright->GetAngle(owner); else angle_to_caster = frand(0, 2 * static_cast(M_PI)); } @@ -98,106 +98,106 @@ bool FleeingMovementGenerator::_getPoint(T &owner, float &x, float &y, float } float curr_x, curr_y, curr_z; - owner.GetPosition(curr_x, curr_y, curr_z); + owner->GetPosition(curr_x, curr_y, curr_z); x = curr_x + dist*cos(angle); y = curr_y + dist*sin(angle); z = curr_z; - owner.UpdateAllowedPositionZ(x, y, z); + owner->UpdateAllowedPositionZ(x, y, z); return true; } template -void FleeingMovementGenerator::Initialize(T &owner) +void FleeingMovementGenerator::Initialize(T* owner) { - if (!&owner) + if (!owner) return; - owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - owner.AddUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); + owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + owner->AddUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - if (owner.GetTypeId() == TYPEID_UNIT) + if (owner->GetTypeId() == TYPEID_UNIT) return; _setTargetLocation(owner); } template<> -void FleeingMovementGenerator::Finalize(Player &owner) +void FleeingMovementGenerator::Finalize(Player* owner) { - owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - owner.ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - owner.StopMoving(); + owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + owner->ClearUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE); + owner->StopMoving(); } template<> -void FleeingMovementGenerator::Finalize(Creature &owner) +void FleeingMovementGenerator::Finalize(Creature* owner) { - owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - owner.ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - if (owner.getVictim()) - owner.SetTarget(owner.getVictim()->GetGUID()); + owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + owner->ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); + if (owner->getVictim()) + owner->SetTarget(owner->getVictim()->GetGUID()); } template -void FleeingMovementGenerator::Reset(T &owner) +void FleeingMovementGenerator::Reset(T* owner) { Initialize(owner); } template -bool FleeingMovementGenerator::Update(T &owner, const uint32 &time_diff) +bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) { - if (!&owner || !owner.isAlive()) + if (!owner || !owner->isAlive()) return false; - if (owner.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { - owner.ClearUnitState(UNIT_STATE_FLEEING_MOVE); + owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE); return true; } i_nextCheckTime.Update(time_diff); - if (i_nextCheckTime.Passed() && owner.movespline->Finalized()) + if (i_nextCheckTime.Passed() && owner->movespline->Finalized()) _setTargetLocation(owner); return true; } -template void FleeingMovementGenerator::Initialize(Player &); -template void FleeingMovementGenerator::Initialize(Creature &); -template bool FleeingMovementGenerator::_getPoint(Player &, float &, float &, float &); -template bool FleeingMovementGenerator::_getPoint(Creature &, float &, float &, float &); -template void FleeingMovementGenerator::_setTargetLocation(Player &); -template void FleeingMovementGenerator::_setTargetLocation(Creature &); -template void FleeingMovementGenerator::Reset(Player &); -template void FleeingMovementGenerator::Reset(Creature &); -template bool FleeingMovementGenerator::Update(Player &, const uint32 &); -template bool FleeingMovementGenerator::Update(Creature &, const uint32 &); - -void TimedFleeingMovementGenerator::Finalize(Unit &owner) +template void FleeingMovementGenerator::Initialize(Player*); +template void FleeingMovementGenerator::Initialize(Creature*); +template bool FleeingMovementGenerator::_getPoint(Player*, float&, float&, float&); +template bool FleeingMovementGenerator::_getPoint(Creature*, float&, float&, float&); +template void FleeingMovementGenerator::_setTargetLocation(Player*); +template void FleeingMovementGenerator::_setTargetLocation(Creature*); +template void FleeingMovementGenerator::Reset(Player*); +template void FleeingMovementGenerator::Reset(Creature*); +template bool FleeingMovementGenerator::Update(Player*, const uint32&); +template bool FleeingMovementGenerator::Update(Creature*, const uint32&); + +void TimedFleeingMovementGenerator::Finalize(Unit* owner) { - owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - owner.ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - if (Unit* victim = owner.getVictim()) + owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); + owner->ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); + if (Unit* victim = owner->getVictim()) { - if (owner.isAlive()) + if (owner->isAlive()) { - owner.AttackStop(); - owner.ToCreature()->AI()->AttackStart(victim); + owner->AttackStop(); + owner->ToCreature()->AI()->AttackStart(victim); } } } -bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32& time_diff) +bool TimedFleeingMovementGenerator::Update(Unit* owner, const uint32& time_diff) { - if (!owner.isAlive()) + if (!owner->isAlive()) return false; - if (owner.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { - owner.ClearUnitState(UNIT_STATE_FLEEING_MOVE); + owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE); return true; } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index cb3bd1cb69a..88dedd31af6 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -27,16 +27,16 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem public: FleeingMovementGenerator(uint64 fright) : i_frightGUID(fright), i_nextCheckTime(0) {} - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - bool Update(T &, const uint32 &); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + bool Update(T*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; } private: - void _setTargetLocation(T &owner); - bool _getPoint(T &owner, float &x, float &y, float &z); + void _setTargetLocation(T*); + bool _getPoint(T*, float &x, float &y, float &z); uint64 i_frightGUID; TimeTracker i_nextCheckTime; @@ -50,8 +50,8 @@ class TimedFleeingMovementGenerator : public FleeingMovementGenerator i_totalFleeTime(time) {} MovementGeneratorType GetMovementGeneratorType() { return TIMED_FLEEING_MOTION_TYPE; } - bool Update(Unit &, const uint32&); - void Finalize(Unit &); + bool Update(Unit*, const uint32&); + void Finalize(Unit*); private: TimeTracker i_totalFleeTime; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index f122349a71c..78c1f80005c 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -23,49 +23,49 @@ #include "MoveSplineInit.h" #include "MoveSpline.h" -void HomeMovementGenerator::Initialize(Creature& owner) +void HomeMovementGenerator::Initialize(Creature* owner) { _setTargetLocation(owner); } -void HomeMovementGenerator::Finalize(Creature& owner) +void HomeMovementGenerator::Finalize(Creature* owner) { if (arrived) { - owner.ClearUnitState(UNIT_STATE_EVADE); - owner.SetWalk(true); - owner.LoadCreaturesAddon(true); - owner.AI()->JustReachedHome(); + owner->ClearUnitState(UNIT_STATE_EVADE); + owner->SetWalk(true); + owner->LoadCreaturesAddon(true); + owner->AI()->JustReachedHome(); } } -void HomeMovementGenerator::Reset(Creature &) +void HomeMovementGenerator::Reset(Creature*) { } -void HomeMovementGenerator::_setTargetLocation(Creature & owner) +void HomeMovementGenerator::_setTargetLocation(Creature* owner) { - if (owner.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return; Movement::MoveSplineInit init(owner); float x, y, z, o; // at apply we can select more nice return points base at current movegen - if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->top()->GetResetPosition(owner,x,y,z)) + if (owner->GetMotionMaster()->empty() || !owner->GetMotionMaster()->top()->GetResetPosition(owner, x, y, z)) { - owner.GetHomePosition(x, y, z, o); + owner->GetHomePosition(x, y, z, o); init.SetFacing(o); } - init.MoveTo(x,y,z); + init.MoveTo(x, y, z); init.SetWalk(false); init.Launch(); arrived = false; - owner.ClearUnitState(UNIT_STATE_ALL_STATE & ~UNIT_STATE_EVADE); + owner->ClearUnitState(UNIT_STATE_ALL_STATE & ~UNIT_STATE_EVADE); } -bool HomeMovementGenerator::Update(Creature &owner, const uint32 /*time_diff*/) +bool HomeMovementGenerator::Update(Creature* owner, const uint32 /*time_diff*/) { - arrived = owner.movespline->Finalized(); + arrived = owner->movespline->Finalized(); return !arrived; } diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index 95eb05f281c..dfbea60d353 100755 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -34,14 +34,14 @@ class HomeMovementGenerator : public MovementGeneratorMedium< Creature HomeMovementGenerator() : arrived(false) {} ~HomeMovementGenerator() {} - void Initialize(Creature &); - void Finalize(Creature &); - void Reset(Creature &); - bool Update(Creature &, const uint32); + void Initialize(Creature*); + void Finalize(Creature*); + void Reset(Creature*); + bool Update(Creature*, const uint32); MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; } private: - void _setTargetLocation(Creature &); + void _setTargetLocation(Creature*); bool arrived; }; #endif diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp index 5a2090cfe28..8ef9bd7697a 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp @@ -24,33 +24,33 @@ IdleMovementGenerator si_idleMovement; // StopMoving is needed to make unit stop if its last movement generator expires // But it should not be sent otherwise there are many redundent packets -void IdleMovementGenerator::Initialize(Unit &owner) +void IdleMovementGenerator::Initialize(Unit* owner) { Reset(owner); } -void IdleMovementGenerator::Reset(Unit& owner) +void IdleMovementGenerator::Reset(Unit* owner) { - if (!owner.IsStopped()) - owner.StopMoving(); + if (!owner->IsStopped()) + owner->StopMoving(); } -void RotateMovementGenerator::Initialize(Unit& owner) +void RotateMovementGenerator::Initialize(Unit* owner) { - if (!owner.IsStopped()) - owner.StopMoving(); + if (!owner->IsStopped()) + owner->StopMoving(); - if (owner.getVictim()) - owner.SetInFront(owner.getVictim()); + if (owner->getVictim()) + owner->SetInFront(owner->getVictim()); - owner.AddUnitState(UNIT_STATE_ROTATING); + owner->AddUnitState(UNIT_STATE_ROTATING); - owner.AttackStop(); + owner->AttackStop(); } -bool RotateMovementGenerator::Update(Unit& owner, const uint32& diff) +bool RotateMovementGenerator::Update(Unit* owner, const uint32& diff) { - float angle = owner.GetOrientation(); + float angle = owner->GetOrientation(); if (m_direction == ROTATE_DIRECTION_LEFT) { angle += (float)diff * static_cast(M_PI * 2) / m_maxDuration; @@ -61,8 +61,8 @@ bool RotateMovementGenerator::Update(Unit& owner, const uint32& diff) angle -= (float)diff * static_cast(M_PI * 2) / m_maxDuration; while (angle < 0) angle += static_cast(M_PI * 2); } - owner.SetOrientation(angle); - owner.SendMovementFlagUpdate(); // this is a hack. we do not have anything correct to send in the beginning + owner->SetOrientation(angle); + owner->SendMovementFlagUpdate(); // this is a hack. we do not have anything correct to send in the beginning if (m_duration > diff) m_duration -= diff; @@ -72,24 +72,24 @@ bool RotateMovementGenerator::Update(Unit& owner, const uint32& diff) return true; } -void RotateMovementGenerator::Finalize(Unit &unit) +void RotateMovementGenerator::Finalize(Unit* unit) { - unit.ClearUnitState(UNIT_STATE_ROTATING); - if (unit.GetTypeId() == TYPEID_UNIT) - unit.ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, 0); + unit->ClearUnitState(UNIT_STATE_ROTATING); + if (unit->GetTypeId() == TYPEID_UNIT) + unit->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, 0); } -void DistractMovementGenerator::Initialize(Unit& owner) +void DistractMovementGenerator::Initialize(Unit* owner) { - owner.AddUnitState(UNIT_STATE_DISTRACTED); + owner->AddUnitState(UNIT_STATE_DISTRACTED); } -void DistractMovementGenerator::Finalize(Unit& owner) +void DistractMovementGenerator::Finalize(Unit* owner) { - owner.ClearUnitState(UNIT_STATE_DISTRACTED); + owner->ClearUnitState(UNIT_STATE_DISTRACTED); } -bool DistractMovementGenerator::Update(Unit& /*owner*/, const uint32& time_diff) +bool DistractMovementGenerator::Update(Unit* /*owner*/, const uint32& time_diff) { if (time_diff > m_timer) return false; @@ -98,9 +98,9 @@ bool DistractMovementGenerator::Update(Unit& /*owner*/, const uint32& time_diff) return true; } -void AssistanceDistractMovementGenerator::Finalize(Unit &unit) +void AssistanceDistractMovementGenerator::Finalize(Unit* unit) { - unit.ClearUnitState(UNIT_STATE_DISTRACTED); - unit.ToCreature()->SetReactState(REACT_AGGRESSIVE); + unit->ClearUnitState(UNIT_STATE_DISTRACTED); + unit->ToCreature()->SetReactState(REACT_AGGRESSIVE); } diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index 7acec82af98..14287d871c9 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -25,10 +25,10 @@ class IdleMovementGenerator : public MovementGenerator { public: - void Initialize(Unit &); - void Finalize(Unit &) { } - void Reset(Unit &); - bool Update(Unit &, const uint32&) { return true; } + void Initialize(Unit*); + void Finalize(Unit*) { } + void Reset(Unit*); + bool Update(Unit*, const uint32&) { return true; } MovementGeneratorType GetMovementGeneratorType() { return IDLE_MOTION_TYPE; } }; @@ -39,10 +39,10 @@ class RotateMovementGenerator : public MovementGenerator public: explicit RotateMovementGenerator(uint32 time, RotateDirection direction) : m_duration(time), m_maxDuration(time), m_direction(direction) {} - void Initialize(Unit& owner); - void Finalize(Unit& owner); - void Reset(Unit& owner) { Initialize(owner); } - bool Update(Unit& owner, const uint32& time_diff); + void Initialize(Unit*); + void Finalize(Unit*); + void Reset(Unit* owner) { Initialize(owner); } + bool Update(Unit*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return ROTATE_MOTION_TYPE; } private: @@ -55,10 +55,10 @@ class DistractMovementGenerator : public MovementGenerator public: explicit DistractMovementGenerator(uint32 timer) : m_timer(timer) {} - void Initialize(Unit& owner); - void Finalize(Unit& owner); - void Reset(Unit& owner) { Initialize(owner); } - bool Update(Unit& owner, const uint32& time_diff); + void Initialize(Unit*); + void Finalize(Unit*); + void Reset(Unit* owner) { Initialize(owner); } + bool Update(Unit*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return DISTRACT_MOTION_TYPE; } private: @@ -72,7 +72,7 @@ class AssistanceDistractMovementGenerator : public DistractMovementGenerator DistractMovementGenerator(timer) {} MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_DISTRACT_MOTION_TYPE; } - void Finalize(Unit& unit); + void Finalize(Unit*); }; #endif diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index cdb8a0a2a05..c8a7c8f8f8d 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -27,12 +27,12 @@ //----- Point Movement Generator template -void PointMovementGenerator::Initialize(T &unit) +void PointMovementGenerator::Initialize(T* unit) { - if (!unit.IsStopped()) - unit.StopMoving(); + if (!unit->IsStopped()) + unit->StopMoving(); - unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); init.MoveTo(i_x, i_y, i_z, m_generatePath); @@ -42,20 +42,20 @@ void PointMovementGenerator::Initialize(T &unit) } template -bool PointMovementGenerator::Update(T &unit, const uint32 & /*diff*/) +bool PointMovementGenerator::Update(T* unit, const uint32& /*diff*/) { - if (!&unit) + if (!unit) return false; - if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) + if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { - unit.ClearUnitState(UNIT_STATE_ROAMING_MOVE); + unit->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } - unit.AddUnitState(UNIT_STATE_ROAMING_MOVE); + unit->AddUnitState(UNIT_STATE_ROAMING_MOVE); - if (i_recalculateSpeed && !unit.movespline->Finalized()) + if (i_recalculateSpeed && !unit->movespline->Finalized()) { i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); @@ -65,74 +65,74 @@ bool PointMovementGenerator::Update(T &unit, const uint32 & /*diff*/) init.Launch(); } - return !unit.movespline->Finalized(); + return !unit->movespline->Finalized(); } template -void PointMovementGenerator::Finalize(T &unit) +void PointMovementGenerator::Finalize(T* unit) { - if (unit.HasUnitState(UNIT_STATE_CHARGING)) - unit.ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); + if (unit->HasUnitState(UNIT_STATE_CHARGING)) + unit->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); - if (unit.movespline->Finalized()) + if (unit->movespline->Finalized()) MovementInform(unit); } template -void PointMovementGenerator::Reset(T &unit) +void PointMovementGenerator::Reset(T* unit) { - if (!unit.IsStopped()) - unit.StopMoving(); + if (!unit->IsStopped()) + unit->StopMoving(); - unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); } template -void PointMovementGenerator::MovementInform(T & /*unit*/) +void PointMovementGenerator::MovementInform(T* /*unit*/) { } -template <> void PointMovementGenerator::MovementInform(Creature &unit) +template <> void PointMovementGenerator::MovementInform(Creature* unit) { - if (unit.AI()) - unit.AI()->MovementInform(POINT_MOTION_TYPE, id); + if (unit->AI()) + unit->AI()->MovementInform(POINT_MOTION_TYPE, id); } -template void PointMovementGenerator::Initialize(Player&); -template void PointMovementGenerator::Initialize(Creature&); -template void PointMovementGenerator::Finalize(Player&); -template void PointMovementGenerator::Finalize(Creature&); -template void PointMovementGenerator::Reset(Player&); -template void PointMovementGenerator::Reset(Creature&); -template bool PointMovementGenerator::Update(Player &, const uint32 &); -template bool PointMovementGenerator::Update(Creature&, const uint32 &); +template void PointMovementGenerator::Initialize(Player*); +template void PointMovementGenerator::Initialize(Creature*); +template void PointMovementGenerator::Finalize(Player*); +template void PointMovementGenerator::Finalize(Creature*); +template void PointMovementGenerator::Reset(Player*); +template void PointMovementGenerator::Reset(Creature*); +template bool PointMovementGenerator::Update(Player*, const uint32&); +template bool PointMovementGenerator::Update(Creature*, const uint32&); -void AssistanceMovementGenerator::Finalize(Unit &unit) +void AssistanceMovementGenerator::Finalize(Unit* unit) { - unit.ToCreature()->SetNoCallAssistance(false); - unit.ToCreature()->CallAssistance(); - if (unit.isAlive()) - unit.GetMotionMaster()->MoveSeekAssistanceDistract(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY)); + unit->ToCreature()->SetNoCallAssistance(false); + unit->ToCreature()->CallAssistance(); + if (unit->isAlive()) + unit->GetMotionMaster()->MoveSeekAssistanceDistract(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY)); } -bool EffectMovementGenerator::Update(Unit &unit, const uint32&) +bool EffectMovementGenerator::Update(Unit* unit, const uint32&) { - return !unit.movespline->Finalized(); + return !unit->movespline->Finalized(); } -void EffectMovementGenerator::Finalize(Unit &unit) +void EffectMovementGenerator::Finalize(Unit* unit) { - if (unit.GetTypeId() != TYPEID_UNIT) + if (unit->GetTypeId() != TYPEID_UNIT) return; - if (((Creature&)unit).AI()) - ((Creature&)unit).AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); + if (unit->ToCreature()->AI()) + unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); // Need restore previous movement since we have no proper states system - if (unit.isAlive() && !unit.HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING)) + if (unit->isAlive() && !unit->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING)) { - if (Unit* victim = unit.getVictim()) - unit.GetMotionMaster()->MoveChase(victim); + if (Unit* victim = unit->getVictim()) + unit->GetMotionMaster()->MoveChase(victim); else - unit.GetMotionMaster()->Initialize(); + unit->GetMotionMaster()->Initialize(); } } diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 541cbdbc3a7..4111690627e 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -29,18 +29,18 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed) {} - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - bool Update(T &, const uint32 &); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + bool Update(T*, const uint32 &); - void MovementInform(T &); + void MovementInform(T*); void unitSpeedChanged() { i_recalculateSpeed = true; } MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; } - bool GetDestination(float& x, float& y, float& z) const { x=i_x; y=i_y; z=i_z; return true; } + void GetDestination(float& x, float& y, float& z) const { x = i_x; y = i_y; z = i_z; } private: uint32 id; float i_x, i_y, i_z; @@ -56,7 +56,7 @@ class AssistanceMovementGenerator : public PointMovementGenerator PointMovementGenerator(0, _x, _y, _z, true) {} MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_MOTION_TYPE; } - void Finalize(Unit &); + void Finalize(Unit*); }; // Does almost nothing - just doesn't allows previous movegen interrupt current effect. @@ -64,10 +64,10 @@ class EffectMovementGenerator : public MovementGenerator { public: explicit EffectMovementGenerator(uint32 Id) : m_Id(Id) {} - void Initialize(Unit &) {} - void Finalize(Unit &unit); - void Reset(Unit &) {} - bool Update(Unit &u, const uint32&); + void Initialize(Unit*) {} + void Finalize(Unit*); + void Reset(Unit*) {} + bool Update(Unit*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return EFFECT_MOTION_TYPE; } private: uint32 m_Id; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 84cd9e88295..3e55b9679c6 100755 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -33,16 +33,16 @@ #endif template<> -void RandomMovementGenerator::_setRandomLocation(Creature& creature) +void RandomMovementGenerator::_setRandomLocation(Creature* creature) { float respX, respY, respZ, respO, destX, destY, destZ, travelDistZ; - creature.GetHomePosition(respX, respY, respZ, respO); - Map const* map = creature.GetBaseMap(); + creature->GetHomePosition(respX, respY, respZ, respO); + Map const* map = creature->GetBaseMap(); // For 2D/3D system selection //bool is_land_ok = creature.CanWalk(); // not used? //bool is_water_ok = creature.CanSwim(); // not used? - bool is_air_ok = creature.CanFly(); + bool is_air_ok = creature->CanFly(); const float angle = float(rand_norm()) * static_cast(M_PI*2.0f); const float range = float(rand_norm()) * wander_distance; @@ -77,17 +77,17 @@ void RandomMovementGenerator::_setRandomLocation(Creature& creature) // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. - destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, false); + destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, false); if (fabs(destZ - respZ) > travelDistZ) // Map check { // Vmap Horizontal or above - destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ - 2.0f, true); + destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ - 2.0f, true); if (fabs(destZ - respZ) > travelDistZ) { // Vmap Higher - destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, true); + destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, true); // let's forget this bad coords where a z cannot be find and retry at next tick if (fabs(destZ - respZ) > travelDistZ) @@ -101,7 +101,7 @@ void RandomMovementGenerator::_setRandomLocation(Creature& creature) else i_nextMoveTime.Reset(urand(500, 10000)); - creature.AddUnitState(UNIT_STATE_ROAMING_MOVE); + creature->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(destX, destY, destZ); @@ -109,47 +109,47 @@ void RandomMovementGenerator::_setRandomLocation(Creature& creature) init.Launch(); //Call for creature group update - if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) - creature.GetFormation()->LeaderMoveTo(destX, destY, destZ); + if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature) + creature->GetFormation()->LeaderMoveTo(destX, destY, destZ); } template<> -void RandomMovementGenerator::Initialize(Creature &creature) +void RandomMovementGenerator::Initialize(Creature* creature) { - if (!creature.isAlive()) + if (!creature->isAlive()) return; if (!wander_distance) - wander_distance = creature.GetRespawnRadius(); + wander_distance = creature->GetRespawnRadius(); - creature.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + creature->AddUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); _setRandomLocation(creature); } template<> -void RandomMovementGenerator::Reset(Creature &creature) +void RandomMovementGenerator::Reset(Creature* creature) { Initialize(creature); } template<> -void RandomMovementGenerator::Finalize(Creature &creature) +void RandomMovementGenerator::Finalize(Creature* creature) { - creature.ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); - creature.SetWalk(false); + creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + creature->SetWalk(false); } template<> -bool RandomMovementGenerator::Update(Creature &creature, const uint32 diff) +bool RandomMovementGenerator::Update(Creature* creature, const uint32 diff) { - if (creature.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) + if (creature->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) { i_nextMoveTime.Reset(0); // Expire the timer - creature.ClearUnitState(UNIT_STATE_ROAMING_MOVE); + creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } - if (creature.movespline->Finalized()) + if (creature->movespline->Finalized()) { i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) @@ -159,14 +159,14 @@ bool RandomMovementGenerator::Update(Creature &creature, const uint32 } template<> -bool RandomMovementGenerator::GetResetPosition(Creature &creature, float& x, float& y, float& z) +bool RandomMovementGenerator::GetResetPosition(Creature* creature, float& x, float& y, float& z) { float radius; - creature.GetRespawnPosition(x, y, z, NULL, &radius); + creature->GetRespawnPosition(x, y, z, NULL, &radius); // use current if in range - if (creature.IsWithinDist2d(x,y,radius)) - creature.GetPosition(x,y,z); + if (creature->IsWithinDist2d(x,y,radius)) + creature->GetPosition(x,y,z); return true; } diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h index 07ec3647052..ca370de6ac3 100755 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h @@ -27,12 +27,12 @@ class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovemen public: RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) {} - void _setRandomLocation(T &); - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - bool Update(T &, const uint32); - bool GetResetPosition(T&, float& x, float& y, float& z); + void _setRandomLocation(T*); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + bool Update(T*, const uint32); + bool GetResetPosition(T*, float& x, float& y, float& z); MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; } private: TimeTrackerSmall i_nextMoveTime; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 6d322a56a80..9784c19b4fd 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -27,12 +27,12 @@ #include "Player.h" template -void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) +void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) { if (!i_target.isValid() || !i_target->IsInWorld()) return; - if (owner.HasUnitState(UNIT_STATE_NOT_MOVE)) + if (owner->HasUnitState(UNIT_STATE_NOT_MOVE)) return; float x, y, z; @@ -49,26 +49,26 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) // else if (!i_offset) { - if (i_target->IsWithinMeleeRange(&owner)) + if (i_target->IsWithinMeleeRange(owner)) return; // to nearest random contact position - i_target->GetRandomContactPoint(&owner, x, y, z, 0, MELEE_RANGE - 0.5f); + i_target->GetRandomContactPoint(owner, x, y, z, 0, MELEE_RANGE - 0.5f); } else { - if (i_target->IsWithinDistInMap(&owner, i_offset + 1.0f)) + if (i_target->IsWithinDistInMap(owner, i_offset + 1.0f)) return; // to at i_offset distance from target and i_angle from target facing - i_target->GetClosePoint(x, y, z, owner.GetObjectSize(), i_offset, i_angle); + i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); } if (!i_path) - i_path = new PathGenerator(&owner); + i_path = new PathGenerator(owner); // allow pets following their master to cheat while generating paths - bool forceDest = (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->isPet() - && owner.HasUnitState(UNIT_STATE_FOLLOW)); + bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet() + && owner->HasUnitState(UNIT_STATE_FOLLOW)); i_path->CalculatePath(x, y, z, forceDest); if (i_path->getPathType() & PATHFIND_NOPATH) return; @@ -76,7 +76,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T &owner) D::_addUnitStateMove(owner); i_targetReached = false; i_recalculateTravel = false; - owner.AddUnitState(UNIT_STATE_CHASE); + owner->AddUnitState(UNIT_STATE_CHASE); Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->getPath()); @@ -111,25 +111,25 @@ void TargetedMovementGeneratorMedium } template -bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_diff) +bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_diff) { if (!i_target.isValid() || !i_target->IsInWorld()) return false; - if (!&owner || !owner.isAlive()) + if (!owner || !owner->isAlive()) return true; - if (owner.HasUnitState(UNIT_STATE_NOT_MOVE)) + if (owner->HasUnitState(UNIT_STATE_NOT_MOVE)) { D::_clearUnitStateMove(owner); return true; } // prevent movement while casting spells with cast time or channel time - if (owner.HasUnitState(UNIT_STATE_CASTING)) + if (owner->HasUnitState(UNIT_STATE_CASTING)) { - if (!owner.IsStopped()) - owner.StopMoving(); + if (!owner->IsStopped()) + owner->StopMoving(); return true; } @@ -145,11 +145,11 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ { i_recheckDistance.Reset(100); //More distance let have better performance, less distance let have more sensitive reaction at target move. - float allowed_dist = owner.GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE); - G3D::Vector3 dest = owner.movespline->FinalDestination(); + float allowed_dist = owner->GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE); + G3D::Vector3 dest = owner->movespline->FinalDestination(); bool targetMoved = false; - if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->CanFly()) + if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly()) targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); @@ -158,11 +158,11 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ _setTargetLocation(owner); } - if (owner.movespline->Finalized()) + if (owner->movespline->Finalized()) { static_cast(this)->MovementInform(owner); - if (i_angle == 0.f && !owner.HasInArc(0.01f, i_target.getTarget())) - owner.SetInFront(i_target.getTarget()); + if (i_angle == 0.f && !owner->HasInArc(0.01f, i_target.getTarget())) + owner->SetInFront(i_target.getTarget()); if (!i_targetReached) { @@ -180,50 +180,50 @@ bool TargetedMovementGeneratorMedium::Update(T &owner, const uint32 & time_ //-----------------------------------------------// template -void ChaseMovementGenerator::_reachTarget(T &owner) +void ChaseMovementGenerator::_reachTarget(T* owner) { - if (owner.IsWithinMeleeRange(this->i_target.getTarget())) - owner.Attack(this->i_target.getTarget(),true); + if (owner->IsWithinMeleeRange(this->i_target.getTarget())) + owner->Attack(this->i_target.getTarget(),true); } template<> -void ChaseMovementGenerator::Initialize(Player &owner) +void ChaseMovementGenerator::Initialize(Player* owner) { - owner.AddUnitState(UNIT_STATE_CHASE|UNIT_STATE_CHASE_MOVE); + owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); _setTargetLocation(owner); } template<> -void ChaseMovementGenerator::Initialize(Creature &owner) +void ChaseMovementGenerator::Initialize(Creature* owner) { - owner.SetWalk(false); - owner.AddUnitState(UNIT_STATE_CHASE|UNIT_STATE_CHASE_MOVE); + owner->SetWalk(false); + owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); _setTargetLocation(owner); } template -void ChaseMovementGenerator::Finalize(T &owner) +void ChaseMovementGenerator::Finalize(T* owner) { - owner.ClearUnitState(UNIT_STATE_CHASE|UNIT_STATE_CHASE_MOVE); + owner->ClearUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); } template -void ChaseMovementGenerator::Reset(T &owner) +void ChaseMovementGenerator::Reset(T* owner) { Initialize(owner); } template -void ChaseMovementGenerator::MovementInform(T & /*unit*/) +void ChaseMovementGenerator::MovementInform(T* /*unit*/) { } template<> -void ChaseMovementGenerator::MovementInform(Creature &unit) +void ChaseMovementGenerator::MovementInform(Creature* unit) { // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle - if (unit.AI()) - unit.AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); + if (unit->AI()) + unit->AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); } //-----------------------------------------------// @@ -240,85 +240,85 @@ bool FollowMovementGenerator::EnableWalking() const } template<> -void FollowMovementGenerator::_updateSpeed(Player &/*u*/) +void FollowMovementGenerator::_updateSpeed(Player* /*u*/) { // nothing to do for Player } template<> -void FollowMovementGenerator::_updateSpeed(Creature &u) +void FollowMovementGenerator::_updateSpeed(Creature* u) { // pet only sync speed with owner - if (!((Creature&)u).isPet() || !i_target.isValid() || i_target->GetGUID() != u.GetOwnerGUID()) + if (!u->isPet() || !i_target.isValid() || i_target->GetGUID() != u->GetOwnerGUID()) return; - u.UpdateSpeed(MOVE_RUN,true); - u.UpdateSpeed(MOVE_WALK,true); - u.UpdateSpeed(MOVE_SWIM,true); + u->UpdateSpeed(MOVE_RUN,true); + u->UpdateSpeed(MOVE_WALK,true); + u->UpdateSpeed(MOVE_SWIM,true); } template<> -void FollowMovementGenerator::Initialize(Player &owner) +void FollowMovementGenerator::Initialize(Player* owner) { - owner.AddUnitState(UNIT_STATE_FOLLOW|UNIT_STATE_FOLLOW_MOVE); + owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); _setTargetLocation(owner); } template<> -void FollowMovementGenerator::Initialize(Creature &owner) +void FollowMovementGenerator::Initialize(Creature* owner) { - owner.AddUnitState(UNIT_STATE_FOLLOW|UNIT_STATE_FOLLOW_MOVE); + owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); _setTargetLocation(owner); } template -void FollowMovementGenerator::Finalize(T &owner) +void FollowMovementGenerator::Finalize(T* owner) { - owner.ClearUnitState(UNIT_STATE_FOLLOW|UNIT_STATE_FOLLOW_MOVE); + owner->ClearUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); } template -void FollowMovementGenerator::Reset(T &owner) +void FollowMovementGenerator::Reset(T* owner) { Initialize(owner); } template -void FollowMovementGenerator::MovementInform(T & /*unit*/) +void FollowMovementGenerator::MovementInform(T* /*unit*/) { } template<> -void FollowMovementGenerator::MovementInform(Creature &unit) +void FollowMovementGenerator::MovementInform(Creature* unit) { // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle - if (unit.AI()) - unit.AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); + if (unit->AI()) + unit->AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); } //-----------------------------------------------// -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player &); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player &); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature &); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature &); -template bool TargetedMovementGeneratorMedium >::Update(Player &, const uint32 &); -template bool TargetedMovementGeneratorMedium >::Update(Player &, const uint32 &); -template bool TargetedMovementGeneratorMedium >::Update(Creature &, const uint32 &); -template bool TargetedMovementGeneratorMedium >::Update(Creature &, const uint32 &); - -template void ChaseMovementGenerator::_reachTarget(Player &); -template void ChaseMovementGenerator::_reachTarget(Creature &); -template void ChaseMovementGenerator::Finalize(Player &); -template void ChaseMovementGenerator::Finalize(Creature &); -template void ChaseMovementGenerator::Reset(Player &); -template void ChaseMovementGenerator::Reset(Creature &); -template void ChaseMovementGenerator::MovementInform(Player &unit); - -template void FollowMovementGenerator::Finalize(Player &); -template void FollowMovementGenerator::Finalize(Creature &); -template void FollowMovementGenerator::Reset(Player &); -template void FollowMovementGenerator::Reset(Creature &); -template void FollowMovementGenerator::MovementInform(Player &unit); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); +template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); +template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); +template bool TargetedMovementGeneratorMedium >::Update(Creature*, const uint32&); +template bool TargetedMovementGeneratorMedium >::Update(Creature*, const uint32&); + +template void ChaseMovementGenerator::_reachTarget(Player*); +template void ChaseMovementGenerator::_reachTarget(Creature*); +template void ChaseMovementGenerator::Finalize(Player*); +template void ChaseMovementGenerator::Finalize(Creature*); +template void ChaseMovementGenerator::Reset(Player*); +template void ChaseMovementGenerator::Reset(Creature*); +template void ChaseMovementGenerator::MovementInform(Player*); + +template void FollowMovementGenerator::Finalize(Player*); +template void FollowMovementGenerator::Finalize(Creature*); +template void FollowMovementGenerator::Reset(Player*); +template void FollowMovementGenerator::Reset(Creature*); +template void FollowMovementGenerator::MovementInform(Player*); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index db5e05c7b23..688d236c3f8 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -28,7 +28,7 @@ class TargetedMovementGeneratorBase { public: - TargetedMovementGeneratorBase(Unit &target) { i_target.link(&target, this); } + TargetedMovementGeneratorBase(Unit* target) { i_target.link(target, this); } void stopFollowing() { } protected: FollowerReference i_target; @@ -38,7 +38,7 @@ template class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase { protected: - TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) : + TargetedMovementGeneratorMedium(Unit* target, float offset, float angle) : TargetedMovementGeneratorBase(target), i_recheckDistance(0), i_path(NULL), i_offset(offset), i_angle(angle), i_recalculateTravel(false), i_targetReached(false) @@ -47,14 +47,14 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, ~TargetedMovementGeneratorMedium() { delete i_path; } public: - bool Update(T &, const uint32 &); + bool Update(T*, const uint32 &); Unit* GetTarget() const { return i_target.getTarget(); } - void unitSpeedChanged() { i_recalculateTravel=true; } + void unitSpeedChanged() { i_recalculateTravel = true; } void UpdateFinalDistance(float fDistance); bool IsReachable() const { return (i_path) ? (i_path->getPathType() & PATHFIND_NORMAL) : true; } protected: - void _setTargetLocation(T &); + void _setTargetLocation(T*); TimeTrackerSmall i_recheckDistance; float i_offset; @@ -68,50 +68,50 @@ template class ChaseMovementGenerator : public TargetedMovementGeneratorMedium > { public: - ChaseMovementGenerator(Unit &target) + ChaseMovementGenerator(Unit* target) : TargetedMovementGeneratorMedium >(target) {} - ChaseMovementGenerator(Unit &target, float offset, float angle) + ChaseMovementGenerator(Unit* target, float offset, float angle) : TargetedMovementGeneratorMedium >(target, offset, angle) {} ~ChaseMovementGenerator() {} MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; } - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - void MovementInform(T &); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + void MovementInform(T*); - static void _clearUnitStateMove(T &u) { u.ClearUnitState(UNIT_STATE_CHASE_MOVE); } - static void _addUnitStateMove(T &u) { u.AddUnitState(UNIT_STATE_CHASE_MOVE); } + static void _clearUnitStateMove(T* u) { u->ClearUnitState(UNIT_STATE_CHASE_MOVE); } + static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_CHASE_MOVE); } bool EnableWalking() const { return false;} - bool _lostTarget(T &u) const { return u.getVictim() != this->GetTarget(); } - void _reachTarget(T &); + bool _lostTarget(T* u) const { return u->getVictim() != GetTarget(); } + void _reachTarget(T*); }; template class FollowMovementGenerator : public TargetedMovementGeneratorMedium > { public: - FollowMovementGenerator(Unit &target) + FollowMovementGenerator(Unit* target) : TargetedMovementGeneratorMedium >(target){} - FollowMovementGenerator(Unit &target, float offset, float angle) + FollowMovementGenerator(Unit* target, float offset, float angle) : TargetedMovementGeneratorMedium >(target, offset, angle) {} ~FollowMovementGenerator() {} MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; } - void Initialize(T &); - void Finalize(T &); - void Reset(T &); - void MovementInform(T &); + void Initialize(T*); + void Finalize(T*); + void Reset(T*); + void MovementInform(T*); - static void _clearUnitStateMove(T &u) { u.ClearUnitState(UNIT_STATE_FOLLOW_MOVE); } - static void _addUnitStateMove(T &u) { u.AddUnitState(UNIT_STATE_FOLLOW_MOVE); } + static void _clearUnitStateMove(T* u) { u->ClearUnitState(UNIT_STATE_FOLLOW_MOVE); } + static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_FOLLOW_MOVE); } bool EnableWalking() const; - bool _lostTarget(T &) const { return false; } - void _reachTarget(T &) {} + bool _lostTarget(T*) const { return false; } + void _reachTarget(T*) {} private: - void _updateSpeed(T &u); + void _updateSpeed(T* u); }; #endif diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 8c2db9ddbd6..c576d7389f3 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -31,64 +31,64 @@ #include "MoveSplineInit.h" #include "MoveSpline.h" -void WaypointMovementGenerator::LoadPath(Creature &creature) +void WaypointMovementGenerator::LoadPath(Creature* creature) { if (!path_id) - path_id = creature.GetWaypointPath(); + path_id = creature->GetWaypointPath(); i_path = sWaypointMgr->GetPath(path_id); if (!i_path) { // No movement found for entry - sLog->outError(LOG_FILTER_SQL, "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path id: %u", creature.GetName(), creature.GetEntry(), creature.GetGUIDLow(), path_id); + sLog->outError(LOG_FILTER_SQL, "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path id: %u", creature->GetName(), creature->GetEntry(), creature->GetGUIDLow(), path_id); return; } StartMoveNow(creature); } -void WaypointMovementGenerator::Initialize(Creature &creature) +void WaypointMovementGenerator::Initialize(Creature* creature) { LoadPath(creature); - creature.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); } -void WaypointMovementGenerator::Finalize(Creature &creature) +void WaypointMovementGenerator::Finalize(Creature* creature) { - creature.ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); - creature.SetWalk(false); + creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + creature->SetWalk(false); } -void WaypointMovementGenerator::Reset(Creature &creature) +void WaypointMovementGenerator::Reset(Creature* creature) { - creature.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); StartMoveNow(creature); } -void WaypointMovementGenerator::OnArrived(Creature& creature) +void WaypointMovementGenerator::OnArrived(Creature* creature) { if (!i_path || i_path->empty()) return; if (m_isArrivalDone) return; - creature.ClearUnitState(UNIT_STATE_ROAMING_MOVE); + creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); m_isArrivalDone = true; if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance) { - sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for "UI64FMTD".", i_path->at(i_currentNode)->event_id, i_currentNode, creature.GetGUID()); - creature.GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, &creature, NULL); + sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for "UI64FMTD".", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID()); + creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, NULL); } // Inform script MovementInform(creature); - creature.UpdateWaypointID(i_currentNode); + creature->UpdateWaypointID(i_currentNode); Stop(i_path->at(i_currentNode)->delay); } -bool WaypointMovementGenerator::StartMove(Creature &creature) +bool WaypointMovementGenerator::StartMove(Creature* creature) { if (!i_path || i_path->empty()) return false; @@ -99,8 +99,8 @@ bool WaypointMovementGenerator::StartMove(Creature &creature) { if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint { - creature.SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature.GetOrientation()); - creature.GetMotionMaster()->Initialize(); + creature->SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature->GetOrientation()); + creature->GetMotionMaster()->Initialize(); return false; } @@ -111,7 +111,7 @@ bool WaypointMovementGenerator::StartMove(Creature &creature) m_isArrivalDone = false; - creature.AddUnitState(UNIT_STATE_ROAMING_MOVE); + creature->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(node->x, node->y, node->z); @@ -124,19 +124,19 @@ bool WaypointMovementGenerator::StartMove(Creature &creature) init.Launch(); //Call for creature group update - if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) - creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); + if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature) + creature->GetFormation()->LeaderMoveTo(node->x, node->y, node->z); return true; } -bool WaypointMovementGenerator::Update(Creature &creature, const uint32 &diff) +bool WaypointMovementGenerator::Update(Creature* creature, const uint32& diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff - if (creature.HasUnitState(UNIT_STATE_NOT_MOVE)) + if (creature->HasUnitState(UNIT_STATE_NOT_MOVE)) { - creature.ClearUnitState(UNIT_STATE_ROAMING_MOVE); + creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. @@ -150,9 +150,9 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 } else { - if (creature.IsStopped()) + if (creature->IsStopped()) Stop(STOP_TIME_FOR_PLAYER); - else if (creature.movespline->Finalized()) + else if (creature->movespline->Finalized()) { OnArrived(creature); return StartMove(creature); @@ -161,13 +161,13 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 return true; } -void WaypointMovementGenerator::MovementInform(Creature &creature) +void WaypointMovementGenerator::MovementInform(Creature* creature) { - if (creature.AI()) - creature.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); + if (creature->AI()) + creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); } -bool WaypointMovementGenerator::GetResetPosition(Creature&, float& x, float& y, float& z) +bool WaypointMovementGenerator::GetResetPosition(Creature*, float& x, float& y, float& z) { // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) @@ -196,37 +196,37 @@ uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const return i_path->size(); } -void FlightPathMovementGenerator::Initialize(Player &player) +void FlightPathMovementGenerator::Initialize(Player* player) { Reset(player); InitEndGridInfo(); } -void FlightPathMovementGenerator::Finalize(Player& player) +void FlightPathMovementGenerator::Finalize(Player* player) { // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack) - player.ClearUnitState(UNIT_STATE_IN_FLIGHT); + player->ClearUnitState(UNIT_STATE_IN_FLIGHT); - player.Dismount(); - player.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + player->Dismount(); + player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); - if (player.m_taxi.empty()) + if (player->m_taxi.empty()) { - player.getHostileRefManager().setOnlineOfflineState(true); + player->getHostileRefManager().setOnlineOfflineState(true); // update z position to ground and orientation for landing point // this prevent cheating with landing point at lags // when client side flight end early in comparison server side - player.StopMoving(); + player->StopMoving(); } } #define PLAYER_FLIGHT_SPEED 32.0f -void FlightPathMovementGenerator::Reset(Player & player) +void FlightPathMovementGenerator::Reset(Player* player) { - player.getHostileRefManager().setOnlineOfflineState(false); - player.AddUnitState(UNIT_STATE_IN_FLIGHT); - player.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + player->getHostileRefManager().setOnlineOfflineState(false); + player->AddUnitState(UNIT_STATE_IN_FLIGHT); + player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); Movement::MoveSplineInit init(player); uint32 end = GetPathAtMapEnd(); @@ -241,9 +241,9 @@ void FlightPathMovementGenerator::Reset(Player & player) init.Launch(); } -bool FlightPathMovementGenerator::Update(Player &player, const uint32& /*diff*/) +bool FlightPathMovementGenerator::Update(Player* player, const uint32& /*diff*/) { - uint32 pointId = (uint32)player.movespline->currentPathIdx(); + uint32 pointId = (uint32)player->movespline->currentPathIdx(); if (pointId > i_currentNode) { bool departureEvent = true; @@ -279,16 +279,16 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() } } -void FlightPathMovementGenerator::DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure) +void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure) { if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID) { - sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player.GetName()); - player.GetMap()->ScriptsStart(sEventScripts, eventid, &player, &player); + sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player->GetName()); + player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player); } } -bool FlightPathMovementGenerator::GetResetPosition(Player&, float& x, float& y, float& z) +bool FlightPathMovementGenerator::GetResetPosition(Player*, float& x, float& y, float& z) { const TaxiPathNodeEntry& node = (*i_path)[i_currentNode]; x = node.x; y = node.y; z = node.z; diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index 0d8f047c83a..5230fe3b0e3 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -65,19 +65,19 @@ class WaypointMovementGenerator : public MovementGeneratorMedium< Crea WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) : i_nextMoveTime(0), m_isArrivalDone(false), path_id(_path_id), repeating(_repeating) {} ~WaypointMovementGenerator() { i_path = NULL; } - void Initialize(Creature &); - void Finalize(Creature &); - void Reset(Creature &); - bool Update(Creature &, const uint32 &diff); + void Initialize(Creature*); + void Finalize(Creature*); + void Reset(Creature*); + bool Update(Creature*, const uint32 &diff); - void MovementInform(Creature &); + void MovementInform(Creature*); MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; } // now path movement implmementation - void LoadPath(Creature &c); + void LoadPath(Creature*); - bool GetResetPosition(Creature&, float& x, float& y, float& z); + bool GetResetPosition(Creature*, float& x, float& y, float& z); private: @@ -91,10 +91,10 @@ class WaypointMovementGenerator : public MovementGeneratorMedium< Crea return i_nextMoveTime.Passed(); } - void OnArrived(Creature&); - bool StartMove(Creature&); + void OnArrived(Creature*); + bool StartMove(Creature*); - void StartMoveNow(Creature& creature) + void StartMoveNow(Creature* creature) { i_nextMoveTime.Reset(0); StartMove(creature); @@ -118,10 +118,10 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig i_path = &pathnodes; i_currentNode = startNode; } - void Initialize(Player &); - void Reset(Player &); - void Finalize(Player &); - bool Update(Player &, const uint32&); + void Initialize(Player*); + void Reset(Player*); + void Finalize(Player*); + bool Update(Player*, const uint32&); MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } TaxiPathNodeList const& GetPath() { return *i_path; } @@ -129,9 +129,9 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig bool HasArrived() const { return (i_currentNode >= i_path->size()); } void SetCurrentNodeAfterTeleport(); void SkipCurrentNode() { ++i_currentNode; } - void DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure); + void DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure); - bool GetResetPosition(Player&, float& x, float& y, float& z); + bool GetResetPosition(Player*, float& x, float& y, float& z); void InitEndGridInfo(); void PreloadEndGrid(); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index c5e314a8636..8167ff36de2 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -58,18 +58,18 @@ namespace Movement int32 MoveSplineInit::Launch() { - MoveSpline& move_spline = *unit.movespline; + MoveSpline& move_spline = *unit->movespline; bool transport = false; - Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); + Location real_position(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZMinusOffset(), unit->GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) + if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID()) { transport = true; - real_position.x = unit.GetTransOffsetX(); - real_position.y = unit.GetTransOffsetY(); - real_position.z = unit.GetTransOffsetZ(); - real_position.orientation = unit.GetTransOffsetO(); + real_position.x = unit->GetTransOffsetX(); + real_position.y = unit->GetTransOffsetY(); + real_position.z = unit->GetTransOffsetZ(); + real_position.orientation = unit->GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it @@ -85,7 +85,7 @@ namespace Movement args.path[0] = real_position; args.initialOrientation = real_position.orientation; - uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); + uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) moveFlags |= MOVEMENTFLAG_WALKING; else @@ -94,7 +94,7 @@ namespace Movement moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); if (!args.HasVelocity) - args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); + args.velocity = unit->GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate()) return 0; @@ -102,33 +102,33 @@ namespace Movement if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; - unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); + unit->m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64); - data.append(unit.GetPackGUID()); + data.append(unit->GetPackGUID()); if (transport) { - data.appendPackGUID(unit.GetTransGUID()); - data << int8(unit.GetTransSeat()); + data.appendPackGUID(unit->GetTransGUID()); + data << int8(unit->GetTransSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); - unit.SendMessageToSet(&data,true); + unit->SendMessageToSet(&data,true); return move_spline.Duration(); } - MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) + MoveSplineInit::MoveSplineInit(Unit* m) : unit(m) { // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID(); + args.TransformForTransport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); // mix existing state into new - args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); - args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY)); + args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); + args.flags.flying = unit->m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); } - void MoveSplineInit::SetFacing(const Unit * target) + void MoveSplineInit::SetFacing(const Unit* target) { args.flags.EnableFacingTarget(); args.facing.target = target->GetGUID(); @@ -138,9 +138,9 @@ namespace Movement { if (args.TransformForTransport) { - if (Unit* vehicle = unit.GetVehicleBase()) + if (Unit* vehicle = unit->GetVehicleBase()) angle -= vehicle->GetOrientation(); - else if (Transport* transport = unit.GetTransport()) + else if (Transport* transport = unit->GetTransport()) angle -= transport->GetOrientation(); } @@ -152,7 +152,7 @@ namespace Movement { if (generatePath) { - PathGenerator path(&unit); + PathGenerator path(unit); path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); MovebyPath(path.getPath()); } @@ -169,13 +169,13 @@ namespace Movement { if (_transformForTransport) { - if (Unit* vehicle = _owner.GetVehicleBase()) + if (Unit* vehicle = _owner->GetVehicleBase()) { input.x -= vehicle->GetPositionX(); input.y -= vehicle->GetPositionY(); input.z -= vehicle->GetPositionZMinusOffset(); } - else if (Transport* transport = _owner.GetTransport()) + else if (Transport* transport = _owner->GetTransport()) { float unused = 0.0f; transport->CalculatePassengerOffset(input.x, input.y, input.z, unused); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 759fc73d7fd..53adec2e633 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -38,12 +38,12 @@ namespace Movement class TransportPathTransform { public: - TransportPathTransform(Unit& owner, bool transformForTransport) + TransportPathTransform(Unit* owner, bool transformForTransport) : _owner(owner), _transformForTransport(transformForTransport) { } Vector3 operator()(Vector3 input); private: - Unit& _owner; + Unit* _owner; bool _transformForTransport; }; @@ -53,7 +53,7 @@ namespace Movement { public: - explicit MoveSplineInit(Unit& m); + explicit MoveSplineInit(Unit* m); /* Final pass of initialization that launches spline movement. */ @@ -76,7 +76,7 @@ namespace Movement */ void SetFacing(float angle); void SetFacing(Vector3 const& point); - void SetFacing(const Unit * target); + void SetFacing(const Unit* target); /* Initializes movement by path * @param path - array of points, shouldn't be empty @@ -138,7 +138,7 @@ namespace Movement protected: MoveSplineInitArgs args; - Unit& unit; + Unit* unit; }; inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 7ee67060f97..c6b89d37878 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -342,7 +342,7 @@ class boss_algalon_the_observer : public CreatureScript DoCast(me, SPELL_RIDE_THE_LIGHTNING, true); me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); me->SetHomePosition(AlgalonLandPos); - Movement::MoveSplineInit init(*me); + Movement::MoveSplineInit init(me); init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); init.SetOrientationFixed(true); init.Launch(); -- cgit v1.2.3 From a97cfbd2ebeaf8e39cef6802deb3139569505288 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 26 Aug 2012 18:14:58 -0500 Subject: Core/MMaps: Fixed infinite wait in the generator --- src/tools/mmaps_generator/MapBuilder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index b04300994f9..8cdbdf61909 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -194,12 +194,13 @@ namespace MMAP buildMap(mapID); } } - // Wait for all threads to finish before closing down - ACE_Thread_Manager::instance()->wait(); // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) + { + _th->wait(); delete *_th; + } } /**************************************************************************/ -- cgit v1.2.3 From 02bbd1154eb3e119fb095850e60e3dc11ee937b1 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 27 Aug 2012 15:21:54 -0500 Subject: Core/Mmaps: Fixed build --- src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 688d236c3f8..0ca688fb0df 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -84,7 +84,7 @@ class ChaseMovementGenerator : public TargetedMovementGeneratorMediumClearUnitState(UNIT_STATE_CHASE_MOVE); } static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_CHASE_MOVE); } bool EnableWalking() const { return false;} - bool _lostTarget(T* u) const { return u->getVictim() != GetTarget(); } + bool _lostTarget(T* u) const { return u->getVictim() != this->GetTarget(); } void _reachTarget(T*); }; diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 8cdbdf61909..03a77c01d27 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -198,7 +198,7 @@ namespace MMAP // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) { - _th->wait(); + (*_th)->wait(); delete *_th; } } -- cgit v1.2.3 From 8f9dad3d7637a18a5e3cc96dfe32826c810f17b3 Mon Sep 17 00:00:00 2001 From: thesensei Date: Tue, 28 Aug 2012 20:58:03 +0300 Subject: Core/Spells: Destabilize Azure Dragonshrine *Spell script support for spell 49370 --- .../2012_08_28_00_world_spell_script_name.sql | 4 +++ src/server/scripts/Spells/spell_quest.cpp | 41 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 sql/updates/world/2012_08_28_00_world_spell_script_name.sql (limited to 'src') diff --git a/sql/updates/world/2012_08_28_00_world_spell_script_name.sql b/sql/updates/world/2012_08_28_00_world_spell_script_name.sql new file mode 100644 index 00000000000..9cc18a4fa5a --- /dev/null +++ b/sql/updates/world/2012_08_28_00_world_spell_script_name.sql @@ -0,0 +1,4 @@ +-- Spell script name linking for Defending Wyrmrest Temple: Destabilize Azure Dragonshrine Effect +DELETE FROM `spell_script_names` WHERE `spell_id`=49370 ; +INSERT INTO `spell_script_names` VALUES +(49370,'spell_q12372_destabilize_azure_dragonshrine_dummy'); \ No newline at end of file diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 8b67a52d300..759dbfe802d 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1276,6 +1276,46 @@ class spell_q12372_cast_from_gossip_trigger : public SpellScriptLoader } }; +// http://www.wowhead.com/quest=12372 Defending Wyrmrest Temple +// 49370 - Wyrmrest Defender: Destabilize Azure Dragonshrine Effect +enum eQuest12372Data +{ + NPC_WYRMREST_TEMPLE_CREDIT = 27698, +}; + +class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoader +{ + public: + spell_q12372_destabilize_azure_dragonshrine_dummy() : SpellScriptLoader("spell_q12372_destabilize_azure_dragonshrine_dummy") { } + + class spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + { + if (Unit* caster = GetOriginalCaster()) + if (Vehicle* vehicle = caster->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + player->KilledMonsterCredit(NPC_WYRMREST_TEMPLE_CREDIT, 0); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1306,4 +1346,5 @@ void AddSC_quest_spell_scripts() new spell_q12066_bunny_kill_credit(); new spell_q12735_song_of_cleansing(); new spell_q12372_cast_from_gossip_trigger(); + new spell_q12372_destabilize_azure_dragonshrine_dummy(); } -- cgit v1.2.3 From d6221fc4f7a08fe09e7c8bb9226b0168db358450 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 28 Aug 2012 19:31:15 +0100 Subject: Scripts: Fix code style after PR --- .../world/2012_08_28_00_world_spell_script_name.sql | 2 +- src/server/scripts/Spells/spell_quest.cpp | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/sql/updates/world/2012_08_28_00_world_spell_script_name.sql b/sql/updates/world/2012_08_28_00_world_spell_script_name.sql index 9cc18a4fa5a..01cfeb35f1f 100644 --- a/sql/updates/world/2012_08_28_00_world_spell_script_name.sql +++ b/sql/updates/world/2012_08_28_00_world_spell_script_name.sql @@ -1,4 +1,4 @@ -- Spell script name linking for Defending Wyrmrest Temple: Destabilize Azure Dragonshrine Effect DELETE FROM `spell_script_names` WHERE `spell_id`=49370 ; INSERT INTO `spell_script_names` VALUES -(49370,'spell_q12372_destabilize_azure_dragonshrine_dummy'); \ No newline at end of file +(49370,'spell_q12372_destabilize_azure_dragonshrine_dummy'); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 759dbfe802d..3cb2300cadf 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1278,7 +1278,7 @@ class spell_q12372_cast_from_gossip_trigger : public SpellScriptLoader // http://www.wowhead.com/quest=12372 Defending Wyrmrest Temple // 49370 - Wyrmrest Defender: Destabilize Azure Dragonshrine Effect -enum eQuest12372Data +enum Quest12372Data { NPC_WYRMREST_TEMPLE_CREDIT = 27698, }; @@ -1294,16 +1294,14 @@ class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoad void HandleDummy(SpellEffIndex /*effIndex*/) { - if (GetHitCreature()) - { - if (Unit* caster = GetOriginalCaster()) - if (Vehicle* vehicle = caster->GetVehicleKit()) - if (Unit* passenger = vehicle->GetPassenger(0)) - if (Player* player = passenger->ToPlayer()) - player->KilledMonsterCredit(NPC_WYRMREST_TEMPLE_CREDIT, 0); - } - } - + if (GetHitCreature()) + if (Unit* caster = GetOriginalCaster()) + if (Vehicle* vehicle = caster->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + player->KilledMonsterCredit(NPC_WYRMREST_TEMPLE_CREDIT, 0); + } + void Register() { OnEffectHitTarget += SpellEffectFn(spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -- cgit v1.2.3 From fa590d006e9026e95cd666223eee68fae8a33a68 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 28 Aug 2012 20:09:04 -0500 Subject: Core/MMaps: Made some cosmetic improvements to the mmaps generator --- src/tools/mmaps_generator/MapBuilder.cpp | 5 ++--- src/tools/mmaps_generator/PathGenerator.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 03a77c01d27..2a74233a1a7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -179,7 +179,6 @@ namespace MMAP { if ((*_th)->Free) { - printf("Thread is free for map %03i\n", mapID); (*_th)->SetMapId(mapID); (*_th)->activate(); next = true; @@ -335,7 +334,7 @@ namespace MMAP buildNavMesh(mapID, navMesh); if (!navMesh) { - printf("Failed creating navmesh! \n"); + printf("[Map %i] Failed creating navmesh!\n", mapID); return; } @@ -363,7 +362,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) { - printf("Building map %03u, tile [%02u,%02u]\n", mapID, tileX, tileY); + printf("[Map %i] Building tile [%02u,%02u]\n", mapID, tileX, tileY); MeshData meshData; diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 4da90fd153a..026bf957ec4 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -292,6 +292,6 @@ int main(int argc, char** argv) builder.buildAllMaps(threads); if (!silent) - printf("Finished. MMAPS were built in %u ms!", GetMSTimeDiffToNow(start)); + printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); return 1; } -- cgit v1.2.3 From 58d250ce83245dfebf089dc7e8d8f2aa05a7a2ed Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 31 Aug 2012 11:58:45 +0200 Subject: Core/Mmaps: Use mmaps if enabled when re-generating point-movement path after speed changes. (often used by pets) --- src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index c8a7c8f8f8d..20f1c3a29e9 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -59,7 +59,7 @@ bool PointMovementGenerator::Update(T* unit, const uint32& /*diff*/) { i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); - init.MoveTo(i_x, i_y, i_z); + init.MoveTo(i_x, i_y, i_z, m_generatePath); if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit init.SetVelocity(speed); init.Launch(); -- cgit v1.2.3 From a5d977c90eaf48f0961bc7dfdee12c603963abf5 Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 31 Aug 2012 12:06:12 +0200 Subject: Core/Config: Disable petlos by default --- src/server/worldserver/worldserver.conf.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 1a237eac08a..e5b8f21da8e 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -305,10 +305,10 @@ vmap.ignoreSpellIds = "7720" # # vmap.petLOS # Description: Check line of sight for pets, to avoid them attacking through walls. -# Default: 1 - (Enabled, each pet attack will be checked for line of sight) +# Default: 1 - (Enabled, each pet attack will be checked for line of sight - not recommended if mmaps is enabled!) # 0 - (Disabled, somewhat less CPU usage) -vmap.petLOS = 1 +vmap.petLOS = 0 # # vmap.enableIndoorCheck -- cgit v1.2.3 From db7b750e0c33bf75ef6943a9da149cfbb8f6f2d1 Mon Sep 17 00:00:00 2001 From: Myran2 Date: Fri, 31 Aug 2012 01:26:21 +0100 Subject: Scripts/Commands: Create a new group of commands, .cheat, and add new and move old commands to it: Changes: - .explorecheat is now .cheat explore - .waterwalk is now .cheat waterwalk - .taxicheat is now .cheat taxi New commands: - .cheat god - .cheat casttime - .cheat cooldown - .cheat power (Descriptions available in the SQL file / in-game) Inspiration on ArcEmu commands Closes #7569 --- sql/updates/world/2012_8_29_00_world_command.sql | 14 ++ src/server/game/Entities/Player/Player.cpp | 2 + src/server/game/Entities/Player/Player.h | 17 ++ src/server/game/Scripting/ScriptLoader.cpp | 2 + src/server/game/Spells/Spell.cpp | 23 ++ src/server/scripts/Commands/CMakeLists.txt | 1 + src/server/scripts/Commands/cs_cheat.cpp | 281 +++++++++++++++++++++++ src/server/scripts/Commands/cs_misc.cpp | 118 ---------- 8 files changed, 340 insertions(+), 118 deletions(-) create mode 100644 sql/updates/world/2012_8_29_00_world_command.sql create mode 100644 src/server/scripts/Commands/cs_cheat.cpp (limited to 'src') diff --git a/sql/updates/world/2012_8_29_00_world_command.sql b/sql/updates/world/2012_8_29_00_world_command.sql new file mode 100644 index 00000000000..c0686d6d907 --- /dev/null +++ b/sql/updates/world/2012_8_29_00_world_command.sql @@ -0,0 +1,14 @@ +DELETE FROM `command` WHERE `name`='explorecheat'; +DELETE FROM `command` WHERE `name`='taxicheat'; +DELETE FROM `command` WHERE `name`='waterwalk'; + +DELETE FROM `command` WHERE `name`='cheat' OR `name` LIKE 'cheat%'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('cheat', 2, 'Syntax: .cheat $subcommand\r\nType .cheat to see the list of possible subcommands or .help cheat $subcommand to see info on subcommands'), +('cheat god', 2, 'Syntax: .cheat god [on/off]\r\nEnables or disables your character''s ability to take damage.'), +('cheat casttime', 2, 'Syntax: .cheat casttime [on/off]\r\nEnables or disables your character''s spell cast times.'), +('cheat cooldown', 2, 'Syntax: .cheat cooldown [on/off]\r\nEnables or disables your character''s spell cooldowns.'), +('cheat power', 2, 'Syntax: .cheat power [on/off]\r\nEnables or disables your character''s spell cost (e.g mana).'), +('cheat waterwalk', 2, 'Syntax: .cheat waterwalk on/off\r\nSet on/off waterwalk state for selected player or self if no player selected.'), +('cheat explore', 2, 'Syntax: .cheat explore #flag\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'), +('cheat taxi', 2, 'Syntax: .cheat taxi on/off\r\nTemporary grant access or remove to all taxi routes for the selected character.\r\n If no character is selected, hide or reveal all routes to you.Visited taxi nodes sill accessible after removing access.'); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 936788f484e..65f6588f80e 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -861,6 +861,8 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_SeasonalQuestChanged = false; SetPendingBind(0, 0); + + _activeCheats = CHEAT_NONE; } Player::~Player() diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 1758b915ebf..71915f42784 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -896,6 +896,16 @@ enum PlayerRestState REST_STATE_RAF_LINKED = 0x06 }; +enum PlayerCommandStates +{ + CHEAT_NONE = 0x00, + CHEAT_GOD = 0x01, + CHEAT_CASTTIME = 0x02, + CHEAT_COOLDOWN = 0x04, + CHEAT_POWER = 0x08, + CHEAT_WATERWALK = 0x10 +}; + class PlayerTaxi { public: @@ -1148,6 +1158,11 @@ class Player : public Unit, public GridObject void InitStatsForLevel(bool reapplyMods = false); + // .cheat command related + bool GetCommandStatus(uint32 command) const { return _activeCheats & command; } + void SetCommandStatusOn(uint32 command) { _activeCheats |= command; } + void SetCommandStatusOff(uint32 command) { _activeCheats &= ~command; } + // Played Time Stuff time_t m_logintime; time_t m_Last_tick; @@ -2854,6 +2869,8 @@ class Player : public Unit, public GridObject InstanceTimeMap _instanceResetTimes; uint32 _pendingBindId; uint32 _pendingBindTimer; + + uint32 _activeCheats; }; void AddItemsSetItem(Player*player, Item* item); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 9d983542fea..1848250ec8e 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -50,6 +50,7 @@ void AddSC_ban_commandscript(); void AddSC_bf_commandscript(); void AddSC_cast_commandscript(); void AddSC_character_commandscript(); +void AddSC_cheat_commandscript(); void AddSC_debug_commandscript(); void AddSC_disable_commandscript(); void AddSC_event_commandscript(); @@ -666,6 +667,7 @@ void AddCommandScripts() AddSC_bf_commandscript(); AddSC_cast_commandscript(); AddSC_character_commandscript(); + AddSC_cheat_commandscript(); AddSC_debug_commandscript(); AddSC_disable_commandscript(); AddSC_event_commandscript(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 19741ea7854..95345ed8b93 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3023,7 +3023,13 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail) m_casttime = m_spellInfo->CalcCastTime(m_caster, this); if (m_caster->GetTypeId() == TYPEID_PLAYER) + { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + + // Set casttime to 0 if .cheat casttime is enabled. + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME)) + m_casttime = 0; + } // don't allow channeled spells / spells with cast time to be casted while moving // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in) @@ -3315,7 +3321,13 @@ void Spell::cast(bool skipCheck) } if (m_caster->GetTypeId() == TYPEID_PLAYER) + { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + + //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled. + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) + m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true); + } SetExecutedCurrently(false); } @@ -4358,6 +4370,13 @@ void Spell::TakePower() if (m_CastItem || m_triggeredByAuraSpell) return; + //Don't take power if the spell is cast while .cheat power is enabled. + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_POWER)) + return; + } + Powers powerType = Powers(m_spellInfo->PowerType); bool hit = true; if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -7193,6 +7212,10 @@ void Spell::TriggerGlobalCooldown() if (!gcd) return; + if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) + return; + // Global cooldown can't leave range 1..1.5 secs // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns // but as tests show are not affected by any spell mods. diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index d5ebeab3b8a..177b3a479f5 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -16,6 +16,7 @@ set(scripts_STAT_SRCS Commands/cs_bf.cpp Commands/cs_cast.cpp Commands/cs_character.cpp + Commands/cs_cheat.cpp Commands/cs_debug.cpp Commands/cs_disable.cpp Commands/cs_event.cpp diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp new file mode 100644 index 00000000000..ade1b9fae02 --- /dev/null +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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, see . + */ + +/* ScriptData +Name: cheat_commandscript +%Complete: 100 +Comment: All cheat related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "ObjectMgr.h" +#include "Chat.h" + +class cheat_commandscript : public CommandScript +{ +public: + cheat_commandscript() : CommandScript("cheat_commandscript") { } + + ChatCommand* GetCommands() const + { + + static ChatCommand cheatCommandTable[] = + { + { "god", SEC_GAMEMASTER, false, &HandleGodModeCheatCommand, "", NULL }, + { "casttime", SEC_GAMEMASTER, false, &HandleCasttimeCheatCommand, "", NULL }, + { "cooldown", SEC_GAMEMASTER, false, &HandleCoolDownCheatCommand, "", NULL }, + { "power", SEC_GAMEMASTER, false, &HandlePowerCheatCommand, "", NULL }, + { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterWalkCheatCommand, "", NULL }, + { "taxi", SEC_GAMEMASTER, false, &HandleTaxiCheatCommand, "", NULL }, + { "explore", SEC_GAMEMASTER, false, &HandleExploreCheatCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + + }; + + static ChatCommand commandTable[] = + { + { "cheat", SEC_GAMEMASTER, false, NULL, "", cheatCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleGodModeCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_GOD)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_GOD); + handler->SendSysMessage("Godmode is OFF. You can take damage."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_GOD); + handler->SendSysMessage("Godmode is ON. You won't take damage."); + return true; + } + + return false; + } + + static bool HandleCasttimeCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_CASTTIME)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_CASTTIME); + handler->SendSysMessage("CastTime Cheat is OFF. Your spells will have a casttime."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_CASTTIME); + handler->SendSysMessage("CastTime Cheat is ON. Your spells won't have a casttime."); + return true; + } + + return false; + } + + static bool HandleCoolDownCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_COOLDOWN); + handler->SendSysMessage("Cooldown Cheat is OFF. You are on the global cooldown."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_COOLDOWN); + handler->SendSysMessage("Cooldown Cheat is ON. You are not on the global cooldown."); + return true; + } + + return false; + } + + static bool HandlePowerCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_POWER)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_POWER); + handler->SendSysMessage("Power Cheat is OFF. You need mana/rage/energy to use spells."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_POWER); + handler->SendSysMessage("Power Cheat is ON. You don't need mana/rage/energy to use spells."); + return true; + } + + return false; + } + + static bool HandleWaterWalkCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + { + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on"; + if (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) + argstr = "off"; + else + argstr = "on"; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK); + handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF + handler->SendSysMessage("Waterwalking is OFF. You can't walk on water."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK); + handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON + handler->SendSysMessage("Waterwalking is ON. You can walk on water."); + return true; + } + + return false; + } + + static bool HandleTaxiCheatCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = (char*)args; + + Player* chr = handler->getSelectedPlayer(); + + if (!chr) + chr = handler->GetSession()->GetPlayer(); + else if (handler->HasLowerSecurity(chr, 0)) // check online security + return false; + + if (argstr == "on") + { + chr->SetTaxiCheater(true); + handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); + return true; + } + + if (argstr == "off") + { + chr->SetTaxiCheater(false); + handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); + + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleExploreCheatCommand(ChatHandler* handler, const char *args) + { + if (!*args) + return false; + + int flag = atoi((char*)args); + + Player* chr = handler->getSelectedPlayer(); + if (chr == NULL) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); + } + else + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); + } + + for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + if (flag != 0) + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); + else + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); + } + + return true; + } +}; + +void AddSC_cheat_commandscript() +{ + new cheat_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 1edaaf5bcbf..fa4b0ce3957 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -82,10 +82,8 @@ public: { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, - { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, - { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, @@ -106,7 +104,6 @@ public: { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, - { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, @@ -960,49 +957,6 @@ public: player->CastSpell(player, 7355, false); return true; } - // Enable on\off all taxi paths - static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argStr = (char*)args; - - Player* chr = handler->getSelectedPlayer(); - - if (!chr) - chr = handler->GetSession()->GetPlayer(); - else if (handler->HasLowerSecurity(chr, 0)) // check online security - return false; - - if (argStr == "on") - { - chr->SetTaxiCheater(true); - handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); - return true; - } - - if (argStr == "off") - { - chr->SetTaxiCheater(false); - handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); - - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - - return false; - } static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) { @@ -1123,45 +1077,6 @@ public: return true; } - static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - int32 flag = int32(atoi((char*)args)); - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (flag != 0) - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); - } - else - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); - } - - for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) - { - if (flag != 0) - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); - else - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); - } - - return true; - } - static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) { if (!*args) @@ -2194,39 +2109,6 @@ public: return true; } - static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->getSelectedPlayer(); - if (!player) - { - handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - if (strncmp(args, "on", 3) == 0) - player->SetMovement(MOVE_WATER_WALK); // ON - else if (strncmp(args, "off", 4) == 0) - player->SetMovement(MOVE_LAND_WALK); // OFF - else - { - handler->SendSysMessage(LANG_USE_BOL); - return false; - } - - handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); - return true; - } - // Send mail by command static bool HandleSendMailCommand(ChatHandler* handler, char const* args) { -- cgit v1.2.3 From 6fbe3a11ecc92a9a3acd4e2b05a784a57051f425 Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Fri, 31 Aug 2012 04:15:04 +0300 Subject: DB/SAI: Taking on All Challengers & Defending Your Title --- sql/updates/world/2012_08_31_00_world_sai.sql | 50 ++++++++++++++ src/server/scripts/Northrend/storm_peaks.cpp | 98 --------------------------- 2 files changed, 50 insertions(+), 98 deletions(-) create mode 100644 sql/updates/world/2012_08_31_00_world_sai.sql (limited to 'src') diff --git a/sql/updates/world/2012_08_31_00_world_sai.sql b/sql/updates/world/2012_08_31_00_world_sai.sql new file mode 100644 index 00000000000..fd7e0d7810f --- /dev/null +++ b/sql/updates/world/2012_08_31_00_world_sai.sql @@ -0,0 +1,50 @@ +-- Defending Your Title (13423) +-- Taking on All Challengers (12971) + +SET @NPC_CHALLENGER := 30012; -- Victorious Challenger +SET @QUEST1 := 12971; +SET @QUEST2 := 13423; +SET @GOSSIP_MENUID := 9865; +SET @SPELL_SUNDER := 11971; -- Sunder Armor +SET @SPELL_REND := 11977; -- Rend + +UPDATE `creature_template` SET `faction_A`=2109,`faction_H`=2109,`unit_flags`=0x8000,`npcflag`=0x1,`gossip_menu_id`=@GOSSIP_MENUID,`AIName`='SmartAI',`ScriptName`='' WHERE `entry`=@NPC_CHALLENGER; + +DELETE FROM `creature_template_addon` WHERE `entry`=@NPC_CHALLENGER; +INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`auras`) VALUES +(@NPC_CHALLENGER,0,0x0,0x1,''); + +DELETE FROM `creature_text` WHERE `entry`=@NPC_CHALLENGER; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@NPC_CHALLENGER,0,0,'You will not defeat me!',12,0,100,0,0,0,'Victorious Challenger'), +(@NPC_CHALLENGER,0,1,'You''re not worthy of Thorim!',12,0,100,0,0,0,'Victorious Challenger'), +(@NPC_CHALLENGER,0,2,'Good luck... You''ll need it!',12,0,100,0,0,0,'Victorious Challenger'), +(@NPC_CHALLENGER,0,3,'May the best win!',12,0,100,0,0,0,'Victorious Challenger'); + +DELETE FROM `gossip_menu` WHERE `entry`=@GOSSIP_MENUID; +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES +(@GOSSIP_MENUID,13660); + +DELETE FROM `gossip_menu_option` WHERE `menu_id`=@GOSSIP_MENUID; +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES +(@GOSSIP_MENUID,0,0,'Let''s do this, sister.',1,1,0,0,0,0,''); + +DELETE FROM `creature_equip_template` WHERE `entry`=@NPC_CHALLENGER; +INSERT INTO `creature_equip_template` (`entry`,`itemEntry1`,`itemEntry2`,`itemEntry3`) VALUES +(@NPC_CHALLENGER,40542,39288,0); + +DELETE FROM `smart_scripts` WHERE (`source_type`=0 AND `entryorguid`=@NPC_CHALLENGER) OR (`source_type`=9 AND `entryorguid`=@NPC_CHALLENGER*100); +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@NPC_CHALLENGER,0,0,0,25,0,100,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Victorious Challenger - On Reset - Set Default Faction'), +(@NPC_CHALLENGER,0,1,2,62,0,100,0,@GOSSIP_MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Victorious Challenger - On Gossip - Close Gossip'), +(@NPC_CHALLENGER,0,2,0,61,0,100,0,0,0,0,0,80,@NPC_CHALLENGER*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Victorious Challenger - On Gossip - Run Timed Script'), +(@NPC_CHALLENGER,0,3,0,9,0,100,0,0,5,5000,10000,11,@SPELL_SUNDER,0,0,0,0,0,2,0,0,0,0,0,0,0,'Victorious Challenger - On Range - Cast Sunder Armor'), +(@NPC_CHALLENGER,0,4,0,0,0,100,0,10000,15000,15000,20000,11,@SPELL_REND,0,0,0,0,0,2,0,0,0,0,0,0,0,'Victorious Challenger - IC - Cast Rend'), +(@NPC_CHALLENGER*100,9,0,0,0,0,100,0,1000,1000,1000,1000,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Victorious Challenger - Timed - Talk'), +(@NPC_CHALLENGER*100,9,1,0,0,0,100,0,3000,3000,3000,3000,2,14,0,0,0,0,0,1,0,0,0,0,0,0,0,'Victorious Challenger - Timed - Set Faction Hostile'), +(@NPC_CHALLENGER*100,9,2,0,0,0,100,0,0,0,0,0,49,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Victorious Challenger - Timed - Attack Invoker'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@GOSSIP_MENUID; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,@GOSSIP_MENUID,0,0,0,9,0,@QUEST1,0,0,0,0,'','Show gossip option 0 if player has quest Taking on All Challengers'), +(15,@GOSSIP_MENUID,0,0,1,9,0,@QUEST2,0,0,0,0,'','Show gossip option 0 if player has quest Defending Your Title'); diff --git a/src/server/scripts/Northrend/storm_peaks.cpp b/src/server/scripts/Northrend/storm_peaks.cpp index 6bf342e4643..60c289dc8de 100644 --- a/src/server/scripts/Northrend/storm_peaks.cpp +++ b/src/server/scripts/Northrend/storm_peaks.cpp @@ -194,103 +194,6 @@ public: } }; -/*###### -## npc_victorious_challenger -######*/ - -#define GOSSIP_CHALLENGER "Let's do this, sister." - -enum eVictoriousChallenger -{ - QUEST_TAKING_ALL_CHALLENGERS = 12971, - QUEST_DEFENDING_YOUR_TITLE = 13423, - - SPELL_SUNDER_ARMOR = 11971, - SPELL_REND_VC = 11977 -}; - -class npc_victorious_challenger : public CreatureScript -{ -public: - npc_victorious_challenger() : CreatureScript("npc_victorious_challenger") { } - - struct npc_victorious_challengerAI : public ScriptedAI - { - npc_victorious_challengerAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 SunderArmorTimer; - uint32 RendTimer; - - void Reset() - { - me->RestoreFaction(); - - SunderArmorTimer = 10000; - RendTimer = 15000; - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (RendTimer < diff) - { - DoCast(me->getVictim(), SPELL_REND_VC, true); - RendTimer = 15000; - }else RendTimer -= diff; - - if (SunderArmorTimer < diff) - { - DoCast(me->getVictim(), SPELL_SUNDER_ARMOR, true); - SunderArmorTimer = 10000; - }else SunderArmorTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void KilledUnit(Unit* /*victim*/) - { - me->RestoreFaction(); - } - - }; - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_TAKING_ALL_CHALLENGERS) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_DEFENDING_YOUR_TITLE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CHALLENGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(14); - creature->AI()->AttackStart(player); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_victorious_challengerAI(creature); - } -}; - /*###### ## npc_loklira_crone ######*/ @@ -753,7 +656,6 @@ void AddSC_storm_peaks() new npc_agnetta_tyrsdottar(); new npc_frostborn_scout(); new npc_thorim(); - new npc_victorious_challenger(); new npc_loklira_crone(); new npc_injured_goblin(); new npc_roxi_ramrocket(); -- cgit v1.2.3 From a8d514914be2e88dbae5013a17013adabefcfe74 Mon Sep 17 00:00:00 2001 From: Trista Date: Fri, 31 Aug 2012 14:20:11 +0100 Subject: Core/Scripts: Improve Wyrmrest Defender gossip * Added conditions to only show default gossip, if not on quest 12372 * Else show other gossip text * Add second gossip text on gossip select * Remove close gossip - after a lot of videos turns out character close it by moving or clicking "goodbye" Ref #1861 Closes #7594 --- src/server/scripts/Northrend/dragonblight.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp index b915f4c6304..1f1d24453ee 100644 --- a/src/server/scripts/Northrend/dragonblight.cpp +++ b/src/server/scripts/Northrend/dragonblight.cpp @@ -174,9 +174,12 @@ public: ## wyrmrest_defender ######*/ -enum Spells +enum WyrmDefenderEnum { - SPELL_CHARACTER_SCRIPT = 49213 + QUEST_DEFENDING_WYRMREST_TEMPLE = 12372, + GOSSIP_TEXTID_DEF1 = 12899, + GOSSIP_TEXTID_DEF2 = 12900, + SPELL_CHARACTER_SCRIPT = 49213 }; #define GOSSIP_ITEM_1 "We need to get into the fight. Are you ready?" @@ -187,19 +190,24 @@ class npc_wyrmrest_defender : public CreatureScript npc_wyrmrest_defender() : CreatureScript("npc_wyrmrest_defender") { } bool OnGossipHello(Player* player, Creature* creature) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + { + if (player->GetQuestStatus(QUEST_DEFENDING_WYRMREST_TEMPLE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF1, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); return true; } - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) { player->PlayerTalkClass->ClearMenus(); if (action == GOSSIP_ACTION_INFO_DEF+1) { - player->CLOSE_GOSSIP_MENU(); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF2, creature->GetGUID()); // Makes player cast trigger spell for 49207 on self player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true); } -- cgit v1.2.3 From d7eeebe0f3b9c1256bce900c39e0abcbf9641168 Mon Sep 17 00:00:00 2001 From: kaelima Date: Mon, 3 Sep 2012 20:30:30 +0200 Subject: Core/MMaps: Implement pathed charge effect --- src/server/game/Movement/MotionMaster.cpp | 14 +++++++++++- src/server/game/Movement/MotionMaster.h | 2 ++ .../MovementGenerators/PointMovementGenerator.cpp | 7 ++++-- .../MovementGenerators/PointMovementGenerator.h | 2 +- src/server/game/Movement/PathGenerator.cpp | 7 ++++++ src/server/game/Movement/PathGenerator.h | 13 ++++++----- src/server/game/Spells/Spell.cpp | 20 ++++++++++++++++- src/server/game/Spells/Spell.h | 2 ++ src/server/game/Spells/SpellEffects.cpp | 26 +++++++++++----------- 9 files changed, 69 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 2ad8028ca4f..d7bf433677c 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -340,7 +340,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + M_PI); Movement::MoveSplineInit init(_owner); - init.MoveTo(x,y,z); + init.MoveTo(x, y, z); init.SetParabolic(max_height,0); init.SetOrientationFixed(true); init.SetVelocity(speedXY); @@ -423,6 +423,18 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, } } +void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) +{ + Vector3 dest = path.getActualEndPosition(); + + MoveCharge(dest.x, dest.y, dest.z); + + Movement::MoveSplineInit init(_owner); + init.MovebyPath(path.getPath()); + init.SetVelocity(speed); + init.Launch(); +} + void MotionMaster::MoveSeekAssistance(float x, float y, float z) { if (_owner->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 16accff2ab4..d59ec83e615 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -26,6 +26,7 @@ class MovementGenerator; class Unit; +class PathGenerator; // Creature Entry ID used for waypoints show, visible only for GMs #define VISUAL_WAYPOINT 1 @@ -161,6 +162,7 @@ class MotionMaster //: private std::stack void MoveTakeoff(uint32 id, Position const& pos); void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); + void MoveCharge(PathGenerator path, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 20f1c3a29e9..c022de31869 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -33,7 +33,10 @@ void PointMovementGenerator::Initialize(T* unit) unit->StopMoving(); unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); - i_recalculateSpeed = false; + + if (id == EVENT_CHARGE) + return; + Movement::MoveSplineInit init(unit); init.MoveTo(i_x, i_y, i_z, m_generatePath); if (speed > 0.0f) @@ -55,7 +58,7 @@ bool PointMovementGenerator::Update(T* unit, const uint32& /*diff*/) unit->AddUnitState(UNIT_STATE_ROAMING_MOVE); - if (i_recalculateSpeed && !unit->movespline->Finalized()) + if (id != EVENT_CHARGE && i_recalculateSpeed && !unit->movespline->Finalized()) { i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 4111690627e..e01ced758a3 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -27,7 +27,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG { public: PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), - i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed) {} + i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed), i_recalculateSpeed(false) {} void Initialize(T*); void Finalize(T*); diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 4d7707020e1..a02eb0a9a84 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -456,6 +456,13 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin m_type = PATHFIND_NOPATH; return; } + else if (pointCount == m_pointPathLimit) + { + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, m_pointPathLimit); + BuildShortcut(); + m_type = PATHFIND_SHORT; + return; + } m_pathPoints.resize(pointCount); for (uint32 i = 0; i < pointCount; ++i) diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index a0d925cb11f..ac163f43be5 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -43,12 +43,13 @@ class Unit; enum PathType { - PATHFIND_BLANK = 0x0000, // path not built yet - PATHFIND_NORMAL = 0x0001, // normal path - PATHFIND_SHORTCUT = 0x0002, // travel through obstacles, terrain, air, etc (old behavior) - PATHFIND_INCOMPLETE = 0x0004, // we have partial path to follow - getting closer to target - PATHFIND_NOPATH = 0x0008, // no valid path at all or error in generating one - PATHFIND_NOT_USING_PATH = 0x0010 // used when we are either flying/swiming or on map w/o mmaps + PATHFIND_BLANK = 0x00, // path not built yet + PATHFIND_NORMAL = 0x01, // normal path + PATHFIND_SHORTCUT = 0x02, // travel through obstacles, terrain, air, etc (old behavior) + PATHFIND_INCOMPLETE = 0x04, // we have partial path to follow - getting closer to target + PATHFIND_NOPATH = 0x08, // no valid path at all or error in generating one + PATHFIND_NOT_USING_PATH = 0x10, // used when we are either flying/swiming or on map w/o mmaps + PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length }; class PathGenerator diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 79e6404f73e..6e056bf59f8 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -490,7 +490,7 @@ SpellValue::SpellValue(SpellInfo const* proto) Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID, bool skipCheck) : m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)), m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster) -, m_spellValue(new SpellValue(m_spellInfo)) +, m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster)) { m_customError = SPELL_CUSTOM_ERROR_NONE; m_skipCheck = skipCheck; @@ -610,6 +610,7 @@ Spell::~Spell() if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER) ASSERT(m_caster->ToPlayer()->m_spellModTakingSpell != this); + delete m_spellValue; CheckEffectExecuteData(); @@ -5143,8 +5144,25 @@ SpellCastResult Spell::CheckCast(bool strict) if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953)) m_caster->RemoveMovementImpairingAuras(); } + if (m_caster->HasUnitState(UNIT_STATE_ROOT)) return SPELL_FAILED_ROOTED; + + Unit* target = m_targets.GetUnitTarget(); + + if (!target) + return SPELL_FAILED_DONT_REPORT; + + Position pos; + target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); + target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); + + m_preGeneratedPath.setPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); + m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); + + if (m_preGeneratedPath.getPathType() & PATHFIND_SHORT) + return SPELL_FAILED_OUT_OF_RANGE; + break; } case SPELL_EFFECT_SKINNING: diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 1376b0fbd40..22495b3f1f0 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -23,6 +23,7 @@ #include "SharedDefines.h" #include "ObjectMgr.h" #include "SpellInfo.h" +#include "PathGenerator.h" class Unit; class Player; @@ -666,6 +667,7 @@ class Spell bool m_skipCheck; uint8 m_auraScaleMask; + PathGenerator m_preGeneratedPath; ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3637bb18049..1aa2ca0176b 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -63,6 +63,7 @@ #include "GameObjectAI.h" #include "AccountMgr.h" #include "InstanceScript.h" +#include "PathGenerator.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -5133,25 +5134,24 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) void Spell::EffectCharge(SpellEffIndex /*effIndex*/) { + if (!unitTarget) + return; + if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) { - if (!unitTarget) - return; - - float angle = unitTarget->GetRelativeAngle(m_caster); - Position pos; - - unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); - unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), angle); - - m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + unitTarget->GetObjectSize()); + if (m_preGeneratedPath.getPathType() & PATHFIND_NOPATH) + { + Position pos; + unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); + unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster)); + m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ); + } + else + m_caster->GetMotionMaster()->MoveCharge(m_preGeneratedPath); } if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) { - if (!unitTarget) - return; - // not all charge effects used in negative spells if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->Attack(unitTarget, true); -- cgit v1.2.3 From a9e672ab1d33a3502381d4b33f679a9d1f1f2087 Mon Sep 17 00:00:00 2001 From: kaelima Date: Mon, 3 Sep 2012 20:34:07 +0200 Subject: Core/MMaps: Prevent path generation when falling or exiting vehicle --- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Movement/MotionMaster.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ca8cb4763d7..d610c2e0fb9 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17158,7 +17158,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) } Movement::MoveSplineInit init(this); - init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false); init.SetFacing(GetOrientation()); init.SetTransportExit(); init.Launch(); diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index d7bf433677c..bf938c3af6c 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -399,7 +399,7 @@ void MotionMaster::MoveFall(uint32 id/*=0*/) } Movement::MoveSplineInit init(_owner); - init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz); + init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false); init.SetFall(); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); -- cgit v1.2.3 From 306e4c173c2a2c050af61f8eb511c67496621a60 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 4 Sep 2012 19:58:39 +0100 Subject: Fix a merge failure --- .../game/Movement/MovementGenerators/FleeingMovementGenerator.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 029bc55ab58..acb1a57a9ba 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -47,11 +47,6 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) path.setPathLengthLimit(30.0f); path.CalculatePath(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) - default: - angle = 0.0f; - distance = 0.0f; - break; - { i_nextCheckTime.Reset(urand(1000, 1500)); return; -- cgit v1.2.3 From 69602df83388e89dc473936f08992c48022a73f0 Mon Sep 17 00:00:00 2001 From: kaelima Date: Tue, 4 Sep 2012 23:33:11 +0200 Subject: Core/MMaps: Fix some uninitialized variable complaints in PathGenerator --- src/server/game/Movement/PathGenerator.cpp | 19 ++++++++++--------- src/tools/mmaps_generator/PathGenerator.cpp | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index a02eb0a9a84..62ab0be4630 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -30,7 +30,7 @@ PathGenerator::PathGenerator(const Unit* owner) : m_polyLength(0), m_type(PATHFIND_BLANK), m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), - m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL) + m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL), m_endPosition(Vector3::zero()) { sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", m_sourceUnit->GetGUIDLow()); @@ -52,16 +52,16 @@ PathGenerator::~PathGenerator() bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) { - if (!Trinity::IsValidMapCoord(destX, destY, destZ) || - !Trinity::IsValidMapCoord(m_sourceUnit->GetPositionX(), m_sourceUnit->GetPositionY(), m_sourceUnit->GetPositionZ())) + float x, y, z; + m_sourceUnit->GetPosition(x, y, z); + + if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; Vector3 oldDest = getEndPosition(); Vector3 dest(destX, destY, destZ); setEndPosition(dest); - float x, y, z; - m_sourceUnit->GetPosition(x, y, z); Vector3 start(x, y, z); setStartPosition(start); @@ -84,7 +84,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo // check if destination moved - if not we can optimize something here // we are following old, precalculated path? float dist = m_sourceUnit->GetObjectSize(); - if (inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) + if (oldDest != Vector3::zero() && inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride @@ -192,7 +192,7 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos if (waterPath) { // Check both start and end points, if they're both in water, then we can *safely* let the creature move - for (int i = 0; i < m_pathPoints.size(); ++i) + for (uint32 i = 0; i < m_pathPoints.size(); ++i) { LiquidData data; m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); @@ -277,11 +277,12 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // TODO: we can merge it with getPathPolyByPosition() loop bool startPolyFound = false; bool endPolyFound = false; - uint32 pathStartIndex, pathEndIndex; + uint32 pathStartIndex = 0; + uint32 pathEndIndex = 0; if (m_polyLength) { - for (pathStartIndex = 0; pathStartIndex < m_polyLength; ++pathStartIndex) + for (; pathStartIndex < m_polyLength; ++pathStartIndex) { // here to carch few bugs ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 026bf957ec4..9707cb4160a 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -26,14 +26,14 @@ bool checkDirectories(bool debugOutput) { vector dirFiles; - if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'maps' directory is empty or does not exist\n"); return false; } dirFiles.clear(); - if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || !dirFiles.size()) + if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'vmaps' directory is empty or does not exist\n"); return false; -- cgit v1.2.3 From c2f446ded917efed58c8054693858b3c4b4c4a8f Mon Sep 17 00:00:00 2001 From: kaelima Date: Wed, 5 Sep 2012 17:07:47 +0200 Subject: Core/MMaps: Minor warning fix --- src/server/game/Movement/PathGenerator.cpp | 13 ++++++------- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 62ab0be4630..c9cfff08ede 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -591,8 +591,7 @@ bool PathGenerator::HaveTile(const Vector3 &p) const return (m_navMesh->getTileAt(tx, ty) != NULL); } -uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, - const dtPolyRef* visited, uint32 nvisited) +uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) { int32 furthestPath = -1; int32 furthestVisited = -1; @@ -622,17 +621,17 @@ uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPat // Adjust beginning of the buffer to include the visited. uint32 req = nvisited - furthestVisited; - uint32 orig = uint32(furthestPath+1) < npath ? furthestPath+1 : npath; - uint32 size = npath-orig > 0 ? npath-orig : 0; - if (req+size > maxPath) + uint32 orig = uint32(furthestPath + 1) < npath ? furthestPath + 1 : npath; + uint32 size = npath > orig ? npath - orig : 0; + if (req + size > maxPath) size = maxPath-req; if (size) - memmove(path+req, path+orig, size*sizeof(dtPolyRef)); + memmove(path + req, path + orig, size * sizeof(dtPolyRef)); // Store visited for (uint32 i = 0; i < req; ++i) - path[i] = visited[(nvisited-1)-i]; + path[i] = visited[(nvisited - 1) - i]; return req+size; } diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 2a74233a1a7..69ffad94eb7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -564,10 +564,10 @@ namespace MMAP Tile& tile = tiles[x + y * TILES_PER_MAP]; // Calculate the per tile bounding box. - tileCfg.bmin[0] = config.bmin[0] + (x*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmin[2] = config.bmin[2] + (y*config.tileSize - config.borderSize)*config.cs; - tileCfg.bmax[0] = config.bmin[0] + ((x+1)*config.tileSize + config.borderSize)*config.cs; - tileCfg.bmax[2] = config.bmin[2] + ((y+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmin[0] = config.bmin[0] + float(x*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmin[2] = config.bmin[2] + float(y*config.tileSize - config.borderSize)*config.cs; + tileCfg.bmax[0] = config.bmin[0] + float((x+1)*config.tileSize + config.borderSize)*config.cs; + tileCfg.bmax[2] = config.bmin[2] + float((y+1)*config.tileSize + config.borderSize)*config.cs; // build heightfield tile.solid = rcAllocHeightfield(); @@ -633,7 +633,7 @@ namespace MMAP } tile.dmesh = rcAllocPolyMeshDetail(); - if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh)) { printf("%s Failed building polymesh detail! \n", tileString); continue; -- cgit v1.2.3 From 593f08609fa474c9aa881898e23e256e6e55c06e Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 5 Sep 2012 15:32:35 -0500 Subject: Core/Mmaps: Fixed a mistake in BuildPolyPath which could cause swimming creatures to bug in the navmesh generation. --- src/server/game/Movement/PathGenerator.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index c9cfff08ede..00aa8043312 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -194,10 +194,9 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // Check both start and end points, if they're both in water, then we can *safely* let the creature move for (uint32 i = 0; i < m_pathPoints.size(); ++i) { - LiquidData data; - m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, &data); + ZLiquidStatus status = m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); // One of the points is not in the water, cancel movement. - if (data.type_flags == MAP_LIQUID_TYPE_NO_WATER) + if (status == LIQUID_MAP_NO_WATER) { waterPath = false; break; -- cgit v1.2.3 From ccdca7774023e7570f17cf15456384b316322420 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 5 Sep 2012 16:05:26 -0500 Subject: Core/Mmaps: Fixed unloading mmap tiles, the x and y were swapped. thanks to MaNGOS for original implementation, and thanks to @Chevron for noticing. --- src/server/collision/Management/MMapManager.cpp | 24 ++++++++++++------------ src/server/game/Maps/Map.cpp | 4 +--- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 0222f1a5995..8e6e2a3b6b4 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -100,8 +100,8 @@ namespace MMAP // load this tile :: mmaps/MMMXXYY.mmtile uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1; char *fileName = new char[pathLen]; - // this change of y and x is needed because of mapbuilder.cpp (x and y are swapped there) so change it here so we dont need to re-extract. All swappes are done in other files. DONT CHANGE THIS! - snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, y, x); + + snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y); FILE *file = fopen(fileName, "rb"); if (!file) @@ -118,7 +118,7 @@ namespace MMAP if (fileHeader.mmapMagic != MMAP_MAGIC) { - sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); return false; } @@ -135,7 +135,7 @@ namespace MMAP size_t result = fread(data, fileHeader.size, 1, file); if (!result) { - sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y); fclose(file); return false; } @@ -150,12 +150,12 @@ namespace MMAP { mmap->mmapLoadedTiles.insert(std::pair(packedGridPos, tileRef)); ++loadedTiles; - sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, y, x, mapId, header->x, header->y); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y); return true; } else { - sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); dtFree(data); return false; } @@ -169,7 +169,7 @@ namespace MMAP if (loadedMMaps.find(mapId) == loadedMMaps.end()) { // file may not exist, therefore not loaded - sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, y, x); + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y); return false; } @@ -180,7 +180,7 @@ namespace MMAP if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end()) { // file may not exist, therefore not loaded - sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, y, x); + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y); return false; } @@ -192,14 +192,14 @@ namespace MMAP // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used // we cannot recover from this error - assert out - sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); ASSERT(false); } else { mmap->mmapLoadedTiles.erase(packedGridPos); --loadedTiles; - sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId); return true; } @@ -222,11 +222,11 @@ namespace MMAP uint32 x = (i->first >> 16); uint32 y = (i->first & 0x0000FFFF); if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL)) - sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, y, x); + sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); else { --loadedTiles; - sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, y, x, mapId); + sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId); } } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index af139568ece..7e5a2ebb220 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -123,8 +123,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { - // DONT CHANGE "gy" and "gx" - Its necessary ! - bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gy, gx); + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); if (mmapLoadResult) sLog->outInfo(LOG_FILTER_MAPS, "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); @@ -1011,7 +1010,6 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) GridMaps[gx][gy]->unloadData(); delete GridMaps[gx][gy]; } - // x and y are swapped VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gx, gy); MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId(), gx, gy); } -- cgit v1.2.3 From e7c0d8bef023a0b948602e2fc6b31fc68a120ac4 Mon Sep 17 00:00:00 2001 From: Venugh Date: Wed, 5 Sep 2012 23:47:02 +0200 Subject: Core/MMaps: Applied Trinity Codestyle to PathGenerator. --- src/server/game/Movement/MotionMaster.cpp | 4 +- .../ConfusedMovementGenerator.cpp | 6 +- .../FleeingMovementGenerator.cpp | 6 +- .../TargetedMovementGenerator.cpp | 4 +- src/server/game/Movement/PathGenerator.cpp | 307 ++++++++++----------- src/server/game/Movement/PathGenerator.h | 91 +++--- src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 +- src/server/game/Spells/Spell.cpp | 4 +- src/server/game/Spells/SpellEffects.cpp | 2 +- 9 files changed, 211 insertions(+), 215 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index bf938c3af6c..34be779a8b7 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -425,12 +425,12 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) { - Vector3 dest = path.getActualEndPosition(); + Vector3 dest = path.GetActualEndPosition(); MoveCharge(dest.x, dest.y, dest.z); Movement::MoveSplineInit init(_owner); - init.MovebyPath(path.getPath()); + init.MovebyPath(path.GetPath()); init.SetVelocity(speed); init.Launch(); } diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index f1d1d8cf04a..32c6ec3858d 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -77,16 +77,16 @@ bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) unit->UpdateAllowedPositionZ(x, y, z); PathGenerator path(unit); - path.setPathLengthLimit(30.0f); + path.SetPathLengthLimit(30.0f); path.CalculatePath(x, y, z); - if (path.getPathType() & PATHFIND_NOPATH) + if (path.GetPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); return true; } Movement::MoveSplineInit init(unit); - init.MovebyPath(path.getPath()); + init.MovebyPath(path.GetPath()); init.SetWalk(true); init.Launch(); } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index acb1a57a9ba..8f4d78b34b1 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -44,16 +44,16 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); PathGenerator path(owner); - path.setPathLengthLimit(30.0f); + path.SetPathLengthLimit(30.0f); path.CalculatePath(x, y, z); - if (path.getPathType() & PATHFIND_NOPATH) + if (path.GetPathType() & PATHFIND_NOPATH) { i_nextCheckTime.Reset(urand(1000, 1500)); return; } Movement::MoveSplineInit init(owner); - init.MovebyPath(path.getPath()); + init.MovebyPath(path.GetPath()); init.SetWalk(false); int32 traveltime = init.Launch(); i_nextCheckTime.Reset(traveltime + urand(800, 1500)); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 9784c19b4fd..4a8d15b8079 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -70,7 +70,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)); i_path->CalculatePath(x, y, z, forceDest); - if (i_path->getPathType() & PATHFIND_NOPATH) + if (i_path->GetPathType() & PATHFIND_NOPATH) return; D::_addUnitStateMove(owner); @@ -79,7 +79,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) owner->AddUnitState(UNIT_STATE_CHASE); Movement::MoveSplineInit init(owner); - init.MovebyPath(i_path->getPath()); + init.MovebyPath(i_path->GetPath()); init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 00aa8043312..165cc282e3a 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -28,69 +28,69 @@ ////////////////// PathGenerator ////////////////// PathGenerator::PathGenerator(const Unit* owner) : - m_polyLength(0), m_type(PATHFIND_BLANK), - m_useStraightPath(false), m_forceDestination(false), m_pointPathLimit(MAX_POINT_PATH_LENGTH), - m_sourceUnit(owner), m_navMesh(NULL), m_navMeshQuery(NULL), m_endPosition(Vector3::zero()) + _polyLength(0), _type(PATHFIND_BLANK), + _useStraightPath(false), _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), + _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL), _endPosition(Vector3::zero()) { - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", m_sourceUnit->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); - uint32 mapId = m_sourceUnit->GetMapId(); + uint32 mapId = _sourceUnit->GetMapId(); if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); - m_navMesh = mmap->GetNavMesh(mapId); - m_navMeshQuery = mmap->GetNavMeshQuery(mapId, m_sourceUnit->GetInstanceId()); + _navMesh = mmap->GetNavMesh(mapId); + _navMeshQuery = mmap->GetNavMeshQuery(mapId, _sourceUnit->GetInstanceId()); } - createFilter(); + CreateFilter(); } PathGenerator::~PathGenerator() { - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::~PathGenerator() for %u \n", m_sourceUnit->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow()); } bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest) { float x, y, z; - m_sourceUnit->GetPosition(x, y, z); + _sourceUnit->GetPosition(x, y, z); if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; - Vector3 oldDest = getEndPosition(); + Vector3 oldDest = GetEndPosition(); Vector3 dest(destX, destY, destZ); - setEndPosition(dest); + SetEndPosition(dest); Vector3 start(x, y, z); - setStartPosition(start); + SetStartPosition(start); - m_forceDestination = forceDest; + _forceDestination = forceDest; - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath() for %u \n", m_sourceUnit->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow()); // make sure navMesh works - we can run on map w/o mmap // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) - if (!m_navMesh || !m_navMeshQuery || m_sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || + if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) || !HaveTile(start) || !HaveTile(dest)) { BuildShortcut(); - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); return true; } - updateFilter(); + UpdateFilter(); // check if destination moved - if not we can optimize something here // we are following old, precalculated path? - float dist = m_sourceUnit->GetObjectSize(); - if (oldDest != Vector3::zero() && inRange(oldDest, dest, dist, dist) && m_pathPoints.size() > 2) + float dist = _sourceUnit->GetObjectSize(); + if (oldDest != Vector3::zero() && InRange(oldDest, dest, dist, dist) && _pathPoints.size() > 2) { // our target is not moving - we just coming closer // we are moving on precalculated path - enjoy the ride sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath:: precalculated path\n"); - m_pathPoints.erase(m_pathPoints.begin()); + _pathPoints.erase(_pathPoints.begin()); return false; } else @@ -101,7 +101,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo } } -dtPolyRef PathGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance) const +dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* point, float* distance) const { if (!polyPath || !polyPathSize) return INVALID_POLYREF; @@ -113,7 +113,7 @@ dtPolyRef PathGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 for (uint32 i = 0; i < polyPathSize; ++i) { float closestPoint[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)) + if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)) continue; float d = dtVdist2DSqr(point, closestPoint); @@ -134,12 +134,12 @@ dtPolyRef PathGenerator::getPathPolyByPosition(const dtPolyRef *polyPath, uint32 return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF; } -dtPolyRef PathGenerator::getPolyByLocation(const float* point, float *distance) const +dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance) const { // first we check the current path // if the current path doesn't contain the current poly, // we need to use the expensive navMesh.findNearestPoly - dtPolyRef polyRef = getPathPolyByPosition(m_pathPolyRefs, m_polyLength, point, distance); + dtPolyRef polyRef = GetPathPolyByPosition(_pathPolyRefs, _polyLength, point, distance); if (polyRef != INVALID_POLYREF) return polyRef; @@ -148,7 +148,7 @@ dtPolyRef PathGenerator::getPolyByLocation(const float* point, float *distance) // first try with low search box float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f}; - dtStatus result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + dtStatus result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint); if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) { *distance = dtVdist(closestPoint, point); @@ -158,7 +158,7 @@ dtPolyRef PathGenerator::getPolyByLocation(const float* point, float *distance) // still nothing .. // try with bigger search box extents[1] = 200.0f; - result = m_navMeshQuery->findNearestPoly(point, extents, &m_filter, &polyRef, closestPoint); + result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint); if (DT_SUCCESS == result && polyRef != INVALID_POLYREF) { *distance = dtVdist(closestPoint, point); @@ -168,7 +168,7 @@ dtPolyRef PathGenerator::getPolyByLocation(const float* point, float *distance) return INVALID_POLYREF; } -void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos) +void PathGenerator::BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos) { // *** getting start/end poly logic *** @@ -176,8 +176,8 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x}; float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x}; - dtPolyRef startPoly = getPolyByLocation(startPoint, &distToStartPoly); - dtPolyRef endPoly = getPolyByLocation(endPoint, &distToEndPoly); + dtPolyRef startPoly = GetPolyByLocation(startPoint, &distToStartPoly); + dtPolyRef endPoly = GetPolyByLocation(endPoint, &distToEndPoly); // we have a hole in our mesh // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) @@ -186,15 +186,15 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n"); BuildShortcut(); - bool path = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->CanFly(); + bool path = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanFly(); - bool waterPath = m_sourceUnit->GetTypeId() == TYPEID_UNIT && m_sourceUnit->ToCreature()->canSwim(); + bool waterPath = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->canSwim(); if (waterPath) { // Check both start and end points, if they're both in water, then we can *safely* let the creature move - for (uint32 i = 0; i < m_pathPoints.size(); ++i) + for (uint32 i = 0; i < _pathPoints.size(); ++i) { - ZLiquidStatus status = m_sourceUnit->GetBaseMap()->getLiquidStatus(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); + ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); // One of the points is not in the water, cancel movement. if (status == LIQUID_MAP_NO_WATER) { @@ -204,7 +204,7 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos } } - m_type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; + _type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH; return; } @@ -215,12 +215,12 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly); bool buildShotrcut = false; - if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + if (_sourceUnit->GetTypeId() == TYPEID_UNIT) { - Creature* owner = (Creature*)m_sourceUnit; + Creature* owner = (Creature*)_sourceUnit; Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos; - if (m_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) + if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n"); if (owner->canSwim()) @@ -237,20 +237,20 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos if (buildShotrcut) { BuildShortcut(); - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); return; } else { float closestPoint[VERTEX_SIZE]; // we may want to use closestPointOnPolyBoundary instead - if (DT_SUCCESS == m_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)) + if (DT_SUCCESS == _navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)) { dtVcopy(endPoint, closestPoint); - setActualEndPosition(Vector3(endPoint[2],endPoint[0],endPoint[1])); + SetActualEndPosition(Vector3(endPoint[2], endPoint[0], endPoint[1])); } - m_type = PATHFIND_INCOMPLETE; + _type = PATHFIND_INCOMPLETE; } } @@ -264,11 +264,11 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos BuildShortcut(); - m_pathPolyRefs[0] = startPoly; - m_polyLength = 1; + _pathPolyRefs[0] = startPoly; + _polyLength = 1; - m_type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; - sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", m_type); + _type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; + sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", _type); return; } @@ -279,22 +279,22 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos uint32 pathStartIndex = 0; uint32 pathEndIndex = 0; - if (m_polyLength) + if (_polyLength) { - for (; pathStartIndex < m_polyLength; ++pathStartIndex) + for (; pathStartIndex < _polyLength; ++pathStartIndex) { // here to carch few bugs - ASSERT(m_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); + ASSERT(_pathPolyRefs[pathStartIndex] != INVALID_POLYREF); - if (m_pathPolyRefs[pathStartIndex] == startPoly) + if (_pathPolyRefs[pathStartIndex] == startPoly) { startPolyFound = true; break; } } - for (pathEndIndex = m_polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) - if (m_pathPolyRefs[pathEndIndex] == endPoly) + for (pathEndIndex = _polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex) + if (_pathPolyRefs[pathEndIndex] == endPoly) { endPolyFound = true; break; @@ -309,8 +309,8 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // our path is a simple subpath case, we have all the data we need // just "cut" it out - m_polyLength = pathEndIndex - pathStartIndex + 1; - memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, m_polyLength*sizeof(dtPolyRef)); + _polyLength = pathEndIndex - pathStartIndex + 1; + memmove(_pathPolyRefs, _pathPolyRefs + pathStartIndex, _polyLength * sizeof(dtPolyRef)); } else if (startPolyFound && !endPolyFound) { @@ -319,7 +319,7 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // we are moving on the old path but target moved out // so we have atleast part of poly-path ready - m_polyLength -= pathStartIndex; + _polyLength -= pathStartIndex; // try to adjust the suffix of the path instead of recalculating entire length // at given interval the target cannot get too far from its last location @@ -328,37 +328,37 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // take ~80% of the original length // TODO : play with the values here - uint32 prefixPolyLength = uint32(m_polyLength*0.8f + 0.5f); - memmove(m_pathPolyRefs, m_pathPolyRefs+pathStartIndex, prefixPolyLength*sizeof(dtPolyRef)); + uint32 prefixPolyLength = uint32(_polyLength * 0.8f + 0.5f); + memmove(_pathPolyRefs, _pathPolyRefs+pathStartIndex, prefixPolyLength * sizeof(dtPolyRef)); - dtPolyRef suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; + dtPolyRef suffixStartPoly = _pathPolyRefs[prefixPolyLength-1]; // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data float suffixEndPoint[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) { // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that // try to recover by using prev polyref --prefixPolyLength; - suffixStartPoly = m_pathPolyRefs[prefixPolyLength-1]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) + suffixStartPoly = _pathPolyRefs[prefixPolyLength-1]; + if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)) { // suffixStartPoly is still invalid, error state BuildShortcut(); - m_type = PATHFIND_NOPATH; + _type = PATHFIND_NOPATH; return; } } // generate suffix uint32 suffixPolyLength = 0; - dtStatus dtResult = m_navMeshQuery->findPath( + dtStatus dtResult = _navMeshQuery->findPath( suffixStartPoly, // start polygon endPoly, // end polygon suffixEndPoint, // start position endPoint, // end position - &m_filter, // polygon search filter - m_pathPolyRefs + prefixPolyLength - 1, // [out] path + &_filter, // polygon search filter + _pathPolyRefs + prefixPolyLength - 1, // [out] path (int*)&suffixPolyLength, MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path @@ -367,13 +367,13 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix - sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); } - sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n",m_polyLength, prefixPolyLength, suffixPolyLength); + sLog->outDebug(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n", _polyLength, prefixPolyLength, suffixPolyLength); // new path = prefix + suffix - overlap - m_polyLength = prefixPolyLength + suffixPolyLength - 1; + _polyLength = prefixPolyLength + suffixPolyLength - 1; } else { @@ -384,33 +384,33 @@ void PathGenerator::BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos // just generate new path // free and invalidate old path data - clear(); + Clear(); - dtStatus dtResult = m_navMeshQuery->findPath( + dtStatus dtResult = _navMeshQuery->findPath( startPoly, // start polygon endPoly, // end polygon startPoint, // start position endPoint, // end position - &m_filter, // polygon search filter - m_pathPolyRefs, // [out] path - (int*)&m_polyLength, + &_filter, // polygon search filter + _pathPolyRefs, // [out] path + (int*)&_polyLength, MAX_PATH_LENGTH); // max number of polygons in output path - if (!m_polyLength || dtResult != DT_SUCCESS) + if (!_polyLength || dtResult != DT_SUCCESS) { // only happens if we passed bad data to findPath(), or navmesh is messed up - sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", m_sourceUnit->GetGUIDLow()); + sLog->outError(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); BuildShortcut(); - m_type = PATHFIND_NOPATH; + _type = PATHFIND_NOPATH; return; } } // by now we know what type of path we can get - if (m_pathPolyRefs[m_polyLength - 1] == endPoly && !(m_type & PATHFIND_INCOMPLETE)) - m_type = PATHFIND_NORMAL; + if (_pathPolyRefs[_polyLength - 1] == endPoly && !(_type & PATHFIND_INCOMPLETE)) + _type = PATHFIND_NORMAL; else - m_type = PATHFIND_INCOMPLETE; + _type = PATHFIND_INCOMPLETE; // generate the point-path out of our up-to-date poly-path BuildPointPath(startPoint, endPoint); @@ -421,29 +421,29 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE]; uint32 pointCount = 0; dtStatus dtResult = DT_FAILURE; - if (m_useStraightPath) + if (_useStraightPath) { - dtResult = m_navMeshQuery->findStraightPath( + dtResult = _navMeshQuery->findStraightPath( startPoint, // start position endPoint, // end position - m_pathPolyRefs, // current path - m_polyLength, // lenth of current path + _pathPolyRefs, // current path + _polyLength, // lenth of current path pathPoints, // [out] path corner points NULL, // [out] flags NULL, // [out] shortened path (int*)&pointCount, - m_pointPathLimit); // maximum number of points/polygons to use + _pointPathLimit); // maximum number of points/polygons to use } else { - dtResult = findSmoothPath( + dtResult = FindSmoothPath( startPoint, // start position endPoint, // end position - m_pathPolyRefs, // current path - m_polyLength, // length of current path + _pathPolyRefs, // current path + _polyLength, // length of current path pathPoints, // [out] path corner points (int*)&pointCount, - m_pointPathLimit); // maximum number of points + _pointPathLimit); // maximum number of points } if (pointCount < 2 || dtResult != DT_SUCCESS) @@ -453,81 +453,80 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin // TODO : check the exact cases sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount); BuildShortcut(); - m_type = PATHFIND_NOPATH; + _type = PATHFIND_NOPATH; return; } - else if (pointCount == m_pointPathLimit) + else if (pointCount == _pointPathLimit) { - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, m_pointPathLimit); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, _pointPathLimit); BuildShortcut(); - m_type = PATHFIND_SHORT; + _type = PATHFIND_SHORT; return; } - m_pathPoints.resize(pointCount); + _pathPoints.resize(pointCount); for (uint32 i = 0; i < pointCount; ++i) - m_pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); + _pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); NormalizePath(); // first point is always our current location - we need the next one - setActualEndPosition(m_pathPoints[pointCount-1]); + SetActualEndPosition(_pathPoints[pointCount-1]); // force the given destination, if needed - if(m_forceDestination && - (!(m_type & PATHFIND_NORMAL) || !inRange(getEndPosition(), getActualEndPosition(), 1.0f, 1.0f))) + if (_forceDestination && + (!(_type & PATHFIND_NORMAL) || !InRange(GetEndPosition(), GetActualEndPosition(), 1.0f, 1.0f))) { // we may want to keep partial subpath - if(dist3DSqr(getActualEndPosition(), getEndPosition()) < - 0.3f * dist3DSqr(getStartPosition(), getEndPosition())) + if (Dist3DSqr(GetActualEndPosition(), GetEndPosition()) < 0.3f * Dist3DSqr(GetStartPosition(), GetEndPosition())) { - setActualEndPosition(getEndPosition()); - m_pathPoints[m_pathPoints.size()-1] = getEndPosition(); + SetActualEndPosition(GetEndPosition()); + _pathPoints[_pathPoints.size()-1] = GetEndPosition(); } else { - setActualEndPosition(getEndPosition()); + SetActualEndPosition(GetEndPosition()); BuildShortcut(); } - m_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); } - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", m_type, pointCount, m_polyLength); + sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", _type, pointCount, _polyLength); } void PathGenerator::NormalizePath() { - for (uint32 i = 0; i < m_pathPoints.size(); ++i) - m_sourceUnit->UpdateAllowedPositionZ(m_pathPoints[i].x, m_pathPoints[i].y, m_pathPoints[i].z); + for (uint32 i = 0; i < _pathPoints.size(); ++i) + _sourceUnit->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z); } void PathGenerator::BuildShortcut() { sLog->outDebug(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n"); - clear(); + Clear(); // make two point path, our curr pos is the start, and dest is the end - m_pathPoints.resize(2); + _pathPoints.resize(2); // set start and a default next position - m_pathPoints[0] = getStartPosition(); - m_pathPoints[1] = getActualEndPosition(); + _pathPoints[0] = GetStartPosition(); + _pathPoints[1] = GetActualEndPosition(); NormalizePath(); - m_type = PATHFIND_SHORTCUT; + _type = PATHFIND_SHORTCUT; } -void PathGenerator::createFilter() +void PathGenerator::CreateFilter() { uint16 includeFlags = 0; uint16 excludeFlags = 0; - if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) + if (_sourceUnit->GetTypeId() == TYPEID_UNIT) { - Creature* creature = (Creature*)m_sourceUnit; + Creature* creature = (Creature*)_sourceUnit; if (creature->canWalk()) includeFlags |= NAV_GROUND; // walk @@ -535,37 +534,37 @@ void PathGenerator::createFilter() if (creature->canSwim()) includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim } - else if (m_sourceUnit->GetTypeId() == TYPEID_PLAYER) + else if (_sourceUnit->GetTypeId() == TYPEID_PLAYER) { // perfect support not possible, just stay 'safe' includeFlags |= (NAV_GROUND | NAV_WATER); } - m_filter.setIncludeFlags(includeFlags); - m_filter.setExcludeFlags(excludeFlags); + _filter.setIncludeFlags(includeFlags); + _filter.setExcludeFlags(excludeFlags); - updateFilter(); + UpdateFilter(); } -void PathGenerator::updateFilter() +void PathGenerator::UpdateFilter() { // allow creatures to cheat and use different movement types if they are moved // forcefully into terrain they can't normally move in - if (m_sourceUnit->IsInWater() || m_sourceUnit->IsUnderWater()) + if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater()) { - uint16 includedFlags = m_filter.getIncludeFlags(); - includedFlags |= getNavTerrain(m_sourceUnit->GetPositionX(), - m_sourceUnit->GetPositionY(), - m_sourceUnit->GetPositionZ()); + uint16 includedFlags = _filter.getIncludeFlags(); + includedFlags |= GetNavTerrain(_sourceUnit->GetPositionX(), + _sourceUnit->GetPositionY(), + _sourceUnit->GetPositionZ()); - m_filter.setIncludeFlags(includedFlags); + _filter.setIncludeFlags(includedFlags); } } -NavTerrain PathGenerator::getNavTerrain(float x, float y, float z) +NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) { LiquidData data; - m_sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); + _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); switch (data.type_flags) { @@ -581,16 +580,16 @@ NavTerrain PathGenerator::getNavTerrain(float x, float y, float z) } } -bool PathGenerator::HaveTile(const Vector3 &p) const +bool PathGenerator::HaveTile(Vector3 const& p) const { int tx, ty; float point[VERTEX_SIZE] = {p.y, p.z, p.x}; - m_navMesh->calcTileLoc(point, &tx, &ty); - return (m_navMesh->getTileAt(tx, ty) != NULL); + _navMesh->calcTileLoc(point, &tx, &ty); + return (_navMesh->getTileAt(tx, ty) != NULL); } -uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) +uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) { int32 furthestPath = -1; int32 furthestVisited = -1; @@ -635,8 +634,8 @@ uint32 PathGenerator::fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPat return req+size; } -bool PathGenerator::getSteerTarget(const float* startPos, const float* endPos, - float minTargetDist, const dtPolyRef* path, uint32 pathSize, +bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos, + float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef) { // Find steer target. @@ -645,7 +644,7 @@ bool PathGenerator::getSteerTarget(const float* startPos, const float* endPos, unsigned char steerPathFlags[MAX_STEER_POINTS]; dtPolyRef steerPathPolys[MAX_STEER_POINTS]; uint32 nsteerPath = 0; - dtStatus dtResult = m_navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, + dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize, steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS); if (!nsteerPath || DT_SUCCESS != dtResult) return false; @@ -656,7 +655,7 @@ bool PathGenerator::getSteerTarget(const float* startPos, const float* endPos, { // Stop at Off-Mesh link or when point is further than slop away. if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) || - !inRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) + !InRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f)) break; ns++; } @@ -672,8 +671,8 @@ bool PathGenerator::getSteerTarget(const float* startPos, const float* endPos, return true; } -dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPos, - const dtPolyRef* polyPath, uint32 polyPathSize, +dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPos, + dtPolyRef const* polyPath, uint32 polyPathSize, float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize) { *smoothPathSize = 0; @@ -684,10 +683,10 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo uint32 npolys = polyPathSize; float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)) + if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)) return DT_FAILURE; - if (DT_SUCCESS != m_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)) + if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)) return DT_FAILURE; dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); @@ -702,7 +701,7 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo unsigned char steerPosFlag; dtPolyRef steerPosRef = INVALID_POLYREF; - if (!getSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) + if (!GetSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef)) break; bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END); @@ -727,15 +726,15 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo dtPolyRef visited[MAX_VISIT_POLY]; uint32 nvisited = 0; - m_navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); - npolys = fixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); + _navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY); + npolys = FixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited); - m_navMeshQuery->getPolyHeight(polys[0], result, &result[1]); + _navMeshQuery->getPolyHeight(polys[0], result, &result[1]); result[1] += 0.5f; dtVcopy(iterPos, result); // Handle end of path and off-mesh links when close enough. - if (endOfPath && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + if (endOfPath && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) { // Reached end of path. dtVcopy(iterPos, targetPos); @@ -746,7 +745,7 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo } break; } - else if (offMeshConnection && inRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) + else if (offMeshConnection && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f)) { // Advance the path up to and over the off-mesh connection. dtPolyRef prevRef = INVALID_POLYREF; @@ -766,7 +765,7 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo // Handle the connection. float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; - if (DT_SUCCESS == m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) + if (DT_SUCCESS == _navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) { if (nsmoothPath < maxSmoothPathSize) { @@ -775,7 +774,7 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo } // Move position at the other side of the off-mesh link. dtVcopy(iterPos, endPos); - m_navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); + _navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); iterPos[1] += 0.5f; } } @@ -794,21 +793,21 @@ dtStatus PathGenerator::findSmoothPath(const float* startPos, const float* endPo return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; } -bool PathGenerator::inRangeYZX(const float* v1, const float* v2, float r, float h) const +bool PathGenerator::InRangeYZX(const float* v1, const float* v2, float r, float h) const { const float dx = v2[0] - v1[0]; const float dy = v2[1] - v1[1]; // elevation const float dz = v2[2] - v1[2]; - return (dx*dx + dz*dz) < r*r && fabsf(dy) < h; + return (dx * dx + dz * dz) < r * r && fabsf(dy) < h; } -bool PathGenerator::inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const +bool PathGenerator::InRange(Vector3 const& p1, Vector3 const& p2, float r, float h) const { - Vector3 d = p1-p2; - return (d.x*d.x + d.y*d.y) < r*r && fabsf(d.z) < h; + Vector3 d = p1 - p2; + return (d.x * d.x + d.y * d.y) < r * r && fabsf(d.z) < h; } -float PathGenerator::dist3DSqr(const Vector3 &p1, const Vector3 &p2) const +float PathGenerator::Dist3DSqr(Vector3 const& p1, Vector3 const& p2) const { - return (p1-p2).squaredLength(); + return (p1 - p2).squaredLength(); } diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index ac163f43be5..a20f900b584 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _PATH_INFO_H -#define _PATH_INFO_H +#ifndef _PATH_GENERATOR_H +#define _PATH_GENERATOR_H #include "SharedDefines.h" #include "DetourNavMesh.h" @@ -63,75 +63,72 @@ class PathGenerator bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); // option setters - use optional - void SetUseStraightPath(bool useStraightPath) { m_useStraightPath = useStraightPath; }; - void setPathLengthLimit(float distance) { m_pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; + void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }; + void SetPathLengthLimit(float distance) { _pointPathLimit = std::min(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }; // result getters - Vector3 getStartPosition() const { return m_startPosition; } - Vector3 getEndPosition() const { return m_endPosition; } - Vector3 getActualEndPosition() const { return m_actualEndPosition; } + Vector3 const& GetStartPosition() const { return _startPosition; } + Vector3 const& GetEndPosition() const { return _endPosition; } + Vector3 const& GetActualEndPosition() const { return _actualEndPosition; } - PointsArray& getPath() { return m_pathPoints; } - PathType getPathType() const { return m_type; } + PointsArray& GetPath() { return _pathPoints; } + PathType GetPathType() const { return _type; } private: - dtPolyRef m_pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references - uint32 m_polyLength; // number of polygons in the path + dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references + uint32 _polyLength; // number of polygons in the path - PointsArray m_pathPoints; // our actual (x,y,z) path to the target - PathType m_type; // tells what kind of path this is + PointsArray _pathPoints; // our actual (x,y,z) path to the target + PathType _type; // tells what kind of path this is - bool m_useStraightPath; // type of path will be generated - bool m_forceDestination; // when set, we will always arrive at given point - uint32 m_pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) + bool _useStraightPath; // type of path will be generated + bool _forceDestination; // when set, we will always arrive at given point + uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH) - Vector3 m_startPosition; // {x, y, z} of current location - Vector3 m_endPosition; // {x, y, z} of the destination - Vector3 m_actualEndPosition;// {x, y, z} of the closest possible point to given destination + Vector3 _startPosition; // {x, y, z} of current location + Vector3 _endPosition; // {x, y, z} of the destination + Vector3 _actualEndPosition;// {x, y, z} of the closest possible point to given destination - const Unit* const m_sourceUnit; // the unit that is moving - const dtNavMesh* m_navMesh; // the nav mesh - const dtNavMeshQuery* m_navMeshQuery; // the nav mesh query used to find the path + Unit const* const _sourceUnit; // the unit that is moving + dtNavMesh const* _navMesh; // the nav mesh + dtNavMeshQuery const* _navMeshQuery; // the nav mesh query used to find the path - dtQueryFilter m_filter; // use single filter for all movements, update it when needed + dtQueryFilter _filter; // use single filter for all movements, update it when needed - void setStartPosition(Vector3 point) { m_startPosition = point; } - void setEndPosition(Vector3 point) { m_actualEndPosition = point; m_endPosition = point; } - void setActualEndPosition(Vector3 point) { m_actualEndPosition = point; } - + void SetStartPosition(Vector3 Point) { _startPosition = Point; } + void SetEndPosition(Vector3 Point) { _actualEndPosition = Point; _endPosition = Point; } + void SetActualEndPosition(Vector3 Point) { _actualEndPosition = Point; } void NormalizePath(); - void clear() + void Clear() { - m_polyLength = 0; - m_pathPoints.clear(); + _polyLength = 0; + _pathPoints.clear(); } - bool inRange(const Vector3 &p1, const Vector3 &p2, float r, float h) const; - float dist3DSqr(const Vector3 &p1, const Vector3 &p2) const; - bool inRangeYZX(const float* v1, const float* v2, float r, float h) const; + bool InRange(Vector3 const& p1, Vector3 const& p2, float r, float h) const; + float Dist3DSqr(Vector3 const& p1, Vector3 const& p2) const; + bool InRangeYZX(float const* v1, float const* v2, float r, float h) const; - dtPolyRef getPathPolyByPosition(const dtPolyRef *polyPath, uint32 polyPathSize, const float* point, float *distance = NULL) const; - dtPolyRef getPolyByLocation(const float* point, float *distance) const; - bool HaveTile(const Vector3 &p) const; + dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = NULL) const; + dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const; + bool HaveTile(Vector3 const& p) const; - void BuildPolyPath(const Vector3 &startPos, const Vector3 &endPos); - void BuildPointPath(const float *startPoint, const float *endPoint); + void BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos); + void BuildPointPath(float const* startPoint, float const* endPoint); void BuildShortcut(); - NavTerrain getNavTerrain(float x, float y, float z); - void createFilter(); - void updateFilter(); + NavTerrain GetNavTerrain(float x, float y, float z); + void CreateFilter(); + void UpdateFilter(); // smooth path aux functions - uint32 fixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, - const dtPolyRef* visited, uint32 nvisited); - bool getSteerTarget(const float* startPos, const float* endPos, float minTargetDist, - const dtPolyRef* path, uint32 pathSize, float* steerPos, + uint32 FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited); + bool GetSteerTarget(float const* startPos, float const* endPos, float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef); - dtStatus findSmoothPath(const float* startPos, const float* endPos, - const dtPolyRef* polyPath, uint32 polyPathSize, + dtStatus FindSmoothPath(float const* startPos, float const* endPos, + dtPolyRef const* polyPath, uint32 polyPathSize, float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize); }; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 8167ff36de2..2796e208e34 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -154,7 +154,7 @@ namespace Movement { PathGenerator path(unit); path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); - MovebyPath(path.getPath()); + MovebyPath(path.GetPath()); } else { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 081056c1c79..0cbae416271 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5157,10 +5157,10 @@ SpellCastResult Spell::CheckCast(bool strict) target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); - m_preGeneratedPath.setPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); + m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); - if (m_preGeneratedPath.getPathType() & PATHFIND_SHORT) + if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; break; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1aa2ca0176b..d3b21395725 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5139,7 +5139,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) { - if (m_preGeneratedPath.getPathType() & PATHFIND_NOPATH) + if (m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH) { Position pos; unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); -- cgit v1.2.3 From c9eb42f2465e607c5e13425cc913b792a15e937e Mon Sep 17 00:00:00 2001 From: Venugh Date: Thu, 6 Sep 2012 00:36:24 +0200 Subject: Core/Commands: Implemented mmaps commands. --- sql/updates/world/2012_09_06_00_world_command.sql | 9 + src/server/game/Scripting/ScriptLoader.cpp | 2 + src/server/scripts/Commands/CMakeLists.txt | 1 + src/server/scripts/Commands/cs_mmaps.cpp | 293 ++++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 sql/updates/world/2012_09_06_00_world_command.sql create mode 100644 src/server/scripts/Commands/cs_mmaps.cpp (limited to 'src') diff --git a/sql/updates/world/2012_09_06_00_world_command.sql b/sql/updates/world/2012_09_06_00_world_command.sql new file mode 100644 index 00000000000..e60c1644e05 --- /dev/null +++ b/sql/updates/world/2012_09_06_00_world_command.sql @@ -0,0 +1,9 @@ +DELETE FROM `command` WHERE `name`='mmap' OR `name` LIKE 'mmap%'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('mmap', 3, 'Syntax: Syntax: .mmaps $subcommand Type .mmaps to see the list of possible subcommands or .help mmaps $subcommand to see info on subcommands'), +('mmap path', 3, 'Syntax: .mmap path to calculate and show a path to current select unit'), +('mmap loc', 3, 'Syntax: .mmap loc to print on which tile one is'), +('mmap loadedtiles', 3, 'Syntax: .mmap loadedtiles to show which tiles are currently loaded'), +('mmap stats', 3, 'Syntax: .mmap stats to show information about current state of mmaps'), +('mmap testarea', 3, 'Syntax: .mmap testarea to calculate paths for all nearby npcs to player'); + diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index fc56106ab6f..6442a35f0c3 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -75,6 +75,7 @@ void AddSC_tele_commandscript(); void AddSC_ticket_commandscript(); void AddSC_titles_commandscript(); void AddSC_wp_commandscript(); +void AddSC_mmaps_commandscript(); #ifdef SCRIPTS //world @@ -693,6 +694,7 @@ void AddCommandScripts() AddSC_ticket_commandscript(); AddSC_titles_commandscript(); AddSC_wp_commandscript(); + AddSC_mmaps_commandscript(); } void AddWorldScripts() diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 177b3a479f5..e799cf20633 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -41,6 +41,7 @@ set(scripts_STAT_SRCS Commands/cs_server.cpp Commands/cs_titles.cpp Commands/cs_wp.cpp + Commands/cs_mmaps.cpp # Commands/cs_pdump.cpp # Commands/cs_channel.cpp # Commands/cs_pet.cpp diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp new file mode 100644 index 00000000000..c1fc4d1a5e9 --- /dev/null +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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, see . + */ + +/** +* @file cs_mmaps.cpp +* @brief .mmap related commands +* +* This file contains the CommandScripts for all +* mmap sub-commands +*/ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "PointMovementGenerator.h" +#include "PathGenerator.h" +#include "MMapFactory.h" +#include "Map.h" +#include "TargetedMovementGenerator.h" + +class mmaps_commandscript : public CommandScript +{ +public: + mmaps_commandscript() : CommandScript("mmaps_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand mmapCommandTable[] = + { + { "path", SEC_ADMINISTRATOR, false, &HandleMmapPathCommand, "", NULL }, + { "loc", SEC_ADMINISTRATOR, false, &HandleMmapLocCommand, "", NULL }, + { "loadedtiles", SEC_ADMINISTRATOR, false, &HandleMmapLoadedTilesCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, false, &HandleMmapStatsCommand, "", NULL }, + { "testarea", SEC_ADMINISTRATOR, false, &HandleMmapTestArea, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "mmap", SEC_ADMINISTRATOR, true, NULL, "", mmapCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) + { + if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap path:"); + + // units + Player* player = handler->GetSession()->GetPlayer(); + Unit* target = handler->getSelectedUnit(); + if (!player || !target) + { + handler->PSendSysMessage("Invalid target/source selection."); + return true; + } + + char* para = strtok((char*)args, " "); + + bool useStraightPath = false; + if (para && strcmp(para, "true") == 0) + useStraightPath = true; + + // unit locations + float x, y, z; + player->GetPosition(x, y, z); + + // path + PathGenerator path(target); + path.SetUseStraightPath(useStraightPath); + path.CalculatePath(x, y, z); + + PointsArray pointPath = path.GetPath(); + handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); + handler->PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath"); + handler->PSendSysMessage("length %i type %u", pointPath.size(), path.GetPathType()); + + Vector3 start = path.GetStartPosition(); + Vector3 end = path.GetEndPosition(); + Vector3 actualEnd = path.GetActualEndPosition(); + + handler->PSendSysMessage("start (%.3f, %.3f, %.3f)", start.x, start.y, start.z); + handler->PSendSysMessage("end (%.3f, %.3f, %.3f)", end.x, end.y, end.z); + handler->PSendSysMessage("actual end (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); + + if (!player->isGameMaster()) + handler->PSendSysMessage("Enable GM mode to see the path points."); + + // this entry visible only to GM's with "gm on" + static const uint32 WAYPOINT_NPC_ENTRY = 1; + for (uint32 i = 0; i < pointPath.size(); ++i) + player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); + + return true; + } + + static bool HandleMmapLocCommand(ChatHandler* handler, const char* args) + { + handler->PSendSysMessage("mmap tileloc:"); + + // grid tile location + Player* player = handler->GetSession()->GetPlayer(); + + int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; + int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; + + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); + handler->PSendSysMessage("gridloc [%i,%i]", gx, gy); + + // calculate navmesh tile location + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId()); + if (!navmesh || !navmeshquery) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + float const* min = navmesh->getParams()->orig; + float x, y, z; + player->GetPosition(x, y, z); + float location[VERTEX_SIZE] = {y, z, x}; + float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; + + int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); + int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); + + handler->PSendSysMessage("Calc [%02i,%02i]", tilex, tiley); + + // navmesh poly -> navmesh tile location + dtQueryFilter filter = dtQueryFilter(); + dtPolyRef polyRef = INVALID_POLYREF; + navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL); + + if (polyRef == INVALID_POLYREF) + handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)"); + else + { + dtMeshTile const* tile; + dtPoly const* poly; + navmesh->getTileAndPolyByRef(polyRef, &tile, &poly); + if (tile) + handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y); + else + handler->PSendSysMessage("Dt [??,??] (no tile loaded)"); + } + + return true; + } + + static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, const char* args) + { + uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId()); + if (!navmesh || !navmeshquery) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap loadedtiles:"); + + for (int32 i = 0; i < navmesh->getMaxTiles(); ++i) + { + dtMeshTile const* tile = navmesh->getTile(i); + if (!tile || !tile->header) + continue; + + handler->PSendSysMessage("[%02i,%02i]", tile->header->x, tile->header->y); + } + + return true; + } + + static bool HandleMmapStatsCommand(ChatHandler* handler, const char* args) + { + uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); + handler->PSendSysMessage("mmap stats:"); + handler->PSendSysMessage(" global mmap pathfinding is %sabled", MMAP::MMapFactory::IsPathfindingEnabled(mapId) ? "en" : "dis"); + + MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager(); + handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); + + dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); + if (!navmesh) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + uint32 tileCount = 0; + uint32 nodeCount = 0; + uint32 polyCount = 0; + uint32 vertCount = 0; + uint32 triCount = 0; + uint32 triVertCount = 0; + uint32 dataSize = 0; + for (int32 i = 0; i < navmesh->getMaxTiles(); ++i) + { + dtMeshTile const* tile = navmesh->getTile(i); + if (!tile || !tile->header) + continue; + + tileCount++; + nodeCount += tile->header->bvNodeCount; + polyCount += tile->header->polyCount; + vertCount += tile->header->vertCount; + triCount += tile->header->detailTriCount; + triVertCount += tile->header->detailVertCount; + dataSize += tile->dataSize; + } + + handler->PSendSysMessage("Navmesh stats:"); + handler->PSendSysMessage(" %u tiles loaded", tileCount); + handler->PSendSysMessage(" %u BVTree nodes", nodeCount); + handler->PSendSysMessage(" %u polygons (%u vertices)", polyCount, vertCount); + handler->PSendSysMessage(" %u triangles (%u vertices)", triCount, triVertCount); + handler->PSendSysMessage(" %.2f MB of data (not including pointers)", ((float)dataSize / sizeof(unsigned char)) / 1048576); + + return true; + } + + static bool HandleMmapTestArea(ChatHandler* handler, const char* args) + { + float radius = 40.0f; + WorldObject* object = handler->GetSession()->GetPlayer(); + + CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()) ); + Cell cell(pair); + cell.SetNoCreate(); + + std::list creatureList; + + Trinity::AnyUnitInObjectRangeCheck go_check(object, radius); + Trinity::CreatureListSearcher go_search(object, creatureList, go_check); + TypeContainerVisitor, GridTypeMapContainer> go_visit(go_search); + + // Get Creatures + cell.Visit(pair, go_visit, *(object->GetMap()), *object, radius); + + if (!creatureList.empty()) + { + handler->PSendSysMessage("Found %i Creatures.", creatureList.size()); + + uint32 paths = 0; + uint32 uStartTime = getMSTime(); + + float gx, gy, gz; + object->GetPosition(gx, gy, gz); + for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) + { + PathGenerator path(*itr); + path.CalculatePath(gx, gy, gz); + ++paths; + } + + uint32 uPathLoadTime = getMSTimeDiff(uStartTime, getMSTime()); + handler->PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime); + } + else + handler->PSendSysMessage("No creatures in %f yard range.", radius); + + return true; + } +}; + +void AddSC_mmaps_commandscript() +{ + new mmaps_commandscript(); +} \ No newline at end of file -- cgit v1.2.3 From 5617921a55973018e1c5fd9c3307be875cf321b6 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Thu, 6 Sep 2012 05:27:14 +0300 Subject: compile fix --- src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 0ca688fb0df..064e5bfa1a2 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -52,7 +52,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, void unitSpeedChanged() { i_recalculateTravel = true; } void UpdateFinalDistance(float fDistance); - bool IsReachable() const { return (i_path) ? (i_path->getPathType() & PATHFIND_NORMAL) : true; } + bool IsReachable() const { return (i_path) ? (i_path->GetPathType() & PATHFIND_NORMAL) : true; } protected: void _setTargetLocation(T*); -- cgit v1.2.3 From a2d533752c447a2bf4ef7b784e8abdbe3f6d6904 Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 7 Sep 2012 04:21:11 +0200 Subject: Core/MMaps: Add several safety checks to confirm a valid path generation. - Address some issues in TargetMovementGenerator. Thanks Chevron --- src/server/collision/Management/MMapManager.cpp | 2 +- src/server/game/Entities/Object/Object.cpp | 2 +- .../ConfusedMovementGenerator.cpp | 4 +-- .../FleeingMovementGenerator.cpp | 4 +-- .../TargetedMovementGenerator.cpp | 41 +++++++++++----------- src/server/game/Movement/PathGenerator.cpp | 8 +++-- src/server/game/Movement/Spline/MoveSplineInit.cpp | 20 ++++++----- src/server/game/Spells/Spell.cpp | 5 +-- 8 files changed, 46 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 8e6e2a3b6b4..c7dea358d92 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -295,4 +295,4 @@ namespace MMAP return mmap->navMeshQueries[instanceId]; } -} \ No newline at end of file +} diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fe5d32b9b95..2205efa8724 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2780,7 +2780,7 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) desty = pos.m_positionY + dist * sin(angle); // Prevent invalid coordinates here, position is unchanged - if (!Trinity::IsValidMapCoord(destx, desty)) + if (!Trinity::IsValidMapCoord(destx, desty, pos.m_positionZ)) { sLog->outFatal(LOG_FILTER_GENERAL, "WorldObject::MovePosition invalid coordinates X: %f and Y: %f were passed!", destx, desty); return; diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 32c6ec3858d..4c269a1024a 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -78,8 +78,8 @@ bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) PathGenerator path(unit); path.SetPathLengthLimit(30.0f); - path.CalculatePath(x, y, z); - if (path.GetPathType() & PATHFIND_NOPATH) + bool result = path.CalculatePath(x, y, z); + if (!result || path.GetPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); return true; diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 8f4d78b34b1..29466ab9670 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -45,8 +45,8 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) PathGenerator path(owner); path.SetPathLengthLimit(30.0f); - path.CalculatePath(x, y, z); - if (path.GetPathType() & PATHFIND_NOPATH) + bool result = path.CalculatePath(x, y, z); + if (!result || path.GetPathType() & PATHFIND_NOPATH) { i_nextCheckTime.Reset(urand(1000, 1500)); return; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 4a8d15b8079..145251ec4aa 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -35,30 +35,28 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) if (owner->HasUnitState(UNIT_STATE_NOT_MOVE)) return; + if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature())) + return; + float x, y, z; - //! Following block of code deleted by MrSmite in issue 4891 - //! Code kept for learning and diagnostical purposes -// -// if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) -// { -// if (!owner.movespline->Finalized()) -// return; -// -// owner.GetPosition(x, y, z); -// } -// else + if (!i_offset) { - if (i_target->IsWithinMeleeRange(owner)) - return; + float dist = 0.0f; + + if (owner->getVictim() && owner->getVictim()->GetGUID() == i_target->GetGUID()) + dist = owner->GetFloatValue(UNIT_FIELD_COMBATREACH) + i_target->GetFloatValue(UNIT_FIELD_COMBATREACH) - i_target->GetObjectSize() - owner->GetObjectSize() - 1.0f; + + if (dist < 0.5f) + dist = 0.5f; - // to nearest random contact position - i_target->GetRandomContactPoint(owner, x, y, z, 0, MELEE_RANGE - 0.5f); + if (owner->IsWithinLOSInMap(owner->getVictim())) + i_target->GetContactPoint(owner, x, y, z, dist); + else + i_target->GetPosition(x, y, z); } else { - if (i_target->IsWithinDistInMap(owner, i_offset + 1.0f)) - return; // to at i_offset distance from target and i_angle from target facing i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); } @@ -69,8 +67,9 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) // allow pets following their master to cheat while generating paths bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)); - i_path->CalculatePath(x, y, z, forceDest); - if (i_path->GetPathType() & PATHFIND_NOPATH) + + bool result = i_path->CalculatePath(x, y, z, forceDest); + if (!result || i_path->GetPathType() & PATHFIND_NOPATH) return; D::_addUnitStateMove(owner); @@ -117,7 +116,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d return false; if (!owner || !owner->isAlive()) - return true; + return false; if (owner->HasUnitState(UNIT_STATE_NOT_MOVE)) { @@ -154,7 +153,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); - if (targetMoved) + if (targetMoved || !owner->IsWithinLOSInMap(owner->getVictim())) _setTargetLocation(owner); } diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 165cc282e3a..68dd8f4057d 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -58,8 +58,12 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; + float newDestZ = _sourceUnit->GetBaseMap()->GetHeight(_sourceUnit->GetPhaseMask(), x, y, z, true, MAX_FALL_DISTANCE); + if (newDestZ >= INVALID_HEIGHT) + return false; + Vector3 oldDest = GetEndPosition(); - Vector3 dest(destX, destY, destZ); + Vector3 dest(destX, destY, newDestZ); SetEndPosition(dest); Vector3 start(x, y, z); @@ -124,7 +128,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 minDist3d = dtVdistSqr(point, closestPoint); } - if(minDist2d < 1.0f) // shortcut out - close enough for us + if (minDist2d < 1.0f) // shortcut out - close enough for us break; } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 2796e208e34..68201fcf275 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -153,16 +153,18 @@ namespace Movement if (generatePath) { PathGenerator path(unit); - path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); - MovebyPath(path.GetPath()); - } - else - { - args.path_Idx_offset = 0; - args.path.resize(2); - TransportPathTransform transform(unit, args.TransformForTransport); - args.path[1] = transform(dest); + bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); + if (result && path.GetPathType() & ~PATHFIND_NOPATH) + { + MovebyPath(path.GetPath()); + return; + } } + + args.path_Idx_offset = 0; + args.path.resize(2); + TransportPathTransform transform(unit, args.TransformForTransport); + args.path[1] = transform(dest); } Vector3 TransportPathTransform::operator()(Vector3 input) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d9a3e6a4b3c..a701b9d143e 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5162,10 +5162,11 @@ SpellCastResult Spell::CheckCast(bool strict) target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); - m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); - + bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; + else if (!result) + return SPELL_FAILED_NOPATH; break; } -- cgit v1.2.3 From 2e80503283b8cb15f95dda6bd6a6da973e0b8501 Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 7 Sep 2012 12:54:38 +0200 Subject: Typo --- src/server/game/Movement/PathGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 68dd8f4057d..6f505de25cd 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -59,7 +59,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo return false; float newDestZ = _sourceUnit->GetBaseMap()->GetHeight(_sourceUnit->GetPhaseMask(), x, y, z, true, MAX_FALL_DISTANCE); - if (newDestZ >= INVALID_HEIGHT) + if (newDestZ <= INVALID_HEIGHT) return false; Vector3 oldDest = GetEndPosition(); -- cgit v1.2.3 From 8966347a416b9e2fba43bc3ff7043d946cfe10c4 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 9 Sep 2012 15:14:02 -0500 Subject: Core/MMaps: Added a little workaround to prevent the crash. ref issue #7631 --- src/server/game/Movement/PathGenerator.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 6f505de25cd..9635399e71f 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -584,12 +584,19 @@ NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) } } -bool PathGenerator::HaveTile(Vector3 const& p) const +bool PathGenerator::HaveTile(const Vector3& p) const { - int tx, ty; + int tx = -1, ty = -1; float point[VERTEX_SIZE] = {p.y, p.z, p.x}; _navMesh->calcTileLoc(point, &tx, &ty); + + /// Workaround + /// For some reason, often the tx and ty variables wont get a valid value + /// Use this check to prevent getting negative tile coords and crashing on getTileAt + if (tx < 0 || ty < 0) + return false; + return (_navMesh->getTileAt(tx, ty) != NULL); } -- cgit v1.2.3 From f237a57f51c0473bda90bae7a06bd5b9c187754b Mon Sep 17 00:00:00 2001 From: kaelima Date: Mon, 10 Sep 2012 13:24:01 +0200 Subject: Fix compile. Closes #7718 --- src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 4f6865405ae..edef9cfed43 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -174,7 +174,7 @@ namespace Movement if (_transformForTransport) { float unused = 0.0f; - if (TransportBase* transport = _owner.GetDirectTransport()) + if (TransportBase* transport = _owner->GetDirectTransport()) transport->CalculatePassengerOffset(input.x, input.y, input.z, unused); } -- cgit v1.2.3 From 33994351fff5f7ebad7ae75a5dbadd70c6f26413 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 25 Sep 2012 12:22:02 -0500 Subject: Core/Configs: Removed vmap.petLOS option in the worldserver config, it was intended to somewhat fix the lack of pathfinding, its not needed anymore. Closes #7817 --- src/server/game/Handlers/PetHandler.cpp | 7 ------- src/server/game/World/World.cpp | 4 +--- src/server/game/World/World.h | 1 - src/server/worldserver/worldserver.conf.dist | 8 -------- 4 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src') diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 3501b3bc068..f8cb0344a96 100755 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -194,13 +194,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid if (!owner->IsValidAttackTarget(TargetUnit)) return; - // Not let attack through obstructions - if (sWorld->getBoolConfig(CONFIG_PET_LOS)) - { - if (!pet->IsWithinLOSInMap(TargetUnit)) - return; - } - pet->ClearUnitState(UNIT_STATE_FOLLOW); // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != TargetUnit || (pet->getVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack())) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 72b81b671b0..e9d727e072a 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1133,7 +1133,6 @@ void World::LoadConfigSettings(bool reload) bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true); bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", true); - bool enablePetLOS = ConfigMgr::GetBoolDefault("vmap.petLOS", true); std::string ignoreSpellIds = ConfigMgr::GetStringDefault("vmap.ignoreSpellIds", ""); if (!enableHeight) @@ -1142,11 +1141,10 @@ void World::LoadConfigSettings(bool reload) VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS); VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight); VMAP::VMapFactory::preventSpellsFromBeingTestedForLoS(ignoreSpellIds.c_str()); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight:%i, getHeight:%i, indoorCheck:%i PetLOS:%i", enableLOS, enableHeight, enableIndoor, enablePetLOS); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight:%i, getHeight:%i, indoorCheck:%i", enableLOS, enableHeight, enableIndoor); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap data directory is: %svmaps", m_dataPath.c_str()); m_int_configs[CONFIG_MAX_WHO] = ConfigMgr::GetIntDefault("MaxWhoListReturns", 49); - m_bool_configs[CONFIG_PET_LOS] = ConfigMgr::GetBoolDefault("vmap.petLOS", true); m_bool_configs[CONFIG_START_ALL_SPELLS] = ConfigMgr::GetBoolDefault("PlayerStart.AllSpells", false); if (m_bool_configs[CONFIG_START_ALL_SPELLS]) sLog->outWarn(LOG_FILTER_SERVER_LOADING, "PlayerStart.AllSpells enabled - may not function as intended!"); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index f75745dac9b..e63ffa878ce 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -138,7 +138,6 @@ enum WorldBoolConfigs CONFIG_ARENA_LOG_EXTENDED_INFO, CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN, CONFIG_VMAP_INDOOR_CHECK, - CONFIG_PET_LOS, CONFIG_START_ALL_SPELLS, CONFIG_START_ALL_EXPLORED, CONFIG_START_ALL_REP, diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index e70ef00e94c..14d772aa79a 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -303,14 +303,6 @@ vmap.enableHeight = 1 vmap.ignoreSpellIds = "7720" -# -# vmap.petLOS -# Description: Check line of sight for pets, to avoid them attacking through walls. -# Default: 1 - (Enabled, each pet attack will be checked for line of sight - not recommended if mmaps is enabled!) -# 0 - (Disabled, somewhat less CPU usage) - -vmap.petLOS = 0 - # # vmap.enableIndoorCheck # Description: VMap based indoor check to remove outdoor-only auras (mounts etc.). -- cgit v1.2.3 From bb6ce2b2c9018873127a352a39737ed4df7f7d46 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 25 Sep 2012 12:37:25 -0500 Subject: Core/MMaps: Only unload the navMeshQuery when instances are unloaded, suggestion by @Vlad852 closes #7631 --- src/server/game/Maps/Map.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 50218c8ba83..ae192f16080 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -72,7 +72,6 @@ Map::~Map() sScriptMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); - MMAP::MMapFactory::createOrGetMMapManager()->unloadMap(GetId()); } bool Map::ExistMap(uint32 mapid, int gx, int gy) -- cgit v1.2.3 From 50f833a0086c9f7f80152b907c77acb19d352896 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 06:59:31 -0500 Subject: Tools: Added an experimental tool (still WIP) to replace the current mmaps generator --- cmake/options.cmake | 2 +- src/tools/CMakeLists.txt | 1 + src/tools/mesh_extractor/ADT.h | 26 ++ src/tools/mesh_extractor/CMakeLists.txt | 62 +++ src/tools/mesh_extractor/Cache.h | 44 +++ src/tools/mesh_extractor/Chunk.cpp | 31 ++ src/tools/mesh_extractor/Chunk.h | 20 + src/tools/mesh_extractor/ChunkedData.cpp | 63 ++++ src/tools/mesh_extractor/ChunkedData.h | 20 + src/tools/mesh_extractor/Constants.h | 33 ++ src/tools/mesh_extractor/ContinentBuilder.cpp | 11 + src/tools/mesh_extractor/ContinentBuilder.h | 15 + src/tools/mesh_extractor/DoodadHandler.cpp | 99 +++++ src/tools/mesh_extractor/DoodadHandler.h | 51 +++ src/tools/mesh_extractor/Geometry.cpp | 102 +++++ src/tools/mesh_extractor/Geometry.h | 21 ++ src/tools/mesh_extractor/LiquidHandler.cpp | 1 + src/tools/mesh_extractor/LiquidHandler.h | 17 + src/tools/mesh_extractor/MPQ.cpp | 117 ++++++ src/tools/mesh_extractor/MPQ.h | 88 +++++ src/tools/mesh_extractor/MPQManager.cpp | 58 +++ src/tools/mesh_extractor/MPQManager.h | 24 ++ src/tools/mesh_extractor/MapChunk.cpp | 77 ++++ src/tools/mesh_extractor/MapChunk.h | 25 ++ src/tools/mesh_extractor/MeshExtractor.cpp | 34 ++ src/tools/mesh_extractor/Model.cpp | 49 +++ src/tools/mesh_extractor/Model.h | 21 ++ src/tools/mesh_extractor/ObjectDataHandler.cpp | 21 ++ src/tools/mesh_extractor/ObjectDataHandler.h | 15 + src/tools/mesh_extractor/TileBuilder.cpp | 37 ++ src/tools/mesh_extractor/TileBuilder.h | 22 ++ src/tools/mesh_extractor/Utils.cpp | 163 ++++++++ src/tools/mesh_extractor/Utils.h | 497 +++++++++++++++++++++++++ src/tools/mesh_extractor/WDT.cpp | 55 +++ src/tools/mesh_extractor/WDT.h | 27 ++ src/tools/mesh_extractor/WorldModelGroup.cpp | 122 ++++++ src/tools/mesh_extractor/WorldModelGroup.h | 33 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 190 ++++++++++ src/tools/mesh_extractor/WorldModelHandler.h | 42 +++ src/tools/mesh_extractor/WorldModelRoot.cpp | 74 ++++ src/tools/mesh_extractor/WorldModelRoot.h | 26 ++ src/tools/mesh_extractor/readme | 6 + 42 files changed, 2441 insertions(+), 1 deletion(-) create mode 100644 src/tools/mesh_extractor/ADT.h create mode 100644 src/tools/mesh_extractor/CMakeLists.txt create mode 100644 src/tools/mesh_extractor/Cache.h create mode 100644 src/tools/mesh_extractor/Chunk.cpp create mode 100644 src/tools/mesh_extractor/Chunk.h create mode 100644 src/tools/mesh_extractor/ChunkedData.cpp create mode 100644 src/tools/mesh_extractor/ChunkedData.h create mode 100644 src/tools/mesh_extractor/Constants.h create mode 100644 src/tools/mesh_extractor/ContinentBuilder.cpp create mode 100644 src/tools/mesh_extractor/ContinentBuilder.h create mode 100644 src/tools/mesh_extractor/DoodadHandler.cpp create mode 100644 src/tools/mesh_extractor/DoodadHandler.h create mode 100644 src/tools/mesh_extractor/Geometry.cpp create mode 100644 src/tools/mesh_extractor/Geometry.h create mode 100644 src/tools/mesh_extractor/LiquidHandler.cpp create mode 100644 src/tools/mesh_extractor/LiquidHandler.h create mode 100644 src/tools/mesh_extractor/MPQ.cpp create mode 100644 src/tools/mesh_extractor/MPQ.h create mode 100644 src/tools/mesh_extractor/MPQManager.cpp create mode 100644 src/tools/mesh_extractor/MPQManager.h create mode 100644 src/tools/mesh_extractor/MapChunk.cpp create mode 100644 src/tools/mesh_extractor/MapChunk.h create mode 100644 src/tools/mesh_extractor/MeshExtractor.cpp create mode 100644 src/tools/mesh_extractor/Model.cpp create mode 100644 src/tools/mesh_extractor/Model.h create mode 100644 src/tools/mesh_extractor/ObjectDataHandler.cpp create mode 100644 src/tools/mesh_extractor/ObjectDataHandler.h create mode 100644 src/tools/mesh_extractor/TileBuilder.cpp create mode 100644 src/tools/mesh_extractor/TileBuilder.h create mode 100644 src/tools/mesh_extractor/Utils.cpp create mode 100644 src/tools/mesh_extractor/Utils.h create mode 100644 src/tools/mesh_extractor/WDT.cpp create mode 100644 src/tools/mesh_extractor/WDT.h create mode 100644 src/tools/mesh_extractor/WorldModelGroup.cpp create mode 100644 src/tools/mesh_extractor/WorldModelGroup.h create mode 100644 src/tools/mesh_extractor/WorldModelHandler.cpp create mode 100644 src/tools/mesh_extractor/WorldModelHandler.h create mode 100644 src/tools/mesh_extractor/WorldModelRoot.cpp create mode 100644 src/tools/mesh_extractor/WorldModelRoot.h create mode 100644 src/tools/mesh_extractor/readme (limited to 'src') diff --git a/cmake/options.cmake b/cmake/options.cmake index 11ebe6ddd12..5802ab86f43 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -10,7 +10,7 @@ option(SERVERS "Build worldserver and authserver" 1) option(SCRIPTS "Build core with scripts included" 1) -option(TOOLS "Build map/vmap extraction/assembler tools" 0) +option(TOOLS "Build map/vmap/mmap extraction/assembler tools" 0) option(USE_SCRIPTPCH "Use precompiled headers when compiling scripts" 1) option(USE_COREPCH "Use precompiled headers when compiling servers" 1) option(WITH_WARNINGS "Show all warnings during compile" 0) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 2d378966aff..bbff6f85751 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -12,3 +12,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) add_subdirectory(mmaps_generator) +add_subdirectory(mesh_extractor) diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h new file mode 100644 index 00000000000..18b811a4e4c --- /dev/null +++ b/src/tools/mesh_extractor/ADT.h @@ -0,0 +1,26 @@ +#ifndef ADT_H +#define ADT_H +#include "ChunkedData.h" +#include "MapChunk.h" +#include "DoodadHandler.h" +#include "WorldModelHandler.h" + +class ADT +{ +public: + ADT(); + ~ADT() { delete[] MapChunks; delete ObjectData; delete Data; } + + ChunkedData* ObjectData; + ChunkedData* Data; + // This here is not a pointer, is an array of objects ( made this way to allow the dynamic allocation ) + MapChunk* MapChunks; + MHDR Header; + // Can we dispose of this? + bool HasObjectData; + + DoodadHandler* _DoodadHandler; + WorldModelHandler* _WorldModelHandler; + LiquidHandler* _LiquidHandler; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt new file mode 100644 index 00000000000..3f5b5526dd4 --- /dev/null +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2005-2009 MaNGOS project +# Copyright (C) 2008-2012 TrinityCore +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources *.cpp *.h) + +if( UNIX ) + include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${CMAKE_CURRENT_SOURCE_DIR} + ) +elseif( WIN32 ) + include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/libmpq/win + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() + +add_executable(MeshExtractor + ${sources} +) + +target_link_libraries(MeshExtractor + mpq + Recast + Detour + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + ${ACE_LIBRARY} +) + +add_dependencies(MeshExtractor mpq Recast Detour) + +if( UNIX ) + install(TARGETS MeshExtractor DESTINATION bin) +elseif( WIN32 ) + install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() \ No newline at end of file diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h new file mode 100644 index 00000000000..186a7870af1 --- /dev/null +++ b/src/tools/mesh_extractor/Cache.h @@ -0,0 +1,44 @@ +#ifndef CACHE_H +#define CACHE_H +#include +#include "Common.h" + +class WorldModelRoot; +class Model; + +template +class GenericCache +{ +public: + GenericCache() {} + const int32 FlushLimit = 1000; + + void Insert(std::string key, T* val) + { + if (_items.size() > FlushLimit) + Clear(); + _items.insert(key, val); + } + + T* Get(std::string key) + { + UNORDERED_MAP::iterator itr = _items.find(key); + if (itr != _items.end()) + return itr->second; + return NULL; + } + + void Clear() { _items.clear(); } +private: + UNORDERED_MAP _items; +}; + +class CacheClass +{ + CacheClass() {} + GenericCache ModelCache; + GenericCache WorldModelCache; +}; + +extern CacheClass* Cache; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp new file mode 100644 index 00000000000..b41fa7d07d4 --- /dev/null +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -0,0 +1,31 @@ +#include "Chunk.h" +#include "Utils.h" + +int32 Chunk::FindSubChunkOffset(std::string name) +{ + // Reverse the name + name = std::string(name.rbegin(), name.rend()); + if (name.size() != 4) + return -1; + + FILE* stream = GetStream(); + uint32 matched = 0; + while (ftell(stream) < Utils::Size(stream)) + { + char b; + fread(&b, sizeof(char), 1, stream); + if (b == name[matched]) + ++matched; + else + matched = 0; + if (matched == 4) + return ftell(stream) - 4; + } + return -1; +} + +FILE* Chunk::GetStream() +{ + fseek(Stream, Offset, SEEK_SET); + return Stream; +} diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h new file mode 100644 index 00000000000..2eea36f69b6 --- /dev/null +++ b/src/tools/mesh_extractor/Chunk.h @@ -0,0 +1,20 @@ +#ifndef CHUNK_H +#define CHUNK_H +#include "Common.h" +#include +class ChunkedData; + +class Chunk +{ +public: + Chunk(const char* name, uint32 length, uint32 offset, FILE* stream) : Name(name), Length(length), Offset(offset), Stream(stream) {} + + int32 FindSubChunkOffset(std::string name); + FILE* GetStream(); + std::string Name; + uint32 Length; + uint32 Offset; + FILE* Stream; +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp new file mode 100644 index 00000000000..470b8b94f39 --- /dev/null +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -0,0 +1,63 @@ +#include "ChunkedData.h" +#include "MPQManager.h" +#include "Utils.h" + +#include + +ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : +Stream(stream) +{ + if (!Stream) + return; + Load(maxLength, chunksHint); +} + +ChunkedData::ChunkedData( std::string file, uint32 chunksHint /*= 300*/ ) +{ + Stream = MPQHandler->GetFile(file); + if (!Stream) + return; + Load(0, chunksHint); +} + +void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) +{ + if (!maxLength) + maxLength = Utils::Size(Stream); + Chunks.reserve(chunksHint); + uint32 baseOffset = ftell(Stream); + uint32 calcOffset = 0; + while ((calcOffset + baseOffset) < Utils::Size(Stream) && (calcOffset < maxLength)) + { + char nameBytes[5]; + uint32 read = fread(&nameBytes, sizeof(char), 4, Stream); + nameBytes[read] = '\0'; + std::string name = std::string(nameBytes); + // Utils::Reverse(nameBytes); + name = std::string(name.rbegin(), name.rend()); + uint32 length; + fread(&length, sizeof(uint32), 1, Stream); + calcOffset += 8; + Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); + calcOffset += length; + // save an extra seek at the end + if ((calcOffset + baseOffset) < Utils::Size(Stream) && calcOffset < maxLength) + fseek(Stream, length, SEEK_CUR); + } +} + +int ChunkedData::GetFirstIndex( std::string name ) +{ + for (int i = 0; i < Chunks.size(); ++i) + if (Chunks[i]->Name == name) + return i; + return -1; +} + +Chunk* ChunkedData::GetChunkByName( std::string name ) +{ + for (int i = 0; i < Chunks.size(); ++i) + if (Chunks[i]->Name == name) + return Chunks[i]; + return NULL; +} diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h new file mode 100644 index 00000000000..6e102828222 --- /dev/null +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -0,0 +1,20 @@ +#ifndef CHNK_H +#define CHNK_H + +#include +#include "Chunk.h" + +class ChunkedData +{ +public: + ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); + ChunkedData(std::string file, uint32 chunksHint = 300); + + int GetFirstIndex(std::string name); + Chunk* GetChunkByName(std::string name); + + void Load(uint32 maxLength, uint32 chunksHint); + std::vector Chunks; + FILE* Stream; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h new file mode 100644 index 00000000000..885761f1687 --- /dev/null +++ b/src/tools/mesh_extractor/Constants.h @@ -0,0 +1,33 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#include "Common.h" + +class Constants +{ +public: + enum TriangleType + { + TRIANGLE_TYPE_UNKNOWN, + TRIANGLE_TYPE_TERRAIN, + TRIANGLE_TYPE_WATER, + TRIANGLE_TYPE_DOODAD, + TRIANGLE_TYPE_WMO + }; + + enum PolyArea + { + POLY_AREA_TERRAIN = 1, + POLY_AREA_WATER = 2, + POLY_AREA_ROAD = 3, + POLY_AREA_DANGER = 4, + }; + static const float TileSize; + static const float MaxXY; + static const float ChunkSize; + static const float UnitSize; + static const float Origin[]; + static const float PI; +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp new file mode 100644 index 00000000000..8af6f3a02e8 --- /dev/null +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -0,0 +1,11 @@ +#include "ContinentBuilder.h" +#include "WDT.h" +#include "Utils.h" + +void ContinentBuilder::Build() +{ + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + + } +} diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h new file mode 100644 index 00000000000..7db141ddcf1 --- /dev/null +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -0,0 +1,15 @@ +#ifndef CONT_BUILDER_H +#define CONT_BUILDER_H +#include +#include "WDT.h" + +class ContinentBuilder +{ +public: + ContinentBuilder(std::string continent, WDT* wdt) : Continent(continent), TileMap(wdt) {} + void Build(); +private: + std::string Continent; + WDT* TileMap; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp new file mode 100644 index 00000000000..4a7707753c4 --- /dev/null +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -0,0 +1,99 @@ +#include "DoodadHandler.h" +#include "Chunk.h" +#include "Cache.h" +#include "Model.h" +#include "g3d/Matrix4.h" + +DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) +{ + if (!adt->HasObjectData) + return; + Chunk* mddf = adt->ObjectData->GetChunkByName("MDDF"); + if (mddf) + ReadDoodadDefinitions(mddf); + + Chunk* mmid = adt->ObjectData->GetChunkByName("MMID"); + Chunk* mmdx = adt->ObjectData->GetChunkByName("MMDX"); + if (mmid && mmdx) + ReadDoodadPaths(mmid, mmdx); +} + +void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) +{ + if (!IsSane()) + return; + Chunk* doodadReferencesChunk = subChunks->GetChunkByName("MCRD"); + if (!doodadReferencesChunk) + return; + FILE* stream = doodadReferencesChunk->GetStream(); + uint32 refCount = doodadReferencesChunk->Length / 4; + for (int i = 0; i < refCount; i++) + { + int32 index; + fread(&index, sizeof(int32), 1, stream); + if (index < 0 || index >= _definitions->size()) + continue; + DoodadDefinition doodad = (*_definitions)[index]; + if (_drawn.find(doodad.UniqueId) != _drawn.end()) + continue; + _drawn.insert(doodad.UniqueId); + if (doodad.MmidIndex >= _paths->size()) + continue; + + std::string path = (*_paths)[doodad.MmidIndex]; + Model* model = Cache.ModelCache.Get(path); + if (!model) + { + model = new Model(path); + Cache.ModelCache.Insert(path, model); + } + if (!model->IsCollidable) + continue; + + Vertices.reserve(refCount * model->Vertices.size() * 0.2); + Triangles.reserve(refCount * model->Triangles.size() * 0.2); + + InsertModelGeometry(doodad, model); + } +} + +void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) +{ + int32 count = chunk->Length / 36; + _definitions = new std::vector; + _definitions->reserve(count); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < count; i++) + { + DoodadDefinition def; + def.Read(stream); + _definitions->push_back(def); + } +} + +void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) +{ + int paths = id->Length / 4; + _paths = new std::vector(); + _paths->reserve(paths); + for (int i = 0; i < paths; i++) + { + FILE* idStream = id->GetStream(); + fseek(idStream, i * 4, SEEK_CUR); + uint32 offset; + fread(&offset, sizeof(uint32), 1, idStream); + FILE* dataStream = data->GetStream(); + fseek(dataStream, offset + data->Offset, SEEK_SET); + _paths->push_back(Utils::ReadString(dataStream)); + } +} + +void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) +{ + G3D::Matrix4 transformation = Utils::GetTransformation(def); + uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) + Vertices.push_back(Utils::VectorTransform(*itr, transformation)); + for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h new file mode 100644 index 00000000000..c62584ca1f1 --- /dev/null +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -0,0 +1,51 @@ +#ifndef DOOADHNDL_H +#define DOOADHNDL_H +#include "ObjectDataHandler.h" +#include "Utils.h" +#include "Chunk.h" +#include "Model.h" +#include +#include + +class DoodadDefinition : IDefinition +{ +public: + uint32 MmidIndex; + uint32 UniqueId; + uint16 DecimalScale; + uint16 Flags; + + float Scale() { return DecimalScale / 1024.0f; } + + void Read(FILE* stream) + { + fread(&MmidIndex, sizeof(uint32), 1, stream); + fread(&UniqueId, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + Rotation = Vector3::Read(stream); + fread(&DecimalScale, sizeof(uint16), 1, stream); + fread(&Flags, sizeof(uint16), 1, stream); + } +}; + +class DoodadHandler : public ObjectDataHandler +{ +public: + DoodadHandler(ADT* adt); + std::vector Vertices; + std::vector > Triangles; + bool IsSane() { return _definitions && _paths; } + + +protected: + void ProcessInternal(ChunkedData* chunk); + +private: + void ReadDoodadDefinitions(Chunk* chunk); + void ReadDoodadPaths(Chunk* id, Chunk* data); + void InsertModelGeometry(DoodadDefinition def, Model* model); + std::set _drawn; + std::vector* _definitions; + std::vector* _paths; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp new file mode 100644 index 00000000000..8e417af4c73 --- /dev/null +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -0,0 +1,102 @@ +#include "Geometry.h" +#include "Constants.h" + +Geometry::Geometry() : Transform(false) +{ + Vertices.reserve(10000); + Triangles.reserve(10000); +} + +void Geometry::CalculateBoundingBox( float*& min, float*& max ) +{ + min = new float[3]; + max = new float[3]; + + for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) + { + if (itr->x > max[0]) + max[0] = itr->x; + if (itr->x < min[0]) + min[0] = itr->x; + + if (itr->y > max[1]) + max[1] = itr->y; + if (itr->y < min[1]) + min[1] = itr->y; + + if (itr->z > max[2]) + max[2] = itr->z; + if (itr->z < min[2]) + min[2] = itr->z; + } +} + +void Geometry::CalculateMinMaxHeight( float& min, float& max ) +{ + min = 0.0f; + max = 0.0f; + + for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) + { + if (Transform) + { + if (itr->y < min) + min = itr->y; + if (itr->y > max) + max = itr->y; + } + else + { + if (itr->z < min) + min = itr->z; + if (itr->z > max) + max = itr->z; + } + } +} + +void Geometry::AddData( std::vector& verts, std::vector >& tris ) +{ + uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = verts.begin(); itr != verts.end(); ++itr) + Vertices.push_back(Transform ? Utils::ToRecast(*itr) : *itr); + + for (std::vector >::iterator itr = tris.begin(); itr != tris.end(); ++itr) + Triangles.push_back(Triangle(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} + +void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) +{ + verts = new float[Vertices.size() * 3]; + for (int i = 0; i < Vertices.size(); ++i) + { + Vector3& vert = Vertices[i]; + verts[(i * 3) + 0] = vert.x; + verts[(i * 3) + 1] = vert.y; + verts[(i * 3) + 2] = vert.z; + } + + tris = new int[Triangles.size() * 3]; + for (int i = 0; i < Triangles.size(); ++i) + { + Triangle& tri = Triangles[i]; + tris[(i * 3) + 0] = (int)tri.V0; + tris[(i * 3) + 1] = (int)tri.V1; + tris[(i * 3) + 2] = (int)tri.V2; + } + + areas = new uint8[Triangles.size()]; + for (int i = 0; i < Triangles.size(); i++) + { + switch (Triangles[i].Type) + { + case Constants::TRIANGLE_TYPE_WATER: + areas[i] = Constants::POLY_AREA_WATER; + break; + default: + areas[i] = Constants::POLY_AREA_TERRAIN; + break; + } + } +} + diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h new file mode 100644 index 00000000000..048d9fde578 --- /dev/null +++ b/src/tools/mesh_extractor/Geometry.h @@ -0,0 +1,21 @@ +#ifndef GEOMETRY_H +#define GEOMETRY_H +#include + +#include "Utils.h" + +class Geometry +{ +public: + Geometry(); + + void CalculateBoundingBox(float*& min, float*& max); + void CalculateMinMaxHeight(float& min, float& max); + void AddData(std::vector& verts, std::vector >& tris); + void GetRawData(float*& verts, int*& tris, uint8*& areas); + + std::vector Vertices; + std::vector > Triangles; + bool Transform; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp new file mode 100644 index 00000000000..5924c693196 --- /dev/null +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -0,0 +1 @@ +#include "LiquidHandler.h" \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h new file mode 100644 index 00000000000..ba89be33e08 --- /dev/null +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -0,0 +1,17 @@ +#ifndef LIQUID_H +#define LIQUID_H +#include "ADT.h" +#include "Utils.h" +#include "Common.h" + +#include + +class LiquidHandler +{ +public: + ADT* Source; + std::vector Vertices; + std::vector > Triangles; + std::vector MCNKData; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp new file mode 100644 index 00000000000..fbae56cd7a0 --- /dev/null +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -0,0 +1,117 @@ +#include "MPQ.h" +#include "MPQManager.h" +#include +#include + +MPQArchive::MPQArchive(const char* filename) +{ + int result = libmpq__archive_open(&mpq_a, filename, -1); + printf("Opening %s\n", filename); + if (result) + { + switch (result) + { + case LIBMPQ_ERROR_OPEN : + printf("Error opening archive '%s': Does file really exist?\n", filename); + break; + case LIBMPQ_ERROR_FORMAT : /* bad file format */ + printf("Error opening archive '%s': Bad file format\n", filename); + break; + case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ + printf("Error opening archive '%s': Seeking in file failed\n", filename); + break; + case LIBMPQ_ERROR_READ : /* Read error in archive */ + printf("Error opening archive '%s': Read error in archive\n", filename); + break; + case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ + printf("Error opening archive '%s': Maybe not enough memory\n", filename); + break; + default: + printf("Error opening archive '%s': Unknown error\n", filename); + break; + } + } +} + +void MPQArchive::close() +{ + libmpq__archive_close(mpq_a); +} + +MPQFile::MPQFile(const char* filename): +eof(false), buffer(0), pointer(0), size(0) +{ + for (std::deque::iterator i = MPQHandler->Archives.begin(); i != MPQHandler->Archives.end();++i) + { + mpq_archive* mpq_a = (*i)->mpq_a; + + uint32_t filenum; + if(libmpq__file_number(mpq_a, filename, &filenum)) + continue; + libmpq__off_t transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size<=1) { + // printf("warning: file %s has size %d; cannot Read.\n", filename, size); + eof = true; + buffer = 0; + return; + } + buffer = new char[size]; + + //libmpq_file_getdata + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ + return; + + } + eof = true; + buffer = 0; +} + +size_t MPQFile::Read(void* dest, size_t bytes) +{ + if (eof) + return 0; + + size_t rpos = pointer + bytes; + if (rpos > size) { + bytes = size - pointer; + eof = true; + } + + memcpy(dest, &(buffer[pointer]), bytes); + + pointer = rpos; + + return bytes; +} + +void MPQFile::seek(int offset) +{ + pointer = offset; + eof = (pointer >= size); +} + +void MPQFile::seekRelative(int offset) +{ + pointer += offset; + eof = (pointer >= size); +} + +void MPQFile::close() +{ + if (buffer) + delete[] buffer; + buffer = 0; + eof = true; +} + +FILE* MPQFile::GetFileStream() +{ + FILE* file = tmpfile(); + fwrite(buffer, sizeof(char), size, file); + fseek(file, 0, SEEK_SET); + return file; +} diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h new file mode 100644 index 00000000000..dd566bccff5 --- /dev/null +++ b/src/tools/mesh_extractor/MPQ.h @@ -0,0 +1,88 @@ +#ifndef MPQ_H +#define MPQ_H + +#include "libmpq/mpq.h" +#include "Common.h" +#include +#include +#include +#include +#include + +using namespace std; + +class MPQArchive +{ + +public: + mpq_archive_s *mpq_a; + + MPQArchive(const char* filename); + void close(); + + void GetFileListTo(vector& filelist) { + uint32_t filenum; + if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; + libmpq__off_t size, transferred; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + char *buffer = new char[size]; + + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + + char seps[] = "\n"; + char* token; + + token = strtok( buffer, seps ); + uint32 counter = 0; + while ((token != NULL) && (counter < size)) { + //cout << token << endl; + token[strlen(token) - 1] = 0; + string s = token; + filelist.push_back(s); + counter += strlen(token) + 2; + token = strtok(NULL, seps); + } + + delete[] buffer; + } +}; + +class MPQFile +{ + //MPQHANDLE handle; + bool eof; + char *buffer; + libmpq__off_t pointer,size; + + // disable copying + MPQFile(const MPQFile& /*f*/) {} + void operator=(const MPQFile& /*f*/) {} + +public: + MPQFile(const char* filename); // filenames are not case sensitive + ~MPQFile() { close(); } + size_t Read(void* dest, size_t bytes); + FILE* GetFileStream(); + size_t getSize() { return size; } + size_t getPos() { return pointer; } + char* getBuffer() { return buffer; } + char* getPointer() { return buffer + pointer; } + bool isEof() { return eof; } + void seek(int offset); + void seekRelative(int offset); + void close(); +}; + +inline void flipcc(char *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + +#endif diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp new file mode 100644 index 00000000000..429b09ffe02 --- /dev/null +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -0,0 +1,58 @@ +#include "MPQManager.h" +#include "MPQ.h" + +char* MPQManager::Files[] = { + "common.MPQ", + "common-2.MPQ", + "expansion.MPQ", + "lichking.MPQ", + "patch.MPQ", + "patch-2.MPQ", + "patch-3.MPQ" +}; + +void MPQManager::Initialize() +{ + LoadMPQs(); +} + +void MPQManager::LoadMaps() +{ + +} + +void MPQManager::LoadMPQs() +{ + // Load the locale MPQ files first + char filename[512]; + + /*sprintf(filename,"Data/%s/locale-%s.MPQ", langs[locale], langs[locale]);*/ + Archives.push_front(new MPQArchive("Data/enUS/locale-enUS.MPQ")); + + for(int i = 0; i < 3; ++i) + { + char ext[3] = ""; + if (i) + sprintf(ext, "-%i", i + 1); + + sprintf(filename, "Data/enUS/patch-enUS%s.MPQ", ext); + Archives.push_front(new MPQArchive(filename)); + } + + // Now load the common MPQ files + int count = sizeof(Files) / sizeof(char*); + for (int i = 0; i < count; ++i) + { + sprintf(filename, "Data/%s", Files[i]); + Archives.push_front(new MPQArchive(filename)); + } + printf("Loaded %u MPQ files succesfully", Archives.size()); +} + +FILE* MPQManager::GetFile( std::string path ) +{ + MPQFile file(path.c_str()); + if (file.isEof()) + return NULL; + return file.GetFileStream(); +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h new file mode 100644 index 00000000000..e10066ae4a6 --- /dev/null +++ b/src/tools/mesh_extractor/MPQManager.h @@ -0,0 +1,24 @@ +#ifndef MPQ_MANAGER_H +#define MPQ_MANAGER_H + +#include "MPQ.h" + +class MPQManager +{ +public: + MPQManager() {} + ~MPQManager() {} + + void Initialize(); + void LoadMaps(); + FILE* GetFile(std::string path); + + std::deque Archives; + + static char* Files[]; +protected: + void LoadMPQs(); +}; + +extern MPQManager* MPQHandler; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp new file mode 100644 index 00000000000..95f8c2e56c0 --- /dev/null +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -0,0 +1,77 @@ +#include "MapChunk.h" +#include "ADT.h" + +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : adt(_adt), Source(chunk), Vertices(NULL) +{ + FILE* stream = chunk->GetStream(); + Header.Read(stream); + fseek(stream, chunk->Offset, SEEK_SET); + GenerateVertices(stream); +} + +void MapChunk::GenerateTriangles() +{ + Triangles.reserve(256); + for (int y = 0; y < 8; y++) + { + for (int x = 0; x < 8; x++) + { + if (HasHole(Header.Holes, x / 2, y / 2)) + continue; + + uint32 topLeft = (17 * y) + x; + uint32 topRight = (17 * y) + x + 1; + uint32 bottomLeft = (17 * (y + 1)) + x; + uint32 bottomRight = (17 * (y + 1)) + x + 1; + uint32 center = (17 * y) + 9 + x; + + uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; + if (ADT.LiquidHandler && ADT.LiquidHandler.MCNKData) + { + var data = ADT.LiquidHandler.MCNKData[Index]; + uint32 maxHeight = std::max( + std::max( + std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), + Vertices[bottomRight].z), Vertices[center].z); + if (data && data->IsWater(x, y, maxHeight)) + triangleType = Constants::TRIANGLE_TYPE_WATER; + } + + Triangles.push_back(new Triangle(triangleType, topRight, topLeft, center)); + Triangles.push_back(new Triangle(triangleType, topLeft, bottomLeft, center)); + Triangles.push_back(new Triangle(triangleType, bottomLeft, bottomRight, center)); + Triangles.push_back(new Triangle(triangleType, bottomRight, topRight, center)); + } + } +} + +MapChunk::~MapChunk() +{ + delete[] Vertices; +} + +void MapChunk::GenerateVertices( FILE* stream ) +{ + fseek(stream, Header.OffsetMCVT, SEEK_CUR); + int32 vertIndex = 0; + Vertices = new Vector3[125]; + + for (int j = 0; j < 17; j++) + { + int values = j % 2 ? 8 : 9; + for (int i = 0; i < values; i++) + { + float tmp; + fread(&tmp, sizeof(float), 1, stream); + Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); + if (values == 8) + vert.y -= Constants::UnitSize * 0.5f; + Vertices[vertIndex++] = vert; + } + } +} + +bool MapChunk::HasHole( uint32 map, int x, int y ) +{ + return (map & 0x0000FFFF) & ((1 << x) << (y << 2)); +} diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h new file mode 100644 index 00000000000..034429a81ec --- /dev/null +++ b/src/tools/mesh_extractor/MapChunk.h @@ -0,0 +1,25 @@ +#ifndef MAPCHUNK_H +#define MAPCHUNK_H +#include "Chunk.h" +#include "Utils.h" +#include "Constants.h" +#include +class ADT; + +class MapChunk +{ +public: + MapChunk(ADT* _adt, Chunk* chunk); + ~MapChunk(); + + void GenerateTriangles(); + void GenerateVertices(FILE* stream); + static bool HasHole(uint32 map, int x, int y); + ADT* adt; + Chunk* Source; + MapChunkHeader Header; + Vector3* Vertices; + std::vector > Triangles; + int32 Index; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp new file mode 100644 index 00000000000..0220627cbcc --- /dev/null +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -0,0 +1,34 @@ +#include "MPQManager.h" +#include "WDT.h" +#include "ContinentBuilder.h" +#include "Cache.h" + +MPQManager* MPQHandler; +CacheClass* Cache; + +void ExtractAllMaps() +{ + WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); + if (!wdt.IsValid) + return; + printf("Model valid!"); + if (wdt.IsGlobalModel) + { + printf("Unsupported"); + return; + } + ContinentBuilder builder("DalaranPrison", &wdt); + builder.Build(); +} + +int main(int argc, char* argv[]) +{ + system("pause"); + Cache = new CacheClass(); + MPQHandler = new MPQManager(); + MPQHandler->Initialize(); + MPQHandler->LoadMaps(); + ExtractAllMaps(); + return 0; +} + diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp new file mode 100644 index 00000000000..a1c67d23f28 --- /dev/null +++ b/src/tools/mesh_extractor/Model.cpp @@ -0,0 +1,49 @@ +#include "Model.h" +#include "MPQManager.h" +#include "Utils.h" + +Model::Model( std::string path ) +{ + Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + Header.Read(Stream); + if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && + Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) + { + IsCollidable = true; + ReadVertices(Stream); + ReadBoundingNormals(Stream); + ReadBoundingTriangles(Stream); + } +} + +void Model::ReadVertices( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); + Vertices.reserve(Header.CountBoundingVertices); + for (int i = 0; i < Header.CountBoundingVertices; ++i) + Vertices[i] = Vector3::Read(stream); +} + +void Model::ReadBoundingTriangles( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); + Triangles.reserve(Header.CountBoundingTriangles / 3); + for (int i = 0; i < Header.CountBoundingTriangles / 3; i++) + { + Triangle tri; + tri.Type = Constants::TRIANGLE_TYPE_DOODAD; + fread(&tri.V0, sizeof(uint16), 1, stream); + fread(&tri.V1, sizeof(uint16), 1, stream); + fread(&tri.V2, sizeof(uint16), 1, stream); + Triangles[i] = tri; + } +} + +void Model::ReadBoundingNormals( FILE* stream ) +{ + fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); + Normals.reserve(Header.CountBoundingNormals); + for (int i = 0; i < Header.CountBoundingNormals; i++) + Normals[i] = Vector3::Read(stream); +} + diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h new file mode 100644 index 00000000000..a5b8338461d --- /dev/null +++ b/src/tools/mesh_extractor/Model.h @@ -0,0 +1,21 @@ +#ifndef MODEL_H +#define MODEL_H +#include +#include "Utils.h" + +class Model +{ +public: + Model(std::string path); + + void ReadVertices(FILE* stream); + void ReadBoundingTriangles(FILE* stream); + void ReadBoundingNormals(FILE* stream); + ModelHeader Header; + std::vector Vertices; + std::vector Normals; + std::vector > Triangles; + bool IsCollidable; + FILE* Stream; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp new file mode 100644 index 00000000000..3ed2ee49604 --- /dev/null +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -0,0 +1,21 @@ +#include "ObjectDataHandler.h" +#include "Chunk.h" +#include "ADT.h" +#include "ChunkedData.h" + +void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) +{ + if (!Source->HasObjectData) + return; + // fuck it blizzard, why is this crap necessary? + int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); + if (firstIndex == -1) + return; + if (firstIndex + chunk->Index > Source->ObjectData->Chunks.size()) + return; + Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; + if (ourChunk->Length == 0) + return; + ChunkedData* subChunks = new ChunkedData(ourChunk->GetStream(), ourChunk->Length, 2); + ProcessInternal(subChunks); +} diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h new file mode 100644 index 00000000000..834bf66bcfb --- /dev/null +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -0,0 +1,15 @@ +#ifndef ODATA_HNDL_H +#define ODATA_HNDL_H +#include "ADT.h" +#include "MapChunk.h" + +class ObjectDataHandler +{ +public: + ObjectDataHandler(ADT* _adt) : Source(_adt) {} + + void ProcessMapChunk(MapChunk* chunk); + virtual void ProcessInternal(ChunkedData* data) = 0; + ADT* Source; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp new file mode 100644 index 00000000000..070b9d70050 --- /dev/null +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -0,0 +1,37 @@ +#include "TileBuilder.h" +#include "Constants.h" + +TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608) +{ + // Cell Size = TileSize / TileVoxelSize + // 1800 = TileVoxelSize + Config.cs = Constants::TileSize / 1800; + // Cell Height + Config.ch = 0.3f; + // Min Region Area = 6^2 + Config.minRegionArea = 36; + // Merge Region Area = 12^2 + Config.mergeRegionArea = 144; + Config.walkableSlopeAngle = 50.0f; + Config.detailSampleDist = 3.0f; + Config.detailSampleMaxError = 1.25f; + Config.walkableClimb = 1.0f / Config.ch; + Config.walkableHeight = 2.1f / Config.ch; + Config.walkableRadius = 0.6f / Config.cs; + Config.maxEdgeLen = Config.walkableRadius * 8; + Config.borderSize = Config.walkableRadius + 8; + Config.width = 1800; + Config.maxVertsPerPoly = 6; + Config.maxSimplificationError = 1.3f; +} + +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) +{ + float origin[3] = Constants::Origin; + bmin = new float[3]; + bmax = new float[3]; + bmin[0] = origin[0] + (Constants::TileSize * X); + bmin[2] = origin[2] + (Constants::TileSize * Y); + bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); + bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h new file mode 100644 index 00000000000..badb05295e5 --- /dev/null +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -0,0 +1,22 @@ +#ifndef TILE_BUILD_H +#define TILE_BUILD_H +#include +#include "Recast.h" + +#include "Geometry.h" + +class TileBuilder +{ +public: + TileBuilder(std::string world, int x, int y); + void CalculateTileBounds(float*& bmin, float*& bmax); + uint8* Build(); + + std::string World; + int X; + int Y; + int MapId; + rcConfig Config; + Geometry* _Geometry; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp new file mode 100644 index 00000000000..03473eb0794 --- /dev/null +++ b/src/tools/mesh_extractor/Utils.cpp @@ -0,0 +1,163 @@ +#include "Utils.h" +#include "Constants.h" +#include +#include "g3d/Matrix4.h" + +const float Constants::TileSize = 533.0f + (1/3.0f); +const float Constants::MaxXY = 32.0f * Constants::TileSize; +const float Constants::ChunkSize = Constants::TileSize / 16.0f; +const float Constants::UnitSize = Constants::ChunkSize / 8.0f; +const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; +const float Constants::PI = 3.1415926f; + +void Utils::Reverse(char word[]) +{ + int len = strlen(word); + for (int i = 0;i < len / 2; i++) + { + word[i] ^= word[len-i-1]; + word[len-i-1] ^= word[i]; + word[i] ^= word[len-i-1]; + } +} + +std::string Utils::ReadString( FILE* file ) +{ + std::string ret; + int i = 0; + while (true) + { + char b; + fread(&b, sizeof(char), 1, file); + if (b == 0) + break; + ret[i++] = b; + } + return ret; +} + +uint32 Utils::Size( FILE* file ) +{ + // store the old position + uint32 offset = ftell(file); + // Get file size + fseek(file, 0, SEEK_END); + uint32 size = ftell(file); + // reset back to the old position + fseek(file, offset, SEEK_SET); + return size; +} + +Vector3 Utils::ToRecast( Vector3 val ) +{ + return Vector3(-val.y, val.z, -val.x); +} + +std::string Utils::GetAdtPath( std::string world, int x, int y ) +{ + return "World\\Maps\\" + world + "\\" + world + "_" + Utils::ToString(x) + "_" + Utils::ToString(y) + ".adt"; +} + +std::string Utils::FixModelPath( std::string path ) +{ + std::string::size_type idx = path.rfind("."); + // Bizarre way of changing extension but... + if (idx != std::string::npos) + { + path[idx + 1] = "M"; + path[idx + 2] = "2"; + } + return path; +} + +G3D::Matrix4 Utils::RotationX(float angle) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[2][2] = _cos; + ret[2][3] = _sin; + ret[3][2] = -_sin; + ret[3][3] = _cos; + return ret; +} + +G3D::Matrix4 Utils::GetTransformation( IDefinition def ) +{ + G3D::Matrix4 translation; + if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) + translation = G3D::Matrix4::identity(); + else + translation = G3D::Matrix4::translation(-(def.Position.z - Constants::MaxXY), + -(def.Position.x - Constants::MaxXY), def.Position.y); + + G3D::Matrix4 rotation = RotationX(ToRadians(def.Rotation.z)) * RotationY(ToRadians(def.Rotation.x)) * RotationZ(ToRadians(def.Rotation.y + 180)); + if (def.Scale() < 1.0f || def.Scale() > 1.0f) + return G3D::Matrix4::scale(def.Scale()) * rotation * translation; + return rotation * translation; +} + +G3D::Matrix4 Utils::RotationY( float angle ) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[1][3] = -_sin; + ret[3][1] = _sin; + ret[3][3] = _cos; + return ret; +} + +G3D::Matrix4 Utils::RotationZ( float angle ) +{ + float _cos = cos(angle); + float _sin = sin(angle); + Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[1][2] = _sin; + ret[2][1] = -_sin; + ret[2][2] = _cos; + return ret; +} + +float Utils::ToRadians( float degrees ) +{ + return Constants::PI * degrees / 180.0f; +} + +Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix matrix ) +{ + Vector3 ret; + ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; + ret.y = vec.x * matrix[1][2] + vec.y * matrix[2][2] + vec.z * matrix[3][2] + matrix[4][2]; + ret.z = vec.x * matrix[1][3] + vec.y * matrix[2][3] + vec.z * matrix[3][3] + matrix[4][3]; + return ret; +} + +std::string Utils::GetPathBase( std::string path ) +{ + int lastIndex = path.find_last_of("."); + if (lastIndex != std::string::npos) + return path.substr(0, lastindex); + return path; +} + +Vector3 Vector3::Read( FILE* file ) +{ + Vector3 ret; + fread(&ret, sizeof(Vector3), 1, file); + return ret; +} + +Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y) +{ + if (Utils::Distance(height, 0.0f) > 0.5f) + basePosition.z = 0.0f; + return Utils::VectorTransform(basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height), transformation); +} + +float Utils::Distance( float x, float y ) +{ + return sqrt(x*x + y*y); +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h new file mode 100644 index 00000000000..cda5f4c7cd8 --- /dev/null +++ b/src/tools/mesh_extractor/Utils.h @@ -0,0 +1,497 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include + +#include "g3d/Matrix4.h" + +#include "Common.h" +#include "Constants.h" + +struct Vector3 +{ + Vector3() {} + Vector3(float X, float Y, float Z) : x(X), y(Y), z(Z) {} + float x; + float y; + float z; + Vector3 operator+(Vector3 right, Vector3 left) + { + return Vector3(right.x+left.x, right.y+left.y, right.z+left.z); + } + static Vector3 Read(FILE* file); +}; + +struct TilePos +{ + TilePos(int x, int y) : X(x), Y(y) {} + int X; + int Y; +}; + +template +struct Triangle +{ + Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} + T V0; + T V1; + T V2; + Constants::TriangleType Type; +}; + +class MapChunkHeader +{ +public: + MapChunkHeader() {} + uint32 Flags; + uint32 IndexX; + uint32 IndexY; + uint32 Layers; + uint32 DoodadRefs; + uint32 OffsetMCVT; + uint32 OffsetMCNR; + uint32 OffsetMCLY; + uint32 OffsetMCRF; + uint32 OffsetMCAL; + uint32 SizeMCAL; + uint32 OffsetMCSH; + uint32 SizeMCSH; + uint32 AreaId; + uint32 MapObjectRefs; + uint32 Holes; + uint32* LowQualityTextureMap; + uint32 PredTex; + uint32 NumberEffectDoodad; + uint32 OffsetMCSE; + uint32 SoundEmitters; + uint32 OffsetMCLQ; + uint32 SizeMCLQ; + Vector3 Position; + uint32 OffsetMCCV; + + void Read(FILE* stream) + { + fread(&Flags, sizeof(uint32), 1, stream); + fread(&IndexX, sizeof(uint32), 1, stream); + fread(&IndexY, sizeof(uint32), 1, stream); + fread(&Layers, sizeof(uint32), 1, stream); + fread(&DoodadRefs, sizeof(uint32), 1, stream); + fread(&OffsetMCVT, sizeof(uint32), 1, stream); + fread(&OffsetMCNR, sizeof(uint32), 1, stream); + fread(&OffsetMCLY, sizeof(uint32), 1, stream); + fread(&OffsetMCRF, sizeof(uint32), 1, stream); + fread(&OffsetMCAL, sizeof(uint32), 1, stream); + fread(&SizeMCAL, sizeof(uint32), 1, stream); + fread(&OffsetMCSH, sizeof(uint32), 1, stream); + fread(&SizeMCSH, sizeof(uint32), 1, stream); + fread(&AreaId, sizeof(uint32), 1, stream); + fread(&MapObjectRefs, sizeof(uint32), 1, stream); + fread(&Holes, sizeof(uint32), 1, stream); + LowQualityTextureMap = new uint32[4]; + fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + fread(&PredTex, sizeof(uint32), 1, stream); + fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + fread(&OffsetMCSE, sizeof(uint32), 1, stream); + fread(&SoundEmitters, sizeof(uint32), 1, stream); + fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + fread(&SizeMCLQ, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + fread(&OffsetMCCV, sizeof(uint32), 1, stream); + } +}; + +class MHDR +{ +public: + MHDR() {} + uint32 Flags; + uint32 OffsetMCIN; + uint32 OffsetMTEX; + uint32 OffsetMMDX; + uint32 OffsetMMID; + uint32 OffsetMWMO; + uint32 OffsetMWID; + uint32 OffsetMDDF; + uint32 OffsetMODF; + uint32 OffsetMFBO; + uint32 OffsetMH2O; + uint32 OffsetMTFX; + + void Read(FILE* stream) + { + fread(&Flags, sizeof(uint32), 1, stream); + fread(&OffsetMCIN, sizeof(uint32), 1, stream); + fread(&OffsetMTEX, sizeof(uint32), 1, stream); + fread(&OffsetMMDX, sizeof(uint32), 1, stream); + fread(&OffsetMMID, sizeof(uint32), 1, stream); + fread(&OffsetMWMO, sizeof(uint32), 1, stream); + fread(&OffsetMWID, sizeof(uint32), 1, stream); + fread(&OffsetMDDF, sizeof(uint32), 1, stream); + fread(&OffsetMODF, sizeof(uint32), 1, stream); + fread(&OffsetMFBO, sizeof(uint32), 1, stream); + fread(&OffsetMH2O, sizeof(uint32), 1, stream); + fread(&OffsetMTFX, sizeof(uint32), 1, stream); + } +}; + +class ModelHeader +{ +public: + char Magic[5]; + uint32 Version; + uint32 LengthModelName; + uint32 OffsetName; + uint32 ModelFlags; + uint32 CountGlobalSequences; + uint32 OffsetGlobalSequences; + uint32 CountAnimations; + uint32 OffsetAnimations; + uint32 CountAnimationLookup; + uint32 OffsetAnimationLookup; + uint32 CountBones; + uint32 OffsetBones; + uint32 CountKeyBoneLookup; + uint32 OffsetKeyBoneLookup; + uint32 CountVertices; + uint32 OffsetVertices; + uint32 CountViews; + uint32 CountColors; + uint32 OffsetColors; + uint32 CountTextures; + uint32 OffsetTextures; + uint32 CountTransparency; + uint32 OffsetTransparency; + uint32 CountUvAnimation; + uint32 OffsetUvAnimation; + uint32 CountTexReplace; + uint32 OffsetTexReplace; + uint32 CountRenderFlags; + uint32 OffsetRenderFlags; + uint32 CountBoneLookup; + uint32 OffsetBoneLookup; + uint32 CountTexLookup; + uint32 OffsetTexLookup; + uint32 CountTexUnits; + uint32 OffsetTexUnits; + uint32 CountTransLookup; + uint32 OffsetTransLookup; + uint32 CountUvAnimLookup; + uint32 OffsetUvAnimLookup; + Vector3 VertexBox[2]; + float VertexRadius; + Vector3 BoundingBox[2]; + float BoundingRadius; + uint32 CountBoundingTriangles; + uint32 OffsetBoundingTriangles; + uint32 CountBoundingVertices; + uint32 OffsetBoundingVertices; + uint32 CountBoundingNormals; + uint32 OffsetBoundingNormals; + + void Read(FILE* stream) + { + fread(&Magic, sizeof(char), 4, stream); + Magic[4] = '\0'; // null-terminate it. + fread(&Version, sizeof(uint32), 1, stream); + fread(&LengthModelName, sizeof(uint32), 1, stream); + fread(&OffsetName, sizeof(uint32), 1, stream); + fread(&ModelFlags, sizeof(uint32), 1, stream); + fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + fread(&CountAnimations, sizeof(uint32), 1, stream); + fread(&OffsetAnimations, sizeof(uint32), 1, stream); + fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + fread(&CountBones, sizeof(uint32), 1, stream); + fread(&OffsetBones, sizeof(uint32), 1, stream); + fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&CountVertices, sizeof(uint32), 1, stream); + fread(&OffsetVertices, sizeof(uint32), 1, stream); + fread(&CountViews, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + fread(&CountRenderFlags, sizeof(uint32), 1, stream); + fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + fread(&CountBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + fread(&CountTexLookup, sizeof(uint32), 1, stream); + fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + fread(&CountTexUnits, sizeof(uint32), 1, stream); + fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + fread(&CountTransLookup, sizeof(uint32), 1, stream); + fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + VertexBox[0] = Vector3::Read(stream); + VertexBox[1] = Vector3::Read(stream); + fread(&VertexRadius, sizeof(float), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); + fread(&BoundingRadius, sizeof(float), 1, stream); + fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + } +}; + +class WorldModelHeader +{ +public: + WorldModelHeader() {} + uint32 CountMaterials; + uint32 CountGroups; + uint32 CountPortals; + uint32 CountLights; + uint32 CountModels; + uint32 CountDoodads; + uint32 CountSets; + uint32 AmbientColorUnk; + uint32 WmoId; + Vector3 BoundingBox[2]; + uint32 LiquidTypeRelated; + + static WorldModelHeader Read(FILE* stream) + { + WorldModelHeader ret; + fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + fread(&ret.CountGroups, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountLights, sizeof(uint32), 1, stream); + fread(&ret.CountModels, sizeof(uint32), 1, stream); + fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + fread(&ret.CountSets, sizeof(uint32), 1, stream); + fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + return ret; + } +}; + +class DoodadInstance +{ +public: + DoodadInstance() {} + uint32 FileOffset; + std::string File; + Vector3 Position; + float QuatW; + float QuatX; + float QuatY; + float QuatZ; + float Scale; + uint32 LightColor; + + static DoodadInstance Read(FILE* stream) + { + DoodadInstance ret; + fread(&ret.FileOffset, sizeof(uint32), 1, stream); + ret.Position = Vector3::Read(stream); + fread(&ret.QuatW, sizeof(float), 1, stream); + fread(&ret.QuatX, sizeof(float), 1, stream); + fread(&ret.QuatY, sizeof(float), 1, stream); + fread(&ret.QuatZ, sizeof(float), 1, stream); + fread(&ret.Scale, sizeof(float), 1, stream); + fread(&ret.LightColor, sizeof(uint32), 1, stream); + return ret; + } +}; + +class DoodadSet +{ +public: + DoodadSet() {} + std::string Name; + uint32 FirstInstanceIndex; + uint32 CountInstances; + uint32 UnknownZero; + + static DoodadSet Read(FILE* stream) + { + DoodadSet ret; + char name[21]; + fread(&name, sizeof(char), 20, stream); + name[20] = '\0'; + ret.Name = name; + fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + fread(&ret.CountInstances, sizeof(uint32), 1, stream); + fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + return ret; + } +} + +class LiquidHeader +{ +public: + LiquidHeader() {} + uint32 CountXVertices; + uint32 CountYVertices; + uint32 Width; + uint32 Height; + Vector3 BaseLocation; + uint16 MaterialId; + + static LiquidHeader Read(FILE* stream) + { + LiquidHeader ret; + fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + fread(&ret.Width, sizeof(uint32), 1, stream); + fread(&ret.Height, sizeof(uint32), 1, stream); + ret.BaseLocation = Vector3::Read(stream); + fread(&ret.MaterialId, sizeof(uint16), 1, stream); + return ret; + } +}; + +class LiquidData +{ +public: + LiquidData() {} + float** HeightMap; + uint8** RenderFlags; + + bool ShouldRender(int x, int y) + { + return RenderFlags[x][y] != 0x0F; + } + + public static LiquidData Read(FILE* stream, LiquidHeader header) + { + LiquidData ret; + ret.HeightMap = new float*[header.CountXVertices]; + for (int i = 0; i < header.CountXVertices; ++i) + ret.HeightMap[i] = new float[header.CountYVertices]; + + ret.RenderFlags = new uint8*[header.Width]; + for (int i = 0; i < header.Width; ++i) + ret.RenderFlags[i] = new uint8[header.Height]; + + for (int y = 0; y < header.CountYVertices; y++) + { + for (int x = 0; x < header.CountXVertices; x++) + { + uint32 discard; + fread(&discard, sizeof(uint32), 1, stream); + float tmp; + fread(&tmp, sizeof(float), 1, stream); + ret.HeightMap[x][y] = tmp; + } + } + + for (int y = 0; y < header.Height; y++) + { + for (int x = 0; x < header.Width; x++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + ret.RenderFlags[x][y] = tmp; + } + } + + return ret; + } +}; + +class H2ORenderMask +{ +public: + H2ORenderMask() {} + uint8 Mask[8]; + + bool ShouldRender(int x, int y) + { + return (Mask[y] >> x & 1) != 0; + } + + static H2ORenderMask Read(FILE* stream) + { + H2ORenderMask ret; + fread(&ret.Mask, sizeof(uint8), 8, stream); + return ret; + } +}; + +class MCNKLiquidData +{ +public: + MCNKLiquidData() {} + const float MaxStandableHeight = 1.5f; + + float** Heights; + H2ORenderMask* Mask; + + bool IsWater(int x, int y, float height) + { + if (!Heights || !Mask) + return false; + if (!Mask->ShouldRender(x, y)) + return false; + float diff = Heights[x][y] - height; + if (diff > MaxStandableHeight) + return true; + return false; + } +}; + +// Dummy class to act as an interface. +class IDefinition +{ +public: + Vector3 Position; + Vector3 Rotation; + virtual float Scale() = 0; +}; + +class Utils +{ +public: + static void Reverse(char word[]); + static std::string ReadString(FILE* file); + static uint32 Size(FILE* file); + static Vector3 ToRecast( Vector3 val ); + static std::string GetAdtPath(std::string world, int x, int y); + static std::string FixModelPath(std::string path); + static G3D::Matrix4 GetTransformation(IDefinition def); + /// They say its better to declare template functions in the header files. + template + static std::string ToString(T val) + { + std::stringstream ss; + ss << val; + return ss.str(); + } + static G3D::Matrix4 RotationX(float angle); + static G3D::Matrix4 RotationY(float angle); + static G3D::Matrix4 RotationZ(float angle); + static float ToRadians(float degrees); + static Vector3 VectorTransform(Vector3 vec, G3D::Matrix matrix); + static std::string GetPathBase(std::string path); + static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); + static float Distance(float x, float y); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp new file mode 100644 index 00000000000..c06d8ac9677 --- /dev/null +++ b/src/tools/mesh_extractor/WDT.cpp @@ -0,0 +1,55 @@ +#include "WDT.h" +#include "Chunk.h" +#include "ChunkedData.h" +#include "Utils.h" +#include "WorldModelHandler.h" + +WDT::WDT(std::string file) : IsValid(false), IsGlobalModel(false) +{ + Data = new ChunkedData(file, 2); + ReadTileTable(); + ReadGlobalModel(); +} + +void WDT::ReadGlobalModel() +{ + Chunk* fileChunk = Data->GetChunkByName("MWMO"); + Chunk* defChunk = Data->GetChunkByName("MODF"); + if (!fileChunk || !defChunk) + return; + + IsGlobalModel = true; + ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); + ModelFile = Utils::ReadString(fileChunk->GetStream()); +} + +void WDT::ReadTileTable() +{ + Chunk* chunk = Data->GetChunkByName("MAIN"); + if (!chunk) + return; + IsValid = true; + FILE* stream = chunk->GetStream(); + for (int y = 0; y < 64; ++y) + { + for (int x = 0; x < 64; ++x) + { + const uint32 hasTileFlag = 0x1; + uint32 flags; + uint32 discard; + fread(&flags, sizeof(uint32), 1, stream); + fread(&discard, sizeof(uint32), 1, stream); + if (flags & hasTileFlag) + TileTable.push_back(TilePos(x, y)); + + } + } +} + +bool WDT::HasTile( int x, int y ) +{ + for (std::vector::iterator itr = TileTable.begin(); itr != TileTable.end(); ++itr) + if (itr->X == x && itr->Y == y) + return true; + return false; +} diff --git a/src/tools/mesh_extractor/WDT.h b/src/tools/mesh_extractor/WDT.h new file mode 100644 index 00000000000..a12aa65218b --- /dev/null +++ b/src/tools/mesh_extractor/WDT.h @@ -0,0 +1,27 @@ +#ifndef WDT_H +#define WDT_H +#include +#include + +#include "ChunkedData.h" +#include "WorldModelHandler.h" +#include "Utils.h" + +class WDT +{ +public: + WDT(std::string file); + + ChunkedData* Data; + std::vector TileTable; + bool IsGlobalModel; + bool IsValid; + std::string ModelFile; + WorldModelDefinition ModelDefinition; + bool HasTile(int x, int y); +private: + void ReadGlobalModel(); + void ReadTileTable(); +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp new file mode 100644 index 00000000000..308c7ff7b86 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -0,0 +1,122 @@ +#include "WorldModelGroup.h" +#include "ChunkedData.h" +#include "Chunk.h" + +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false) +{ + Data = new ChunkedData(path); + if (!Data->Stream) + { + IsBad = true; + return; + } + Chunk* mainChunk = Data->GetChunkByName("MOGP"); + int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); + if (firstSub == -1) + return; + FILE* stream = mainChunk->GetStream(); + fseek(stream, firstSub, SEEK_SET); + SubData = new ChunkedData(stream, mainChunk->Length - firstSub); + + ReadBoundingBox(); + ReadMaterials(); + ReadTriangles(); + ReadVertices(); + ReadNormals(); + ReadLiquid(); +} + +void WorldModelGroup::ReadNormals() +{ + Chunk* chunk = SubData->GetChunkByName("MONR"); + if (!chunk) + return; + + uint32 normalCount = chunk->Length / 12; + Assert(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + Normals.reserve(normalCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < normalCount; i++) + Normals[i] = Vector3::Read(stream); +} + +void WorldModelGroup::ReadLiquid() +{ + Chunk* chunk = SubData->GetChunkByName("MLIQ"); + if (!chunk) + return; + + HasLiquidData = true; + FILE* stream = chunk->GetStream(); + LiquidDataHeader = LiquidHeader.Read(stream); + LiquidDataGeometry = LiquidData.Read(stream, LiquidDataHeader); +} + +void WorldModelGroup::ReadVertices() +{ + Chunk* chunk = SubData->GetChunkByName("MOVT"); + if (!chunk) + return; + + uint32 verticeCount = chunk.Length / 12; + Vertices.reserve(verticeCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < verticeCount; i++) + Vertices.push_back(Vector3::Read(stream)); +} + +void WorldModelGroup::ReadTriangles() +{ + Chunk* chunk = SubData->GetChunkByName("MOVI"); + if (!chunk) + return; + + uint32 triangleCount = chunk.Length / 6; + Assert(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + FILE* stream = chunk.GetStream(); + Triangles.reserve(triangleCount); + for (int i = 0; i < triangleCount; i++) + { + uint16 v0; + uint16 v1; + uint16 v2; + fread(&v0, sizeof(uint16), 1, stream); + fread(&v1, sizeof(uint16), 1, stream); + fread(&v2, sizeof(uint16), 1, stream); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); + } +} + +void WorldModelGroup::ReadMaterials() +{ + Chunk* chunk = SubData->GetChunkByName("MOPY"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + uint32 triangleCount = chunk.Length / 2; + TriangleFlags.reserve(triangleCount); + TriangleMaterials.reserve(triangleCount); + for (int i = 0; i < triangleCount; i++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + TriangleFlags.push_back(tmp); + // Read again for material. + fread(&tmp, sizeof(uint8), 1, stream); + TriangleMaterials.push_back(tmp); + } +} + +void WorldModelGroup::ReadBoundingBox() +{ + Chunk* chunk = Data->GetChunkByName("MOGP"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + fseek(stream, 8, SEEK_CUR): + fread(&Flags, sizeof(uint32), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); +} diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h new file mode 100644 index 00000000000..1dc754d0221 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -0,0 +1,33 @@ +#ifndef WMOGROUP_H +#define WMOGROUP_H +#include "ChunkedData.h" +#include "Utils.h" + +class WorldModelGroup +{ +public: + WorldModelGroup(std::string path, int groupIndex); + ChunkedData* Data; + ChunkedData* SubData; + int GroupIndex; + Vector3 BoundingBox[2]; + uint32 Flags; + std::vector TriangleFlags; + std::vector TriangleMaterials; + std::vector > Triangles; + std::vector Vertices; + std::vector Normals; + + bool HasLiquidData; + bool IsBad; + LiquidHeader LiquidDataHeader; + LiquidData LiquidDataGeometry; +private: + void ReadNormals(); + void ReadLiquid(); + void ReadVertices(); + void ReadTriangles(); + void ReadMaterials(); + void ReadBoundingBox(); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp new file mode 100644 index 00000000000..e895e2bfde8 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -0,0 +1,190 @@ +#include "WorldModelHandler.h" +#include "Chunk.h" +#include "Cache.h" +#include "Common.h" +#include "g3d/Matrix4.h" +#include + +WorldModelDefinition WorldModelDefinition::Read( FILE* file ) +{ + WorldModelDefinition ret; + fread(&ret.MwidIndex, sizeof(uint32), 1, file); + fread(&ret.UniqueId, sizeof(uint32), 1, file); + ret.Position = Vector3::Read(file); + ret.Rotation = Vector3::Read(file); + ret.UpperExtents = Vector3::Read(file); + ret.LowerExtents = Vector3::Read(file); + fread(&ret.Flags, sizeof(uint16), 1, file); + fread(&ret.DooadSet, sizeof(uint16), 1, file); + uint32 discard; + fread(&discard, sizeof(uint32), 1, file); + return ret; +} + + +WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt) +{ + if (!adt->HasObjectData) + return; + ReadModelPaths(); + ReadDefinitions(); +} + +void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) +{ + if (!IsSane()) + return; + Chunk* wmoReferencesChunk = subChunks->GetChunkByName("MCRW"); + if (!wmoReferencesChunk) + return; + FILE* stream = wmoReferencesChunk->GetStream(); + uint32 refCount = wmoReferencesChunk->Length / 4; + for (int i = 0; i < refCount; i++) + { + int32 index; + fread(&index, sizeof(int32), 1, stream); + + if (index < 0 || index >= _definitions->size()) + continue; + + WorldModelDefinition wmo = (*_definitions)[index]; + + if (_drawn.find(wmo.UniqueId) != _drawn.end()) + continue; + _drawn.insert(wmo.UniqueId); + + if (wmo.MwidIndex >= _paths->size()) + continue; + + std::string path = _paths[(int) wmo.MwidIndex]; + WorldModelRoot* model = Cache->WorldModelCache.Get(path); + if (!model) + { + model = new WorldModelRoot(path); + Cache->WorldModelCache.Insert(path, model); + } + + Vertices.reserve(1000); + Triangles.reserve(1000); + + InsertModelGeometry(Vertices, Triangles, wmo, model); + } +} + +void WorldModelHandler::InsertModelGeometry( std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root ) +{ + G3D::Matrix4 transformation = Utils::GetTransformation(); + for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + { + uint32 vertOffset = verts.size(); + for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) + verts.push_back(Utils::VectorTransform(*itr2, transformation)); + + for (int i = 0; i < group->Triangles.size(); ++i) + { + // only include collidable tris + if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) + continue; + Triangle tri = group->Triangles[i]; + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset)); + } + } + + if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) + { + DoodadSet set = root->DoodadSets[def.DoodadSet]; + std::vector instances = new std::vector; + instances.reserve(set.CountInstances); + for (uint32 i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) + { + if (i >= root->DoodadInstances.size()) + break; + instances.push_back(root->DoodadInstances[i]); + } + + for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) + { + Model* model = Cache.ModelCache.Get(instance->File); + if (!model) + { + model = new Model(instance->File); + Cache.ModelCache.Insert(instance->File, model); + } + + if (!model.IsCollidable) + continue; + G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(instance, def); + int vertOffset = verts.size(); + for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) + verts.push_back(Utils::VectorTransform(*itr2, doodadTransformation)); + for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); + } + + for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) + { + if (!group->HasLiquidData) + continue; + + for (int y = 0; y < group->LiquidDataHeader.Height; y++) + { + for (int x = 0; x < group->LiquidDataHeader.Width; x++) + { + if (!group->LiquidDataGeometry.ShouldRender(x, y)) + continue; + + uint32 vertOffset = verts.size(); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x][y], x, y)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); + verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, + group->LiquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); + + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); + tris.push_back(new Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + + } + } + } + } +} + +void WorldModelHandler::ReadDefinitions() +{ + Chunk* chunk = Source->ObjectData->GetChunkByName("MODF"); + if (!chunk) + return; + + const int32 definitionSize = 64; + uint32 definitionCount = chunk.Length / definitionSize; + _definitions = new new std::vector; + _definitions->reserve(definitionCount); + FILE* stream = chunk->GetStream(); + for (int i = 0; i < definitionCount; i++) + _definitions->push_back(WorldModelDefinition::Read(stream)); +} + +void WorldModelHandler::ReadModelPaths() +{ + Chunk* mwid = Source->ObjectData->GetChunkByName("MWID"); + Chunk* mwmo = Source->ObjectData->GetChunkByName("MWMO"); + if (!mwid || !mwmo) + return; + + uint32 paths = mwid.Length / 4; + _paths = new std::vector; + _paths->reserve(paths); + for (int i = 0; i < paths; i++) + { + FILE* stream = mwid->GetStream(); + fseek(stream, i * 4, SEEK_CUR); + uint32 offset; + fread(&offset, sizeof(uint32), 1, stream); + FILE* dataStream = mwmo->GetStream(); + fseek(dataStream, offset + mwmo->Offset, SEEK_SET); + _paths->push_back(Utils::ReadString(dataStream)); + } +} diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h new file mode 100644 index 00000000000..2236339de9d --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -0,0 +1,42 @@ +#ifndef WMODEL_HNDL_H +#define WMODEL_HNDL_H +#include "Common.h" +#include "Utils.h" +#include "ObjectDataHandler.h" +#include "ADT.h" + +#include +#include + +struct WorldModelDefinition : IDefinition +{ + WorldModelDefinition() {} + uint32 MwidIndex; + uint32 UniqueId; + Vector3 UpperExtents; + Vector3 LowerExtents; + uint16 Flags; + uint16 DoodadSet; + float Scale() { return 1.0f; } + static WorldModelDefinition Read(FILE* file); +}; + +class WorldModelHandler : public ObjectDataHandler +{ +public: + WorldModelHandler(ADT* adt); + + std::vector Vertices; + std::vector > Triangles; + bool IsSane() { return _definitions && _paths; } + void InsertModelGeometry(std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root); +protected: + void ProcessInternal(ChunkedData* data); +private: + void ReadDefinitions(); + void ReadModelPaths(); + std::set _drawn; + std::vector* _definitions; + std::vector* _paths; +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp new file mode 100644 index 00000000000..9764e339242 --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -0,0 +1,74 @@ +#include "WorldModelRoot.h" +#include "ChunkedData.h" +#include "Utils.h" + +WorldModelRoot::WorldModelRoot( std::string path ) +{ + Data = new ChunkedData(path); + Path = path; + ReadHeader(); + ReadGroups(); + ReadDoodadInstances(); + ReadDoodadSets(); +} + +void WorldModelRoot::ReadGroups() +{ + std::string pathBase = Utils::GetPathBase(Path); + Groups.reserve(Header.CountGroups); + for (int i = 0; i < Header.CountGroups; i++) + { + char name[200]; + sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); + WorldModelGroup group(name, i); + if (!group.IsBad) + Groups.push_back(group); + } +} + +void WorldModelRoot::ReadDoodadSets() +{ + Chunk* chunk = Data->GetChunkByName("MODS"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + Assert(chunk.Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + DoodadSets.reserve(Header.CountSets); + for (int i = 0; i < Header.CountSets; i++) + DoodadSets.push_back(DoodadSet::Read(stream)); +} + +void WorldModelRoot::ReadDoodadInstances() +{ + Chunk* chunk = Data->GetChunkByName("MODD"); + Chunk* nameChunk = Data->GetChunkByName("MODN"); + if (!chunk || !nameChunk) + return; + + const uint32 instanceSize = 40; + uint32 countInstances = chunk->Length / instanceSize; + DoodadInstances.reserve(countInstances); + for (int i = 0; i < countInstances; i++) + { + FILE* stream = chunk->GetStream(); + fseek(stream, instanceSize * i, SEEK_CUR); + DoodadInstance instance = DoodadInstance::Read(stream); + FILE* nameStream = nameChunk->GetStream(); + if (instance.FileOffset >= nameChunk->Length) + continue; + fseek(nameStream, instance.FileOffset, SEEK_CUR); + instance.File = Utils::ReadString(nameStream); + DoodadInstances.push_back(instance); + } +} + +void WorldModelRoot::ReadHeader() +{ + Chunk* chunk = Data->GetChunkByName("MOHD"); + if (!chunk) + return; + + FILE* stream = chunk->GetStream(); + Header = WorldModelHeader::Read(stream); +} diff --git a/src/tools/mesh_extractor/WorldModelRoot.h b/src/tools/mesh_extractor/WorldModelRoot.h new file mode 100644 index 00000000000..c06ff3d5d2b --- /dev/null +++ b/src/tools/mesh_extractor/WorldModelRoot.h @@ -0,0 +1,26 @@ +#ifndef WMOROOT_H +#define WMOROOT_H +#include +#include + +#include "ChunkedData.h" +#include "Utils.h" +#include "WorldModelGroup.h" + +class WorldModelRoot +{ +public: + WorldModelRoot(std::string path); + std::string Path; + ChunkedData* Data; + WorldModelHeader Header; + std::vector DoodadInstances; + std::vector DoodadSets; + std::vector Groups; +private: + void ReadGroups(); + void ReadDoodadSets(); + void ReadDoodadInstances(); + void ReadHeader(); +}; +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/readme b/src/tools/mesh_extractor/readme new file mode 100644 index 00000000000..85cd7cfc975 --- /dev/null +++ b/src/tools/mesh_extractor/readme @@ -0,0 +1,6 @@ +Experimental mesh extractor. +Original work in C# by stschake +Thanks to: +Subv +~ +For helping in the porting to C++ \ No newline at end of file -- cgit v1.2.3 From ad0cd9f40acff1ff6d7571426b4acb1ea675d7a6 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 07:59:22 -0500 Subject: Tools: Made more updates to the MeshExtractor --- src/tools/mesh_extractor/ADT.h | 10 ++-- src/tools/mesh_extractor/LiquidHandler.cpp | 96 +++++++++++++++++++++++++++++- src/tools/mesh_extractor/LiquidHandler.h | 3 + src/tools/mesh_extractor/MapChunk.cpp | 8 +-- src/tools/mesh_extractor/MapChunk.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 11 ++++ src/tools/mesh_extractor/Utils.h | 71 ++++++++++++++++++++-- 7 files changed, 186 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 18b811a4e4c..43984d0902c 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -4,17 +4,19 @@ #include "MapChunk.h" #include "DoodadHandler.h" #include "WorldModelHandler.h" +#include "LiquidHandler.h" class ADT { public: - ADT(); - ~ADT() { delete[] MapChunks; delete ObjectData; delete Data; } + ADT(std::string file); + ~ADT(); + + void Read(); ChunkedData* ObjectData; ChunkedData* Data; - // This here is not a pointer, is an array of objects ( made this way to allow the dynamic allocation ) - MapChunk* MapChunks; + std::vector MapChunks; MHDR Header; // Can we dispose of this? bool HasObjectData; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 5924c693196..3217bb2cbc6 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -1 +1,95 @@ -#include "LiquidHandler.h" \ No newline at end of file +#include "LiquidHandler.h" +#include "Utils.h" + +LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) +{ + HandleNewLiquid(); +} + +void LiquidHandler::HandleNewLiquid() +{ + Chunk* chunk = Source->Data->GetChunkByName("MH2O"); + if (!chunk) + return; + + Vertices.reserve(1000); + Triangles.reserve(1000); + + FILE* stream = chunk->GetStream(); + H2OHeader header[256]; + MCNKData.reserve(256); + for (int i = 0; i < 256; i++) + header[i] = H2OHeader::Read(stream); + + for (int i = 0; i < 256; i++) + { + H2OHeader h = header[i]; + if (h.LayerCount == 0) + continue; + fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); + H2OInformation information = H2OInformation::Read(stream); + + float** heights = new float*[9]; + for (int i = 0; i < 9; ++i) + heights[i] = new float[9]; + + H2ORenderMask renderMask; + if (information.LiquidType != 2) + { + fseek(stream, chunk->Offset + h.OffsetRender, SEEK_SET); + renderMask = H2ORenderMask::Read(stream); + if ((Utils::IsAllZero(renderMask.Mask, 8) || (information.Width == 8 && information.Height == 8)) && information.OffsetMask2) + { + fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); + uint32 size = ceil(information.Width * information.Height / 8.0f); + uint8* altMask = new uint8[size]; + fread(altMax, sizeof(uint8), size, stream); + + for (int mi = 0; mi < size; mi++) + renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; + delete[] altMask; + } + fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); + + for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) + for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) + fread(&heights[x][y], sizeof(float), 1, stream); + } + else + { + // Fill with ocean data + for (uint32 i = 0; i < 8; ++i) + renderMask.Mask[i] = 0xFF; + + for (uint32 y = 0; y < 9; ++y) + for (uint32 x = 0; x < 9; ++x) + heights[x][y] = information.HeightLevel1; + } + + MCNKData.push_back(MCNKLiquidData(heights, renderMask)); + + for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) + { + for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) + { + if (!renderMask.ShouldRender(x, y)) + continue; + + MapChunk* mapChunk = Source->MapChunks[i]; + Vector3 location = mapChunk->Header.Position; + location.y = location.y - (x * Constants::UnitSize); + location.x = location.x - (y * Constants::UnitSize); + location.z = heights[x][y]; + + uint32 vertOffset = Vertices.size(); + Vertices.push_back(location); + Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); + Vertices.push_back(new Vector3(location.x, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(new Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); + + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1)); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + } + } + } +} diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index ba89be33e08..138b2da2ad9 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -9,9 +9,12 @@ class LiquidHandler { public: + LiquidHandler(ADT* adt); ADT* Source; std::vector Vertices; std::vector > Triangles; std::vector MCNKData; +private: + void HandleNewLiquid(); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 95f8c2e56c0..4cb5dc04d2d 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -1,7 +1,7 @@ #include "MapChunk.h" #include "ADT.h" -MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : adt(_adt), Source(chunk), Vertices(NULL) +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) { FILE* stream = chunk->GetStream(); Header.Read(stream); @@ -26,14 +26,14 @@ void MapChunk::GenerateTriangles() uint32 center = (17 * y) + 9 + x; uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; - if (ADT.LiquidHandler && ADT.LiquidHandler.MCNKData) + if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { - var data = ADT.LiquidHandler.MCNKData[Index]; + MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; uint32 maxHeight = std::max( std::max( std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), Vertices[bottomRight].z), Vertices[center].z); - if (data && data->IsWater(x, y, maxHeight)) + if (data.IsWater(x, y, maxHeight)) triangleType = Constants::TRIANGLE_TYPE_WATER; } diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 034429a81ec..9d7b02bbfe5 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -15,7 +15,7 @@ public: void GenerateTriangles(); void GenerateVertices(FILE* stream); static bool HasHole(uint32 map, int x, int y); - ADT* adt; + ADT* Adt; Chunk* Source; MapChunkHeader Header; Vector3* Vertices; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 03473eb0794..0b92dab267f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -161,3 +161,14 @@ float Utils::Distance( float x, float y ) { return sqrt(x*x + y*y); } + +std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ) +{ + size_t pos = 0; + while((pos = str.find(oldStr, pos)) != std::string::npos) + { + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return str; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index cda5f4c7cd8..aa73db173a7 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -16,9 +16,9 @@ struct Vector3 float x; float y; float z; - Vector3 operator+(Vector3 right, Vector3 left) + Vector3 operator +(Vector3 const& other) { - return Vector3(right.x+left.x, right.y+left.y, right.z+left.z); + return Vector3(x + other.x, y + other.y, z + other.z); } static Vector3 Read(FILE* file); }; @@ -380,7 +380,7 @@ public: return RenderFlags[x][y] != 0x0F; } - public static LiquidData Read(FILE* stream, LiquidHeader header) + static LiquidData Read(FILE* stream, LiquidHeader header) { LiquidData ret; ret.HeightMap = new float*[header.CountXVertices]; @@ -440,14 +440,15 @@ class MCNKLiquidData { public: MCNKLiquidData() {} + MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} const float MaxStandableHeight = 1.5f; float** Heights; - H2ORenderMask* Mask; + H2ORenderMask Mask; bool IsWater(int x, int y, float height) { - if (!Heights || !Mask) + if (!Heights) return false; if (!Mask->ShouldRender(x, y)) return false; @@ -458,6 +459,56 @@ public: } }; +class H2OHeader +{ +public: + H2OHeader() {} + uint32 OffsetInformation; + uint32 LayerCount; + uint32 OffsetRender; + + static H2OHeader Read(FILE* stream) + { + H2OHeader ret; + fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + fread(&ret.LayerCount, sizeof(uint32), 1, stream); + fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + return ret; + } +}; + +class H2OInformation +{ +public: + H2OInformation() {} + uint16 LiquidType; + uint16 Flags; + float HeightLevel1; + float HeightLevel2; + uint8 OffsetX; + uint8 OffsetY; + uint8 Width; + uint8 Height; + uint32 OffsetMask2; + uint32 OffsetHeightmap; + + static H2OInformation Read(FILE* stream) + { + H2OInformation ret; + fread(&ret.LiquidType, sizeof(uint16), 1, stream); + fread(&ret.Flags, sizeof(uint16), 1, stream); + fread(&ret.HeightLevel1, sizeof(float), 1, stream); + fread(&ret.HeightLevel2, sizeof(float), 1, stream); + fread(&ret.OffsetX, sizeof(uint8), 1, stream); + fread(&ret.OffsetY, sizeof(uint8), 1, stream); + fread(&ret.Width, sizeof(uint8), 1, stream); + fread(&ret.Height, sizeof(uint8), 1, stream); + fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + return ret; + } +}; + // Dummy class to act as an interface. class IDefinition { @@ -493,5 +544,15 @@ public: static std::string GetPathBase(std::string path); static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); static float Distance(float x, float y); + template + static bool IsAllZero(T* arr, uint32 size) + { + for (uint32 i = 0; i < size; ++i) + if (arr[i]) + return false; + return true; + } + static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); + }; #endif \ No newline at end of file -- cgit v1.2.3 From 753f43718e59d4bf94b35e25a335e845e2277002 Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 28 Sep 2012 15:04:47 +0200 Subject: Address a few compile errors. Correct spacing in HandleMmapPathCommand. --- src/server/scripts/Commands/cs_mmaps.cpp | 108 ++++++++++++------------- src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/DoodadHandler.cpp | 12 +-- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/Geometry.cpp | 6 +- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/Utils.cpp | 10 +-- src/tools/mesh_extractor/Utils.h | 22 ++--- src/tools/mesh_extractor/WorldModelGroup.cpp | 14 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 6 +- src/tools/mesh_extractor/WorldModelHandler.h | 6 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 12 files changed, 101 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c1fc4d1a5e9..e4a0ebf7f24 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -60,60 +60,58 @@ public: static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) { - if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) - { - handler->PSendSysMessage("NavMesh not loaded for current map."); - return true; - } - - handler->PSendSysMessage("mmap path:"); - - // units - Player* player = handler->GetSession()->GetPlayer(); - Unit* target = handler->getSelectedUnit(); - if (!player || !target) - { - handler->PSendSysMessage("Invalid target/source selection."); - return true; - } - - char* para = strtok((char*)args, " "); - - bool useStraightPath = false; - if (para && strcmp(para, "true") == 0) - useStraightPath = true; - - // unit locations - float x, y, z; - player->GetPosition(x, y, z); - - // path - PathGenerator path(target); - path.SetUseStraightPath(useStraightPath); - path.CalculatePath(x, y, z); - - PointsArray pointPath = path.GetPath(); - handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); - handler->PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath"); - handler->PSendSysMessage("length %i type %u", pointPath.size(), path.GetPathType()); - - Vector3 start = path.GetStartPosition(); - Vector3 end = path.GetEndPosition(); - Vector3 actualEnd = path.GetActualEndPosition(); - - handler->PSendSysMessage("start (%.3f, %.3f, %.3f)", start.x, start.y, start.z); - handler->PSendSysMessage("end (%.3f, %.3f, %.3f)", end.x, end.y, end.z); - handler->PSendSysMessage("actual end (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); - - if (!player->isGameMaster()) - handler->PSendSysMessage("Enable GM mode to see the path points."); - - // this entry visible only to GM's with "gm on" - static const uint32 WAYPOINT_NPC_ENTRY = 1; - for (uint32 i = 0; i < pointPath.size(); ++i) - player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); - - return true; + if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) + { + handler->PSendSysMessage("NavMesh not loaded for current map."); + return true; + } + + handler->PSendSysMessage("mmap path:"); + + // units + Player* player = handler->GetSession()->GetPlayer(); + Unit* target = handler->getSelectedUnit(); + if (!player || !target) + { + handler->PSendSysMessage("Invalid target/source selection."); + return true; + } + + char* para = strtok((char*)args, " "); + + bool useStraightPath = false; + if (para && strcmp(para, "true") == 0) + useStraightPath = true; + + // unit locations + float x, y, z; + player->GetPosition(x, y, z); + + // path + PathGenerator path(target); + path.SetUseStraightPath(useStraightPath); + bool result = path.CalculatePath(x, y, z); + + PointsArray pointPath = path.GetPath(); + handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); + handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); + handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); + + Vector3 start = path.GetStartPosition(); + Vector3 end = path.GetEndPosition(); + Vector3 actualEnd = path.GetActualEndPosition(); + + handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z); + handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z); + handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z); + + if (!player->isGameMaster()) + handler->PSendSysMessage("Enable GM mode to see the path points."); + + for (uint32 i = 0; i < pointPath.size(); ++i) + player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000); + + return true; } static bool HandleMmapLocCommand(ChatHandler* handler, const char* args) @@ -290,4 +288,4 @@ public: void AddSC_mmaps_commandscript() { new mmaps_commandscript(); -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 186a7870af1..bc2ea6a2883 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -11,7 +11,8 @@ class GenericCache { public: GenericCache() {} - const int32 FlushLimit = 1000; + + static const int32 FlushLimit = 1000; void Insert(std::string key, T* val) { @@ -35,6 +36,7 @@ private: class CacheClass { +public: CacheClass() {} GenericCache ModelCache; GenericCache WorldModelCache; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 4a7707753c4..71ca1974b81 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -27,7 +27,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) return; FILE* stream = doodadReferencesChunk->GetStream(); uint32 refCount = doodadReferencesChunk->Length / 4; - for (int i = 0; i < refCount; i++) + for (uint32 i = 0; i < refCount; i++) { int32 index; fread(&index, sizeof(int32), 1, stream); @@ -41,11 +41,11 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) continue; std::string path = (*_paths)[doodad.MmidIndex]; - Model* model = Cache.ModelCache.Get(path); + Model* model = Cache->ModelCache.Get(path); if (!model) { model = new Model(path); - Cache.ModelCache.Insert(path, model); + Cache->ModelCache.Insert(path, model); } if (!model->IsCollidable) continue; @@ -92,8 +92,10 @@ void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); + for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) Vertices.push_back(Utils::VectorTransform(*itr, transformation)); + for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); -} \ No newline at end of file + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); +} diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index c62584ca1f1..d38ee723bef 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -15,7 +15,7 @@ public: uint16 DecimalScale; uint16 Flags; - float Scale() { return DecimalScale / 1024.0f; } + virtual float Scale() const { return DecimalScale / 1024.0f; } void Read(FILE* stream) { diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 8e417af4c73..130258b6908 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -68,7 +68,7 @@ void Geometry::AddData( std::vector& verts, std::vector& tri = Triangles[i]; tris[(i * 3) + 0] = (int)tri.V0; @@ -86,7 +86,7 @@ void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) } areas = new uint8[Triangles.size()]; - for (int i = 0; i < Triangles.size(); i++) + for (uint32 i = 0; i < Triangles.size(); i++) { switch (Triangles[i].Type) { diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 070b9d70050..36e71730c34 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -34,4 +34,4 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmin[2] = origin[2] + (Constants::TileSize * Y); bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 0b92dab267f..ef24a8017bd 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -74,7 +74,7 @@ G3D::Matrix4 Utils::RotationX(float angle) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[2][2] = _cos; ret[2][3] = _sin; ret[3][2] = -_sin; @@ -82,7 +82,7 @@ G3D::Matrix4 Utils::RotationX(float angle) return ret; } -G3D::Matrix4 Utils::GetTransformation( IDefinition def ) +G3D::Matrix4 Utils::GetTransformation(IDefinition def) { G3D::Matrix4 translation; if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) @@ -101,7 +101,7 @@ G3D::Matrix4 Utils::RotationY( float angle ) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[1][1] = _cos; ret[1][3] = -_sin; ret[3][1] = _sin; @@ -113,7 +113,7 @@ G3D::Matrix4 Utils::RotationZ( float angle ) { float _cos = cos(angle); float _sin = sin(angle); - Matrix4 ret = G3D::Matrix4::identity(); + G3D::Matrix4 ret = G3D::Matrix4::identity(); ret[1][1] = _cos; ret[1][2] = _sin; ret[2][1] = -_sin; @@ -126,7 +126,7 @@ float Utils::ToRadians( float degrees ) return Constants::PI * degrees / 180.0f; } -Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix matrix ) +Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) { Vector3 ret; ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index aa73db173a7..ec333d80f8c 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -16,10 +16,12 @@ struct Vector3 float x; float y; float z; + Vector3 operator +(Vector3 const& other) { return Vector3(x + other.x, y + other.y, z + other.z); } + static Vector3 Read(FILE* file); }; @@ -342,7 +344,7 @@ public: fread(&ret.UnknownZero, sizeof(uint32), 1, stream); return ret; } -} +}; class LiquidHeader { @@ -384,16 +386,16 @@ public: { LiquidData ret; ret.HeightMap = new float*[header.CountXVertices]; - for (int i = 0; i < header.CountXVertices; ++i) + for (uint32 i = 0; i < header.CountXVertices; ++i) ret.HeightMap[i] = new float[header.CountYVertices]; ret.RenderFlags = new uint8*[header.Width]; - for (int i = 0; i < header.Width; ++i) + for (uint32 i = 0; i < header.Width; ++i) ret.RenderFlags[i] = new uint8[header.Height]; - for (int y = 0; y < header.CountYVertices; y++) + for (uint32 y = 0; y < header.CountYVertices; y++) { - for (int x = 0; x < header.CountXVertices; x++) + for (uint32 x = 0; x < header.CountXVertices; x++) { uint32 discard; fread(&discard, sizeof(uint32), 1, stream); @@ -403,9 +405,9 @@ public: } } - for (int y = 0; y < header.Height; y++) + for (uint32 y = 0; y < header.Height; y++) { - for (int x = 0; x < header.Width; x++) + for (uint32 x = 0; x < header.Width; x++) { uint8 tmp; fread(&tmp, sizeof(uint8), 1, stream); @@ -441,8 +443,8 @@ class MCNKLiquidData public: MCNKLiquidData() {} MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} - const float MaxStandableHeight = 1.5f; + static const float MaxStandableHeight = 1.5f; float** Heights; H2ORenderMask Mask; @@ -515,7 +517,7 @@ class IDefinition public: Vector3 Position; Vector3 Rotation; - virtual float Scale() = 0; + virtual float Scale() const = 0; }; class Utils @@ -540,7 +542,7 @@ public: static G3D::Matrix4 RotationY(float angle); static G3D::Matrix4 RotationZ(float angle); static float ToRadians(float degrees); - static Vector3 VectorTransform(Vector3 vec, G3D::Matrix matrix); + static Vector3 VectorTransform(Vector3 vec, G3D::Matrix4 matrix); static std::string GetPathBase(std::string path); static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); static float Distance(float x, float y); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 308c7ff7b86..5039eb56381 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -33,7 +33,7 @@ void WorldModelGroup::ReadNormals() return; uint32 normalCount = chunk->Length / 12; - Assert(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + ASSERT(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < normalCount; i++) @@ -58,7 +58,7 @@ void WorldModelGroup::ReadVertices() if (!chunk) return; - uint32 verticeCount = chunk.Length / 12; + uint32 verticeCount = chunk->Length / 12; Vertices.reserve(verticeCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < verticeCount; i++) @@ -71,9 +71,9 @@ void WorldModelGroup::ReadTriangles() if (!chunk) return; - uint32 triangleCount = chunk.Length / 6; - Assert(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); - FILE* stream = chunk.GetStream(); + uint32 triangleCount = chunk->Length / 6; + ASSERT(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) { @@ -94,7 +94,7 @@ void WorldModelGroup::ReadMaterials() return; FILE* stream = chunk->GetStream(); - uint32 triangleCount = chunk.Length / 2; + uint32 triangleCount = chunk->Length / 2; TriangleFlags.reserve(triangleCount); TriangleMaterials.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) @@ -115,7 +115,7 @@ void WorldModelGroup::ReadBoundingBox() return; FILE* stream = chunk->GetStream(); - fseek(stream, 8, SEEK_CUR): + fseek(stream, 8, SEEK_CUR); fread(&Flags, sizeof(uint32), 1, stream); BoundingBox[0] = Vector3::Read(stream); BoundingBox[1] = Vector3::Read(stream); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index e895e2bfde8..cb8ac6d8e5d 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -159,8 +159,8 @@ void WorldModelHandler::ReadDefinitions() return; const int32 definitionSize = 64; - uint32 definitionCount = chunk.Length / definitionSize; - _definitions = new new std::vector; + uint32 definitionCount = chunk->Length / definitionSize; + _definitions = new std::vector; _definitions->reserve(definitionCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < definitionCount; i++) @@ -174,7 +174,7 @@ void WorldModelHandler::ReadModelPaths() if (!mwid || !mwmo) return; - uint32 paths = mwid.Length / 4; + uint32 paths = mwid->Length / 4; _paths = new std::vector; _paths->reserve(paths); for (int i = 0; i < paths; i++) diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 2236339de9d..81e6eab1c4b 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -10,14 +10,18 @@ struct WorldModelDefinition : IDefinition { +public: WorldModelDefinition() {} + uint32 MwidIndex; uint32 UniqueId; Vector3 UpperExtents; Vector3 LowerExtents; uint16 Flags; uint16 DoodadSet; - float Scale() { return 1.0f; } + + virtual float Scale() const { return 1.0f; } + static WorldModelDefinition Read(FILE* file); }; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 9764e339242..18b3fd8586d 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,7 +33,7 @@ void WorldModelRoot::ReadDoodadSets() return; FILE* stream = chunk->GetStream(); - Assert(chunk.Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + ASSERT(chunk->Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); for (int i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); -- cgit v1.2.3 From e12f7ed3e89bc137ed8e893a6bbda8f3a5d9c63d Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 09:01:13 -0500 Subject: Tools: Fixed build in MeshExtractor (almost) --- dep/CMakeLists.txt | 2 +- src/server/CMakeLists.txt | 1 + src/tools/mesh_extractor/ADT.cpp | 53 ++++++++++++++++++++++++++ src/tools/mesh_extractor/ADT.h | 7 ++-- src/tools/mesh_extractor/CMakeLists.txt | 5 +++ src/tools/mesh_extractor/Cache.h | 2 +- src/tools/mesh_extractor/Constants.h | 1 + src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 4 +- src/tools/mesh_extractor/LiquidHandler.cpp | 6 +-- src/tools/mesh_extractor/MapChunk.cpp | 11 +++--- src/tools/mesh_extractor/TileBuilder.cpp | 9 ++--- src/tools/mesh_extractor/Utils.cpp | 26 ++++++++----- src/tools/mesh_extractor/Utils.h | 13 ++++--- src/tools/mesh_extractor/WorldModelGroup.cpp | 8 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 34 +++++++++-------- src/tools/mesh_extractor/WorldModelHandler.h | 10 ++--- src/tools/mesh_extractor/WorldModelRoot.cpp | 2 +- 18 files changed, 135 insertions(+), 61 deletions(-) create mode 100644 src/tools/mesh_extractor/ADT.cpp (limited to 'src') diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index c01a1e3426a..f6db7ca22b7 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -22,7 +22,7 @@ endif() if(CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(acelite) - if(SERVERS AND USE_MYSQL_SOURCES) + if(USE_MYSQL_SOURCES) add_subdirectory(mysqllite) endif() if(TOOLS) diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 2b6c553e10b..e038f36fd47 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -30,5 +30,6 @@ if( SERVERS ) else() if( TOOLS ) add_subdirectory(collision) + add_subdirectory(shared) endif() endif() diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp new file mode 100644 index 00000000000..c564d7193cf --- /dev/null +++ b/src/tools/mesh_extractor/ADT.cpp @@ -0,0 +1,53 @@ +#include "ADT.h" +#include "DoodadHandler.h" +#include "LiquidHandler.h" +#include "WorldModelHandler.h" + +ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) +{ + Data = new ChunkedData(file); + ObjectData = new ChunkedData(Utils::Replace(file, ".adt", "_obj0.adt")); + if (ObjectData->Stream) + HasObjectData = true; + else + ObjectData = NULL; +} + +ADT::~ADT() +{ + delete ObjectData; + delete Data; + + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + delete *itr; + + MapChunks.clear(); + delete _DoodadHandler; + delete _WorldModelHandler; + delete _LiquidHandler; +} + +void ADT::Read() +{ + Header.Read(Data->GetChunkByName("MHDR")->GetStream()); + MapChunks.reserve(16 * 16); + int mapChunkIndex = 0; + + for (std::vector::iterator itr = Data->Chunks.begin(); itr != Data->Chunks.end(); ++itr) + if ((*itr)->Name == "MCNK") + MapChunks.push_back(new MapChunk(this, *itr)); + + _LiquidHandler = new LiquidHandler(this); + + // do this separate from map chunk initialization to access liquid data + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + (*itr)->GenerateTriangles(); + + _DoodadHandler = new DoodadHandler(this); + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + _DoodadHandler->ProcessMapChunk(*itr); + + _WorldModelHandler = new WorldModelHandler(this); + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) + _WorldModelHandler->ProcessMapChunk(*itr); +} diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 43984d0902c..096f491eed8 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -2,9 +2,10 @@ #define ADT_H #include "ChunkedData.h" #include "MapChunk.h" -#include "DoodadHandler.h" -#include "WorldModelHandler.h" -#include "LiquidHandler.h" + +class DoodadHandler; +class WorldModelHandler; +class LiquidHandler; class ADT { diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 3f5b5526dd4..0469590a201 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -45,9 +45,14 @@ add_executable(MeshExtractor ) target_link_libraries(MeshExtractor + shared + g3dlib mpq Recast Detour + ${MYSQL_LIBRARY} + ${OPENSSL_LIBRARIES} + ${OPENSSL_EXTRA_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} ${ACE_LIBRARY} diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index bc2ea6a2883..2693ce4e1e1 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -18,7 +18,7 @@ public: { if (_items.size() > FlushLimit) Clear(); - _items.insert(key, val); + _items[key] = val; } T* Get(std::string key) diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 885761f1687..38fa0b2e35b 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -28,6 +28,7 @@ public: static const float UnitSize; static const float Origin[]; static const float PI; + static const float MaxStandableHeight; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 71ca1974b81..89fcaba5601 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -88,7 +88,7 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -void DoodadHandler::InsertModelGeometry(DoodadDefinition def, Model* model) +void DoodadHandler::InsertModelGeometry(const DoodadDefinition def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index d38ee723bef..c426504da32 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -7,7 +7,7 @@ #include #include -class DoodadDefinition : IDefinition +class DoodadDefinition : public IDefinition { public: uint32 MmidIndex; @@ -43,7 +43,7 @@ protected: private: void ReadDoodadDefinitions(Chunk* chunk); void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(DoodadDefinition def, Model* model); + void InsertModelGeometry(const DoodadDefinition def, Model* model); std::set _drawn; std::vector* _definitions; std::vector* _paths; diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 3217bb2cbc6..3d0876aeb74 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -43,7 +43,7 @@ void LiquidHandler::HandleNewLiquid() fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); uint32 size = ceil(information.Width * information.Height / 8.0f); uint8* altMask = new uint8[size]; - fread(altMax, sizeof(uint8), size, stream); + fread(altMask, sizeof(uint8), size, stream); for (int mi = 0; mi < size; mi++) renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; @@ -84,8 +84,8 @@ void LiquidHandler::HandleNewLiquid() uint32 vertOffset = Vertices.size(); Vertices.push_back(location); Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); - Vertices.push_back(new Vector3(location.x, location.y - Constants::UnitSize, location.z)); - Vertices.push_back(new Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(Vector3(location.x, location.y - Constants::UnitSize, location.z)); + Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1)); Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 4cb5dc04d2d..0b02a2a4a14 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -1,5 +1,6 @@ #include "MapChunk.h" #include "ADT.h" +#include "LiquidHandler.h" MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) { @@ -25,7 +26,7 @@ void MapChunk::GenerateTriangles() uint32 bottomRight = (17 * (y + 1)) + x + 1; uint32 center = (17 * y) + 9 + x; - uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN; + Constants::TriangleType triangleType = Constants::TRIANGLE_TYPE_TERRAIN; if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; @@ -37,10 +38,10 @@ void MapChunk::GenerateTriangles() triangleType = Constants::TRIANGLE_TYPE_WATER; } - Triangles.push_back(new Triangle(triangleType, topRight, topLeft, center)); - Triangles.push_back(new Triangle(triangleType, topLeft, bottomLeft, center)); - Triangles.push_back(new Triangle(triangleType, bottomLeft, bottomRight, center)); - Triangles.push_back(new Triangle(triangleType, bottomRight, topRight, center)); + Triangles.push_back(Triangle(triangleType, topRight, topLeft, center)); + Triangles.push_back(Triangle(triangleType, topLeft, bottomLeft, center)); + Triangles.push_back(Triangle(triangleType, bottomLeft, bottomRight, center)); + Triangles.push_back(Triangle(triangleType, bottomRight, topRight, center)); } } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 36e71730c34..190607493fa 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -27,11 +27,10 @@ TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), Wor void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) { - float origin[3] = Constants::Origin; bmin = new float[3]; bmax = new float[3]; - bmin[0] = origin[0] + (Constants::TileSize * X); - bmin[2] = origin[2] + (Constants::TileSize * Y); - bmax[0] = origin[0] + (Constants::TileSize * (X + 1)); - bmax[2] = origin[2] + (Constants::TileSize * (Y + 1)); + bmin[0] = Constants::Origin[0] + (Constants::TileSize * X); + bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y); + bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); + bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index ef24a8017bd..c7c0cff0d42 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -1,7 +1,9 @@ #include "Utils.h" +#include "WorldModelHandler.h" #include "Constants.h" #include #include "g3d/Matrix4.h" +#include "g3d/Quat.h" const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; @@ -9,6 +11,7 @@ const float Constants::ChunkSize = Constants::TileSize / 16.0f; const float Constants::UnitSize = Constants::ChunkSize / 8.0f; const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; const float Constants::PI = 3.1415926f; +const float Constants::MaxStandableHeight = 1.5f; void Utils::Reverse(char word[]) { @@ -60,14 +63,7 @@ std::string Utils::GetAdtPath( std::string world, int x, int y ) std::string Utils::FixModelPath( std::string path ) { - std::string::size_type idx = path.rfind("."); - // Bizarre way of changing extension but... - if (idx != std::string::npos) - { - path[idx + 1] = "M"; - path[idx + 2] = "2"; - } - return path; + return Utils::GetPathBase(path) + ".M2"; } G3D::Matrix4 Utils::RotationX(float angle) @@ -139,7 +135,7 @@ std::string Utils::GetPathBase( std::string path ) { int lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) - return path.substr(0, lastindex); + return path.substr(0, lastIndex); return path; } @@ -172,3 +168,15 @@ std::string Utils::Replace( std::string str, const std::string& oldStr, const st } return str; } + +G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ) +{ + G3D::Matrix4 rootTransformation = Utils::GetTransformation(root); + G3D::Matrix4 translation = G3D::Matrix4::translation(inst.Position.x, inst.Position.y, inst.Position.z); + G3D::Matrix4 scale = G3D::Matrix4::scale(inst.Scale); + G3D::Matrix4 rotation = Utils::RotationY(Constants::PI); + G3D::Quat quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); + G3D::Matrix4 quatRotation = quat.toRotationMatrix(); + + return scale * rotation * quatRotation ** translation * rootTransformation; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ec333d80f8c..ac14b9eca69 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -9,6 +9,9 @@ #include "Common.h" #include "Constants.h" +struct WorldModelDefinition; +class DoodadInstance; + struct Vector3 { Vector3() {} @@ -35,6 +38,7 @@ struct TilePos template struct Triangle { + Triangle() {} Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} T V0; T V1; @@ -444,7 +448,6 @@ public: MCNKLiquidData() {} MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} - static const float MaxStandableHeight = 1.5f; float** Heights; H2ORenderMask Mask; @@ -452,10 +455,10 @@ public: { if (!Heights) return false; - if (!Mask->ShouldRender(x, y)) + if (!Mask.ShouldRender(x, y)) return false; float diff = Heights[x][y] - height; - if (diff > MaxStandableHeight) + if (diff > Constants::MaxStandableHeight) return true; return false; } @@ -517,7 +520,7 @@ class IDefinition public: Vector3 Position; Vector3 Rotation; - virtual float Scale() const = 0; + virtual float Scale() const { return 1.0f; }; }; class Utils @@ -555,6 +558,6 @@ public: return true; } static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - + static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 5039eb56381..b4c963020c7 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -33,7 +33,7 @@ void WorldModelGroup::ReadNormals() return; uint32 normalCount = chunk->Length / 12; - ASSERT(normalCount == Vertices.size(), "normalCount is different than the Vertices count"); + ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (int i = 0; i < normalCount; i++) @@ -48,8 +48,8 @@ void WorldModelGroup::ReadLiquid() HasLiquidData = true; FILE* stream = chunk->GetStream(); - LiquidDataHeader = LiquidHeader.Read(stream); - LiquidDataGeometry = LiquidData.Read(stream, LiquidDataHeader); + LiquidDataHeader = LiquidHeader::Read(stream); + LiquidDataGeometry = LiquidData::Read(stream, LiquidDataHeader); } void WorldModelGroup::ReadVertices() @@ -72,7 +72,7 @@ void WorldModelGroup::ReadTriangles() return; uint32 triangleCount = chunk->Length / 6; - ASSERT(triangleCount == TriangleFlags.size(), "triangleCount != TriangleFlags.size()"); + ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); for (int i = 0; i < triangleCount; i++) diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index cb8ac6d8e5d..e5a14d55c0c 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -1,6 +1,8 @@ #include "WorldModelHandler.h" +#include "WorldModelRoot.h" #include "Chunk.h" #include "Cache.h" +#include "Model.h" #include "Common.h" #include "g3d/Matrix4.h" #include @@ -15,7 +17,7 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) ret.UpperExtents = Vector3::Read(file); ret.LowerExtents = Vector3::Read(file); fread(&ret.Flags, sizeof(uint16), 1, file); - fread(&ret.DooadSet, sizeof(uint16), 1, file); + fread(&ret.DoodadSet, sizeof(uint16), 1, file); uint32 discard; fread(&discard, sizeof(uint32), 1, file); return ret; @@ -39,7 +41,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) return; FILE* stream = wmoReferencesChunk->GetStream(); uint32 refCount = wmoReferencesChunk->Length / 4; - for (int i = 0; i < refCount; i++) + for (uint32 i = 0; i < refCount; i++) { int32 index; fread(&index, sizeof(int32), 1, stream); @@ -56,7 +58,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) if (wmo.MwidIndex >= _paths->size()) continue; - std::string path = _paths[(int) wmo.MwidIndex]; + std::string path = (*_paths)[wmo.MwidIndex]; WorldModelRoot* model = Cache->WorldModelCache.Get(path); if (!model) { @@ -71,16 +73,16 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) } } -void WorldModelHandler::InsertModelGeometry( std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root ) +void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) { - G3D::Matrix4 transformation = Utils::GetTransformation(); + G3D::Matrix4 transformation = Utils::GetTransformation(def); for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) { uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) verts.push_back(Utils::VectorTransform(*itr2, transformation)); - for (int i = 0; i < group->Triangles.size(); ++i) + for (uint32 i = 0; i < group->Triangles.size(); ++i) { // only include collidable tris if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) @@ -93,7 +95,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) { DoodadSet set = root->DoodadSets[def.DoodadSet]; - std::vector instances = new std::vector; + std::vector instances; instances.reserve(set.CountInstances); for (uint32 i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) { @@ -104,16 +106,16 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { - Model* model = Cache.ModelCache.Get(instance->File); + Model* model = Cache->ModelCache.Get(instance->File); if (!model) { model = new Model(instance->File); - Cache.ModelCache.Insert(instance->File, model); + Cache->ModelCache.Insert(instance->File, model); } - if (!model.IsCollidable) + if (!model->IsCollidable) continue; - G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(instance, def); + G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(*instance, def); int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) verts.push_back(Utils::VectorTransform(*itr2, doodadTransformation)); @@ -126,9 +128,9 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve if (!group->HasLiquidData) continue; - for (int y = 0; y < group->LiquidDataHeader.Height; y++) + for (uint32 y = 0; y < group->LiquidDataHeader.Height; y++) { - for (int x = 0; x < group->LiquidDataHeader.Width; x++) + for (uint32 x = 0; x < group->LiquidDataHeader.Width; x++) { if (!group->LiquidDataGeometry.ShouldRender(x, y)) continue; @@ -144,7 +146,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector verts, std::ve group->LiquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); - tris.push_back(new Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); + tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); } } @@ -163,7 +165,7 @@ void WorldModelHandler::ReadDefinitions() _definitions = new std::vector; _definitions->reserve(definitionCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < definitionCount; i++) + for (uint32 i = 0; i < definitionCount; i++) _definitions->push_back(WorldModelDefinition::Read(stream)); } @@ -177,7 +179,7 @@ void WorldModelHandler::ReadModelPaths() uint32 paths = mwid->Length / 4; _paths = new std::vector; _paths->reserve(paths); - for (int i = 0; i < paths; i++) + for (uint32 i = 0; i < paths; i++) { FILE* stream = mwid->GetStream(); fseek(stream, i * 4, SEEK_CUR); diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 81e6eab1c4b..daf0713ecd2 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -2,13 +2,15 @@ #define WMODEL_HNDL_H #include "Common.h" #include "Utils.h" +#include "WorldModelRoot.h" #include "ObjectDataHandler.h" -#include "ADT.h" #include #include -struct WorldModelDefinition : IDefinition +class ADT; + +struct WorldModelDefinition : public IDefinition { public: WorldModelDefinition() {} @@ -20,8 +22,6 @@ public: uint16 Flags; uint16 DoodadSet; - virtual float Scale() const { return 1.0f; } - static WorldModelDefinition Read(FILE* file); }; @@ -33,7 +33,7 @@ public: std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } - void InsertModelGeometry(std::vector verts, std::vector > tris, WorldModelDefinition& def, WorldModelRoot* root); + void InsertModelGeometry(std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root); protected: void ProcessInternal(ChunkedData* data); private: diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 18b3fd8586d..3457a35f761 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -33,7 +33,7 @@ void WorldModelRoot::ReadDoodadSets() return; FILE* stream = chunk->GetStream(); - ASSERT(chunk->Length / 32 == Header.CountSets, "chunk.Length / 32 == Header.CountSets"); + ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); for (int i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); -- cgit v1.2.3 From 1c6a44e4c5516b5e81acf858733114e61d332e3f Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 09:30:23 -0500 Subject: Tools: Fixed build in MeshExtractor --- src/tools/mesh_extractor/CMakeLists.txt | 6 ++++++ src/tools/mesh_extractor/MeshExtractor.cpp | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 0469590a201..09bd2982213 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -13,15 +13,19 @@ file(GLOB_RECURSE sources *.cpp *.h) if( UNIX ) include_directories ( + ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${MYSQL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) elseif( WIN32 ) include_directories ( + ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Database ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation @@ -36,6 +40,8 @@ elseif( WIN32 ) ${CMAKE_SOURCE_DIR}/dep/libmpq/win ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${ACE_INCLUDE_DIR} + ${MYSQL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) endif() diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0220627cbcc..0611c9c2d58 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -3,6 +3,10 @@ #include "ContinentBuilder.h" #include "Cache.h" +#include "Common.h" +#include "LoginDatabase.h" +LoginDatabaseWorkerPool LoginDatabase; + MPQManager* MPQHandler; CacheClass* Cache; -- cgit v1.2.3 From 3eda479e2970a72a8fcf7731d94b962ff9874e38 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 13:30:43 -0500 Subject: Tools: MeshExtractor is working now. Please note that this is not yet finished --- src/tools/mesh_extractor/Cache.h | 28 +++- src/tools/mesh_extractor/Constants.h | 7 + src/tools/mesh_extractor/ContinentBuilder.cpp | 29 +++- src/tools/mesh_extractor/Geometry.cpp | 21 +++ src/tools/mesh_extractor/Geometry.h | 2 + src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MapChunk.cpp | 12 +- src/tools/mesh_extractor/MapChunk.h | 3 +- src/tools/mesh_extractor/MeshExtractor.cpp | 4 +- src/tools/mesh_extractor/TileBuilder.cpp | 201 ++++++++++++++++++++++++- src/tools/mesh_extractor/TileBuilder.h | 7 +- src/tools/mesh_extractor/Utils.h | 16 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- 13 files changed, 308 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 2693ce4e1e1..799878bdd3b 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -1,12 +1,14 @@ #ifndef CACHE_H #define CACHE_H #include +#include #include "Common.h" class WorldModelRoot; class Model; +class ADT; -template +template class GenericCache { public: @@ -14,32 +16,42 @@ public: static const int32 FlushLimit = 1000; - void Insert(std::string key, T* val) + void Insert(K key, T* val) { if (_items.size() > FlushLimit) Clear(); _items[key] = val; } - T* Get(std::string key) + T* Get(K key) { - UNORDERED_MAP::iterator itr = _items.find(key); + std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; } - void Clear() { _items.clear(); } + void Clear() + { + for (std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + delete itr->second; + _items.clear(); + } private: - UNORDERED_MAP _items; + std::map _items; }; class CacheClass { public: CacheClass() {} - GenericCache ModelCache; - GenericCache WorldModelCache; + GenericCache ModelCache; + GenericCache WorldModelCache; + GenericCache, ADT> AdtCache; + void Clear() + { + AdtCache.Clear(); + } }; extern CacheClass* Cache; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 38fa0b2e35b..f44d5f16797 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -22,6 +22,13 @@ public: POLY_AREA_ROAD = 3, POLY_AREA_DANGER = 4, }; + + enum PolyFlag + { + POLY_FLAG_WALK = 1, + POLY_FLAG_SWIM = 2, + POLY_FLAG_FLIGHTMASTER = 4 + }; static const float TileSize; static const float MaxXY; static const float ChunkSize; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 8af6f3a02e8..f861dff1648 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -1,11 +1,38 @@ #include "ContinentBuilder.h" +#include "TileBuilder.h" #include "WDT.h" #include "Utils.h" +#include "DetourNavMesh.h" void ContinentBuilder::Build() { + FILE* mmap = fopen("608.mmap", "wb"); + dtNavMeshParams params; + params.maxPolys = 32768; + params.maxTiles = 4096; + params.orig[0] = -17066.666f; + params.orig[1] = 0.0f; + params.orig[2] = -17066.666f; + params.tileHeight = 533.33333f; + params.tileWidth = 533.33333f; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - + TileBuilder builder(Continent, itr->X, itr->Y, TileMap); + char buff[100]; + sprintf(buff, "%03u%02u%02u.mmtile", builder.MapId, itr->X, itr->Y); + FILE* f = fopen(buff, "wb"); + uint8* nav = builder.Build(); + if (nav) + { + MmapTileHeader header; + header.size = builder.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(uint8), builder.DataSize, f); + } + fclose(f); + dtFree(nav); + printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); } } diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 130258b6908..2fbe99e3211 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -1,5 +1,8 @@ #include "Geometry.h" #include "Constants.h" +#include "ADT.h" +#include "WorldModelHandler.h" +#include "DoodadHandler.h" Geometry::Geometry() : Transform(false) { @@ -100,3 +103,21 @@ void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) } } +void Geometry::AddAdt( ADT* adt ) +{ + for (std::vector::iterator itr = adt->MapChunks.begin(); itr != adt->MapChunks.end(); ++itr) + { + std::vector > tmp; + tmp.reserve((*itr)->Triangles.size()); + for (std::vector >::iterator itr2 = (*itr)->Triangles.begin(); itr2 != (*itr)->Triangles.end(); ++itr2) + tmp.push_back(Triangle(itr2->Type, itr2->V0, itr2->V1, itr2->V2)); + AddData((*itr)->Vertices, tmp); + } + + if (!adt->_DoodadHandler->Triangles.empty()) + AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); + + if (!adt->_WorldModelHandler->Triangles.empty()) + AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); +} + diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h index 048d9fde578..9593c98044e 100644 --- a/src/tools/mesh_extractor/Geometry.h +++ b/src/tools/mesh_extractor/Geometry.h @@ -4,6 +4,7 @@ #include "Utils.h" +class ADT; class Geometry { public: @@ -12,6 +13,7 @@ public: void CalculateBoundingBox(float*& min, float*& max); void CalculateMinMaxHeight(float& min, float& max); void AddData(std::vector& verts, std::vector >& tris); + void AddAdt(ADT* adt); void GetRawData(float*& verts, int*& tris, uint8*& areas); std::vector Vertices; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 429b09ffe02..35d4c91fc14 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -46,7 +46,7 @@ void MPQManager::LoadMPQs() sprintf(filename, "Data/%s", Files[i]); Archives.push_front(new MPQArchive(filename)); } - printf("Loaded %u MPQ files succesfully", Archives.size()); + printf("Loaded %u MPQ files succesfully\n", Archives.size()); } FILE* MPQManager::GetFile( std::string path ) diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 0b02a2a4a14..61c106f9766 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -2,7 +2,7 @@ #include "ADT.h" #include "LiquidHandler.h" -MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL) +MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) { FILE* stream = chunk->GetStream(); Header.Read(stream); @@ -46,16 +46,10 @@ void MapChunk::GenerateTriangles() } } -MapChunk::~MapChunk() -{ - delete[] Vertices; -} - void MapChunk::GenerateVertices( FILE* stream ) { fseek(stream, Header.OffsetMCVT, SEEK_CUR); - int32 vertIndex = 0; - Vertices = new Vector3[125]; + Vertices.reserve(125); for (int j = 0; j < 17; j++) { @@ -67,7 +61,7 @@ void MapChunk::GenerateVertices( FILE* stream ) Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); if (values == 8) vert.y -= Constants::UnitSize * 0.5f; - Vertices[vertIndex++] = vert; + Vertices.push_back(vert); } } } diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 9d7b02bbfe5..61dcabac9b0 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -10,7 +10,6 @@ class MapChunk { public: MapChunk(ADT* _adt, Chunk* chunk); - ~MapChunk(); void GenerateTriangles(); void GenerateVertices(FILE* stream); @@ -18,7 +17,7 @@ public: ADT* Adt; Chunk* Source; MapChunkHeader Header; - Vector3* Vertices; + std::vector Vertices; std::vector > Triangles; int32 Index; }; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 0611c9c2d58..38a120449bc 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -15,10 +15,10 @@ void ExtractAllMaps() WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); if (!wdt.IsValid) return; - printf("Model valid!"); + printf("Model valid!\n"); if (wdt.IsGlobalModel) { - printf("Unsupported"); + printf("Unsupported\n"); return; } ContinentBuilder builder("DalaranPrison", &wdt); diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 190607493fa..4736274706d 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,7 +1,15 @@ #include "TileBuilder.h" +#include "Geometry.h" #include "Constants.h" +#include "Utils.h" +#include "Cache.h" +#include "ADT.h" +#include "WDT.h" +#include "Recast.h" +#include "RecastAlloc.h" +#include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608) +TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608), DataSize(0), Wdt(wdt) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize @@ -23,6 +31,8 @@ TileBuilder::TileBuilder(std::string world, int x, int y) : _Geometry(NULL), Wor Config.width = 1800; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; + + Context = new rcContext; } void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) @@ -34,3 +44,192 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } + +uint8* TileBuilder::Build() +{ + _Geometry = new Geometry(); + _Geometry->Transform = true; + ADT* adt = Cache->AdtCache.Get(std::make_pair(X, Y)); + if (!adt) + { + adt = new ADT(Utils::GetAdtPath(World, X, Y)); + adt->Read(); + Cache->AdtCache.Insert(std::make_pair(X, Y), adt); + } + _Geometry->AddAdt(adt); + + if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) + return NULL; + + float* bbMin; + float* bbMax; + CalculateTileBounds(bbMin, bbMax); + _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); + + // again, we load everything - wasteful but who cares + for (int ty = Y - 1; ty <= Y + 1; ty++) + { + for (int tx = X - 1; tx <= X + 1; tx++) + { + // don't load main tile again + if (tx == X && ty == Y) + continue; + + ADT* _adt = Cache->AdtCache.Get(std::make_pair(tx, ty)); + if (!_adt) + { + _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); + // If this condition is met, it means that this wdt does not contain the ADT + if (!_adt->Data->Stream) + { + delete _adt; + continue; + } + _adt->Read(); + Cache->AdtCache.Insert(std::make_pair(tx, ty), _adt); + } + _Geometry->AddAdt(adt); + } + } + uint32 numVerts = _Geometry->Vertices.size(); + uint32 numTris = _Geometry->Triangles.size(); + float* vertices; + int* triangles; + uint8* areas; + _Geometry->GetRawData(vertices, triangles, areas); + _Geometry->Vertices.clear(); + _Geometry->Triangles.clear(); + + bbMin[0] -= Config.borderSize * Config.cs; + bbMin[2] -= Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs; + + rcHeightfield* hf = rcAllocHeightfield(); + int width = Config.width + (Config.borderSize * 2); + rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); + rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); + + printf("[%02u,%02u] Triangles rasterized!\n", X, Y); + + // Once all geometry is rasterized, we do initial pass of filtering to + // remove unwanted overhangs caused by the conservative rasterization + // as well as filter spans where the character cannot possibly stand. + rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); + rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); + + printf("[%02u,%02u] Filtering done!\n", X, Y); + + // Compact the heightfield so that it is faster to handle from now on. + // This will result in more cache coherent data as well as the neighbours + // between walkable cells will be calculated. + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); + + rcFreeHeightField(hf); + + printf("[%02u,%02u] Heightfield compressed!\n", X, Y); + + // Erode the walkable area by agent radius. + rcErodeWalkableArea(Context, Config.walkableRadius, *chf); + // Prepare for region partitioning, by calculating distance field along the walkable surface. + rcBuildDistanceField(Context, *chf); + // Partition the walkable surface into simple regions without holes. + rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + printf("[%02u,%02u] Regions built!\n", X, Y); + + // Create contours. + rcContourSet* cset = rcAllocContourSet(); + rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); + + // Build polygon navmesh from the contours. + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); + + printf("[%02u,%02u] Polymesh built!\n", X, Y); + + // Build detail mesh. + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); + + printf("[%02u,%02u] Polymesh detail built!\n", X, Y); + + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + + // Remove padding from the polymesh data. (Remove this odditity) + for (int i = 0; i < pmesh->nverts; ++i) + { + unsigned short* v = &pmesh->verts[i * 3]; + v[0] -= (unsigned short)Config.borderSize; + v[2] -= (unsigned short)Config.borderSize; + } + + // Set flags according to area types (e.g. Swim for Water) + for (int i = 0; i < pmesh->npolys; i++) + { + if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) + pmesh->flags[i] = Constants::POLY_FLAG_WALK; + else if (pmesh->areas[i] == (int)Constants::POLY_AREA_WATER) + pmesh->flags[i] = Constants::POLY_FLAG_SWIM; + } + + // get original bounds + float* tilebMin; + float* tilebMax; + CalculateTileBounds(tilebMin, tilebMax); + tilebMin[1] = bbMin[1]; + tilebMax[1] = bbMax[1]; + + dtNavMeshCreateParams params; + // PolyMesh data + params.verts = pmesh->verts; + params.vertCount = pmesh->nverts; + params.polys = pmesh->polys; + params.polyAreas = pmesh->areas; + params.polyFlags = pmesh->flags; + params.polyCount = pmesh->npolys; + params.nvp = pmesh->nvp; + // PolyMeshDetail data + params.detailMeshes = dmesh->meshes; + params.detailVerts = dmesh->verts; + params.detailVertsCount = dmesh->nverts; + params.detailTris = dmesh->tris; + params.detailTriCount = dmesh->ntris; + // Copy bounding box + params.bmin[0] = tilebMin[0]; + params.bmin[1] = tilebMin[1]; + params.bmin[2] = tilebMin[2]; + params.bmax[0] = tilebMax[0]; + params.bmax[1] = tilebMax[1]; + params.bmax[2] = tilebMax[2]; + // General settings + params.ch = Config.ch; + params.cs = Config.cs; + params.walkableClimb = Config.walkableClimb; + params.walkableHeight = Config.walkableHeight; + params.walkableRadius = Config.walkableRadius; + params.tileX = X; + params.tileY = Y; + params.tileSize = Config.width; + int navDataSize; + uint8* navData; + printf("[%02u,%02u] Creating the navmesh!\n", X, Y); + bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); + if (result) + { + printf("[%02u,%02u] NavMesh created, size %u!\n", X, Y, navDataSize); + DataSize = navDataSize; + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + Cache->Clear(); + return navData; + } + + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + return NULL; +} diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index badb05295e5..7dff363cabe 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -5,10 +5,12 @@ #include "Geometry.h" +class WDT; + class TileBuilder { public: - TileBuilder(std::string world, int x, int y); + TileBuilder(std::string world, int x, int y, WDT* wdt); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); @@ -17,6 +19,9 @@ public: int Y; int MapId; rcConfig Config; + rcContext* Context; Geometry* _Geometry; + uint32 DataSize; + WDT* Wdt; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index ac14b9eca69..4cf20a4cf9d 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -5,6 +5,7 @@ #include #include "g3d/Matrix4.h" +#include "DetourNavMesh.h" #include "Common.h" #include "Constants.h" @@ -523,6 +524,21 @@ public: virtual float Scale() const { return 1.0f; }; }; +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 3 + +struct MmapTileHeader +{ + uint32 mmapMagic; + uint32 dtVersion; + uint32 mmapVersion; + uint32 size; + bool usesLiquids : 1; + + MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), + mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} +}; + class Utils { public: diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index e5a14d55c0c..1a772a36558 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -92,7 +92,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v } } - if (def.DoodadSet >= 0 && def.DoodadSet < root->DoodadSets.size()) + if (def.DoodadSet < root->DoodadSets.size()) { DoodadSet set = root->DoodadSets[def.DoodadSet]; std::vector instances; -- cgit v1.2.3 From 5725b068d22a22b3e77f8887b2a1736854d85027 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 14:28:50 -0500 Subject: Tools/MeshExtractor: Fixed an uninitialized variable error. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 20 ++++++++++++-------- src/tools/mesh_extractor/Utils.h | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index f861dff1648..c63445b2287 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -29,7 +29,7 @@ void ContinentBuilder::Build() MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(uint8), builder.DataSize, f); + fwrite(nav, sizeof(unsigned char), builder.DataSize, f); } fclose(f); dtFree(nav); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 89fcaba5601..aa298cea698 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -88,7 +88,7 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -void DoodadHandler::InsertModelGeometry(const DoodadDefinition def, Model* model) +void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index c426504da32..aa7e3cac20d 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -43,7 +43,7 @@ protected: private: void ReadDoodadDefinitions(Chunk* chunk); void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(const DoodadDefinition def, Model* model); + void InsertModelGeometry(const DoodadDefinition& def, Model* model); std::set _drawn; std::vector* _definitions; std::vector* _paths; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 4736274706d..445641fc009 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -111,7 +111,7 @@ uint8* TileBuilder::Build() rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - printf("[%02u,%02u] Triangles rasterized!\n", X, Y); + printf("[%02i,%02i] Triangles rasterized!\n", X, Y); // Once all geometry is rasterized, we do initial pass of filtering to // remove unwanted overhangs caused by the conservative rasterization @@ -120,7 +120,7 @@ uint8* TileBuilder::Build() rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - printf("[%02u,%02u] Filtering done!\n", X, Y); + printf("[%02i,%02i] Filtering done!\n", X, Y); // Compact the heightfield so that it is faster to handle from now on. // This will result in more cache coherent data as well as the neighbours @@ -130,7 +130,7 @@ uint8* TileBuilder::Build() rcFreeHeightField(hf); - printf("[%02u,%02u] Heightfield compressed!\n", X, Y); + printf("[%02i,%02i] Heightfield compressed!\n", X, Y); // Erode the walkable area by agent radius. rcErodeWalkableArea(Context, Config.walkableRadius, *chf); @@ -139,7 +139,7 @@ uint8* TileBuilder::Build() // Partition the walkable surface into simple regions without holes. rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); - printf("[%02u,%02u] Regions built!\n", X, Y); + printf("[%02i,%02i] Regions built!\n", X, Y); // Create contours. rcContourSet* cset = rcAllocContourSet(); @@ -149,13 +149,13 @@ uint8* TileBuilder::Build() rcPolyMesh* pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); - printf("[%02u,%02u] Polymesh built!\n", X, Y); + printf("[%02i,%02i] Polymesh built!\n", X, Y); // Build detail mesh. rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - printf("[%02u,%02u] Polymesh detail built!\n", X, Y); + printf("[%02i,%02i] Polymesh detail built!\n", X, Y); rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); @@ -215,13 +215,17 @@ uint8* TileBuilder::Build() params.tileX = X; params.tileY = Y; params.tileSize = Config.width; + + // Offmesh-connection settings + params.offMeshConCount = 0; // none for now + int navDataSize; uint8* navData; - printf("[%02u,%02u] Creating the navmesh!\n", X, Y); + printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); if (result) { - printf("[%02u,%02u] NavMesh created, size %u!\n", X, Y, navDataSize); + printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 4cf20a4cf9d..188d47a88ce 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -533,7 +533,7 @@ struct MmapTileHeader uint32 dtVersion; uint32 mmapVersion; uint32 size; - bool usesLiquids : 1; + bool usesLiquids; MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} -- cgit v1.2.3 From 886f71df72a751abf1b742e67e7707cb623fd854 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 16:21:35 -0500 Subject: Tools/MeshExtract: Fixed linux build, thanks Dev[Acho]. Added a DBC class It will now autodetect your locale and start extracting mmaps as soon as started. --- src/tools/mesh_extractor/ADT.cpp | 9 +++- src/tools/mesh_extractor/CMakeLists.txt | 7 +++ src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 19 ++++++-- src/tools/mesh_extractor/ContinentBuilder.h | 4 +- src/tools/mesh_extractor/DBC.cpp | 64 ++++++++++++++++++++++++++ src/tools/mesh_extractor/DBC.h | 51 ++++++++++++++++++++ src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/MPQManager.cpp | 59 ++++++++++++++---------- src/tools/mesh_extractor/MPQManager.h | 6 ++- src/tools/mesh_extractor/MeshExtractor.cpp | 13 ++++++ src/tools/mesh_extractor/TileBuilder.cpp | 7 ++- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 4 +- src/tools/mesh_extractor/Utils.h | 4 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- 16 files changed, 214 insertions(+), 43 deletions(-) create mode 100644 src/tools/mesh_extractor/DBC.cpp create mode 100644 src/tools/mesh_extractor/DBC.h (limited to 'src') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index c564d7193cf..98bce8b2057 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -29,7 +29,14 @@ ADT::~ADT() void ADT::Read() { - Header.Read(Data->GetChunkByName("MHDR")->GetStream()); + Chunk* mhdr = Data->GetChunkByName("MHDR"); + if (!mhdr) + { + delete Data; + Data = NULL; + return; + } + Header.Read(mhdr->GetStream()); MapChunks.reserve(16 * 16); int mapChunkIndex = 0; diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 09bd2982213..8ef48a90742 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -15,6 +15,13 @@ if( UNIX ) include_directories ( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 799878bdd3b..83b6ba6ca7a 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -25,7 +25,7 @@ public: T* Get(K key) { - std::map::iterator itr = _items.find(key); + typename std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; @@ -33,7 +33,7 @@ public: void Clear() { - for (std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; _items.clear(); } diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index c63445b2287..7391ebb8767 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -6,7 +6,9 @@ void ContinentBuilder::Build() { - FILE* mmap = fopen("608.mmap", "wb"); + char buff[50]; + sprintf(buff, "%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); dtNavMeshParams params; params.maxPolys = 32768; params.maxTiles = 4096; @@ -19,19 +21,26 @@ void ContinentBuilder::Build() fclose(mmap); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - TileBuilder builder(Continent, itr->X, itr->Y, TileMap); + TileBuilder builder(Continent, itr->X, itr->Y, TileMap, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", builder.MapId, itr->X, itr->Y); - FILE* f = fopen(buff, "wb"); + sprintf(buff, "%03u%02u%02u.mmtile", MapId, itr->X, itr->Y); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. + { + fclose(f); + continue; + } uint8* nav = builder.Build(); if (nav) { + fclose(f); + f = fopen(buff, "wb"); MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); fwrite(nav, sizeof(unsigned char), builder.DataSize, f); + fclose(f); } - fclose(f); dtFree(nav); printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); } diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 7db141ddcf1..92c97c5f7e0 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -2,14 +2,16 @@ #define CONT_BUILDER_H #include #include "WDT.h" +#include "Common.h" class ContinentBuilder { public: - ContinentBuilder(std::string continent, WDT* wdt) : Continent(continent), TileMap(wdt) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt) : MapId(mapId), Continent(continent), TileMap(wdt) {} void Build(); private: std::string Continent; WDT* TileMap; + uint32 MapId; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp new file mode 100644 index 00000000000..be04ce070ee --- /dev/null +++ b/src/tools/mesh_extractor/DBC.cpp @@ -0,0 +1,64 @@ +#include +#include "DBC.h" +#include "Common.h" + +DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) +{ + char magic[5]; + fread(&magic, sizeof(char), 4, stream); + magic[4] = '\0'; + fread(&RecordCount, sizeof(uint32), 1, stream); + Records.reserve(RecordCount); + fread(&Fields, sizeof(uint32), 1, stream); + fread(&RecordSize, sizeof(uint32), 1, stream); + fread(&StringBlockSize, sizeof(uint32), 1, stream); + + for (int i = 0; i < RecordCount; i++) + { + Record* rec = new Record(this); + Records.push_back(rec); + int size = 0; + for (int f = 0; f < Fields; f++) + { + if (size + 4 > RecordSize) + { + IsFaulty = true; + break; + } + uint32 tmp; + fread(&tmp, sizeof(uint32), 1, stream); + rec->Values.push_back(tmp); + size += 4; + } + } + StringBlock = new uint8[StringBlockSize]; + fread(StringBlock, sizeof(uint8), StringBlockSize, stream); +} + +std::string DBC::GetStringByOffset( int offset ) +{ + int len = 0; + for (int i = offset; i < StringBlockSize; i++) + { + if (!StringBlock[i]) + { + len = (i - offset); + break; + } + } + char* d = new char[len+1]; + strcpy(d, (const char*)(StringBlock + offset)); + d[len] = '\0'; + std::string val = std::string(d); + delete d; + return val; +} + +Record* DBC::GetRecordById( int id ) +{ + // we assume Id is index 0 + for (std::vector::iterator itr = Records.begin(); itr != Records.end(); ++itr) + if ((*itr)->Values[0] == id) + return *itr; + return NULL; +} diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h new file mode 100644 index 00000000000..6c86c1391dd --- /dev/null +++ b/src/tools/mesh_extractor/DBC.h @@ -0,0 +1,51 @@ +#ifndef DBC_H +#define DBC_H +#include +#include "Common.h" + +class Record; + +class DBC +{ +public: + DBC(FILE* stream); + + std::string GetStringByOffset(int offset); + + Record* GetRecordById(int id); + + std::string Name; + std::vector Records; + int RecordCount; + int Fields; + int RecordSize; + uint8* StringBlock; + uint32 StringBlockSize; + bool IsFaulty; +}; + +class Record +{ +public: + Record(DBC* dbc) : Source(dbc) {} + + DBC* Source; + std::vector Values; + + int operator[](int index) + { + return Values[index]; + } + + float GetFloat(int index) + { + return *(float*)(&Values[index]); + } + + std::string GetString(int index) + { + return Source->GetStringByOffset(Values[index]); + } +}; + +#endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index aa298cea698..28bb9da5f21 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -2,7 +2,7 @@ #include "Chunk.h" #include "Cache.h" #include "Model.h" -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 35d4c91fc14..24e7e827548 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -1,5 +1,7 @@ #include "MPQManager.h" #include "MPQ.h" +#include "DBC.h" +#include "Utils.h" char* MPQManager::Files[] = { "common.MPQ", @@ -11,42 +13,43 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; +char* MPQManager::Languages[] = { "esES", "enUS", "enGB", "esMX", "deDE" }; + void MPQManager::Initialize() { - LoadMPQs(); + InitializeDBC(); + uint32 size = sizeof(Files) / sizeof(char*); + for (uint32 i = 0; i < size; ++i) + { + MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str()); + Archives.push_front(arc); + printf("Opened %s\n", Files[i]); + } } void MPQManager::LoadMaps() { - + DBC* file = GetDBC("Map"); + printf("NAME %s\n", file->GetRecordById(608)->GetString(1).c_str()); } -void MPQManager::LoadMPQs() +void MPQManager::InitializeDBC() { - // Load the locale MPQ files first - char filename[512]; - - /*sprintf(filename,"Data/%s/locale-%s.MPQ", langs[locale], langs[locale]);*/ - Archives.push_front(new MPQArchive("Data/enUS/locale-enUS.MPQ")); - - for(int i = 0; i < 3; ++i) + CurLocale = 0; + std::string fileName; + uint32 size = sizeof(Languages) / sizeof(char*); + for (uint32 i = 0; i < size; ++i) { - char ext[3] = ""; - if (i) - sprintf(ext, "-%i", i + 1); - - sprintf(filename, "Data/enUS/patch-enUS%s.MPQ", ext); - Archives.push_front(new MPQArchive(filename)); + fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; + FILE* file = fopen(fileName.c_str(), "rb"); + if (file) + { + CurLocale = i; + break; + } } - - // Now load the common MPQ files - int count = sizeof(Files) / sizeof(char*); - for (int i = 0; i < count; ++i) - { - sprintf(filename, "Data/%s", Files[i]); - Archives.push_front(new MPQArchive(filename)); - } - printf("Loaded %u MPQ files succesfully\n", Archives.size()); + Archives.push_front(new MPQArchive(fileName.c_str())); + printf("Using locale: %s\n", Languages[CurLocale]); } FILE* MPQManager::GetFile( std::string path ) @@ -56,3 +59,9 @@ FILE* MPQManager::GetFile( std::string path ) return NULL; return file.GetFileStream(); } + +DBC* MPQManager::GetDBC( std::string name ) +{ + std::string path = "DBFilesClient\\" + name + ".dbc"; + return new DBC(GetFile(path)); +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index e10066ae4a6..725e0168237 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -3,6 +3,7 @@ #include "MPQ.h" +class DBC; class MPQManager { public: @@ -12,12 +13,15 @@ public: void Initialize(); void LoadMaps(); FILE* GetFile(std::string path); + DBC* GetDBC(std::string name); std::deque Archives; + uint32 CurLocale; static char* Files[]; + static char* Languages[]; protected: - void LoadMPQs(); + void InitializeDBC(); }; extern MPQManager* MPQHandler; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 38a120449bc..77b5a8e8c3d 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -2,6 +2,7 @@ #include "WDT.h" #include "ContinentBuilder.h" #include "Cache.h" +#include "DBC.h" #include "Common.h" #include "LoginDatabase.h" @@ -12,6 +13,17 @@ CacheClass* Cache; void ExtractAllMaps() { + DBC* dbc = MPQHandler->GetDBC("Map"); + for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + { + std::string name = (*itr)->GetString(1); + WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); + if (!wdt.IsValid || wdt.IsGlobalModel) + continue; + ContinentBuilder builder(name, (*itr)->Values[0], &wdt); + builder.Build(); + } + /* WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); if (!wdt.IsValid) return; @@ -23,6 +35,7 @@ void ExtractAllMaps() } ContinentBuilder builder("DalaranPrison", &wdt); builder.Build(); + */ } int main(int argc, char* argv[]) diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 445641fc009..8bbfd5afb69 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,7 +9,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt) : _Geometry(NULL), World(world), X(x), Y(y), MapId(608), DataSize(0), Wdt(wdt) +TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), Wdt(wdt) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize @@ -54,6 +54,11 @@ uint8* TileBuilder::Build() { adt = new ADT(Utils::GetAdtPath(World, X, Y)); adt->Read(); + if (!adt->Data) + { + delete adt; + return NULL; + } Cache->AdtCache.Insert(std::make_pair(X, Y), adt); } _Geometry->AddAdt(adt); diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 7dff363cabe..261675af7e2 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -10,7 +10,7 @@ class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, WDT* wdt); + TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index c7c0cff0d42..2f07bd20080 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -2,8 +2,8 @@ #include "WorldModelHandler.h" #include "Constants.h" #include -#include "g3d/Matrix4.h" -#include "g3d/Quat.h" +#include "G3D/Matrix4.h" +#include "G3D/Quat.h" const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 188d47a88ce..c247169df73 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -4,7 +4,7 @@ #include #include -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" #include "DetourNavMesh.h" #include "Common.h" @@ -573,7 +573,7 @@ public: return false; return true; } - static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ); + static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 1a772a36558..636b06f6f73 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -4,7 +4,7 @@ #include "Cache.h" #include "Model.h" #include "Common.h" -#include "g3d/Matrix4.h" +#include "G3D/Matrix4.h" #include WorldModelDefinition WorldModelDefinition::Read( FILE* file ) -- cgit v1.2.3 From eba6980b9a52f55859cb3bd93235e14866769514 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 16:26:43 -0500 Subject: Tools/MeshExtractor: Allow to extract only 1 map ( via command line ) --- src/tools/mesh_extractor/MeshExtractor.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 77b5a8e8c3d..a99cc4475a0 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -11,16 +11,20 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps() +void ExtractAllMaps(uint32 onlyMap) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { + uint32 mapId = (*itr)->Values[0]; + if (onlyMap && mapId != onlyMap) + continue; std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; - ContinentBuilder builder(name, (*itr)->Values[0], &wdt); + printf("Building %s MapId %u\n", name, mapId); + ContinentBuilder builder(name, mapId, &wdt); builder.Build(); } /* @@ -45,7 +49,10 @@ int main(int argc, char* argv[]) MPQHandler = new MPQManager(); MPQHandler->Initialize(); MPQHandler->LoadMaps(); - ExtractAllMaps(); + uint32 onlyMap = 0; + if (argc == 2) + onlyMap = uint32(atoi(argv[1])); + ExtractAllMaps(onlyMap); return 0; } -- cgit v1.2.3 From 9b97a89ef8e1dd1694985d1fc8e88808da1550cd Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 17:09:44 -0500 Subject: Tools/MeshExtractor: Fixed a crash and some other mistakes. First glances of multithreading ( need to figure out a way around StormLib ) --- src/tools/mesh_extractor/ContinentBuilder.cpp | 88 +++++++++++++++++++++------ src/tools/mesh_extractor/MapChunk.cpp | 1 + src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.h | 3 +- 5 files changed, 73 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 7391ebb8767..02a4d3626b7 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -3,32 +3,29 @@ #include "WDT.h" #include "Utils.h" #include "DetourNavMesh.h" +#include "ace/Task.h" -void ContinentBuilder::Build() +class BuilderThread : public ACE_Task { - char buff[50]; - sprintf(buff, "%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - dtNavMeshParams params; - params.maxPolys = 32768; - params.maxTiles = 4096; - params.orig[0] = -17066.666f; - params.orig[1] = 0.0f; - params.orig[2] = -17066.666f; - params.tileHeight = 533.33333f; - params.tileWidth = 533.33333f; - fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) +private: + int X, Y, MapId; + std::string Continent; +public: + BuilderThread() : Free(true) {} + void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } + + int svc() { - TileBuilder builder(Continent, itr->X, itr->Y, TileMap, MapId); + Free = false; + TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", MapId, itr->X, itr->Y); + sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { fclose(f); - continue; + Free = true; + return 0; } uint8* nav = builder.Build(); if (nav) @@ -42,6 +39,59 @@ void ContinentBuilder::Build() fclose(f); } dtFree(nav); - printf("[%02u,%02u] Tile Built!\n", itr->X, itr->Y); + printf("[%02u,%02u] Tile Built!\n", X, Y); + Free = true; + return 0; } + + bool Free; +}; + +void ContinentBuilder::Build() +{ + char buff[50]; + sprintf(buff, "%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); + dtNavMeshParams params; + params.maxPolys = 32768; + params.maxTiles = 4096; + params.orig[0] = -17066.666f; + params.orig[1] = 0.0f; + params.orig[2] = -17066.666f; + params.tileHeight = 533.33333f; + params.tileWidth = 533.33333f; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + std::vector Threads; + /*for (uint32 i = 0; i < 1; ++i) + Threads.push_back(new BuilderThread());*/ + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + BuilderThread th; + th.SetData(itr->X, itr->Y, MapId, Continent); + th.svc(); + /*bool next = false; + while (!next) + { + for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) + { + if ((*_th)->Free) + { + (*_th)->SetData(itr->X, itr->Y, MapId, Continent); + (*_th)->activate(); + next = true; + break; + } + } + // Wait for 20 seconds + ACE_OS::sleep(ACE_Time_Value (0, 20000)); + }*/ + } + + /*// Free memory + for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) + { + (*_th)->wait(); + delete *_th; + }*/ } diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 61c106f9766..debde08cda8 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -7,6 +7,7 @@ MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) FILE* stream = chunk->GetStream(); Header.Read(stream); fseek(stream, chunk->Offset, SEEK_SET); + Index = Header.IndexX + Header.IndexY * 16; GenerateVertices(stream); } diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index a99cc4475a0..7ae6afadb84 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -23,7 +23,7 @@ void ExtractAllMaps(uint32 onlyMap) WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; - printf("Building %s MapId %u\n", name, mapId); + printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt); builder.Build(); } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 8bbfd5afb69..baf1fa0375c 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,7 +9,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -TileBuilder::TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), Wdt(wdt) +TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 261675af7e2..f91a732f70c 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -10,7 +10,7 @@ class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, WDT* wdt, uint32 mapId); + TileBuilder(std::string world, int x, int y, uint32 mapId); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); @@ -22,6 +22,5 @@ public: rcContext* Context; Geometry* _Geometry; uint32 DataSize; - WDT* Wdt; }; #endif \ No newline at end of file -- cgit v1.2.3 From 95db9605ce227403eb4ea7fa46c91f47eb51a3ac Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 17:28:20 -0500 Subject: Tools/MeshExtractor: Removed extra fclose --- src/tools/mesh_extractor/ContinentBuilder.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 02a4d3626b7..29541da508c 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -30,7 +30,6 @@ public: uint8* nav = builder.Build(); if (nav) { - fclose(f); f = fopen(buff, "wb"); MmapTileHeader header; header.size = builder.DataSize; -- cgit v1.2.3 From 6b23d2f7710a7b1e39ec7d43c9a3b04345caa988 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 28 Sep 2012 19:08:01 -0500 Subject: Core/Build: Fixed build --- src/server/scripts/Commands/cs_mmaps.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index e4a0ebf7f24..be2d52b5925 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -32,6 +32,9 @@ #include "MMapFactory.h" #include "Map.h" #include "TargetedMovementGenerator.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" class mmaps_commandscript : public CommandScript { -- cgit v1.2.3 From 3bea28e62c00a5f73e4b58cd554db28666b1d54b Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 06:24:35 -0500 Subject: Tools/MeshExtractor: Fixed a crash and bad data for liquids --- src/tools/mesh_extractor/ContinentBuilder.cpp | 1 + src/tools/mesh_extractor/LiquidHandler.cpp | 3 +++ src/tools/mesh_extractor/MapChunk.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 29541da508c..9d3b18491f1 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -17,6 +17,7 @@ public: int svc() { Free = false; + printf("[%02i,%02i] Building tile", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 3d0876aeb74..f6f8e5678c6 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -31,7 +31,10 @@ void LiquidHandler::HandleNewLiquid() float** heights = new float*[9]; for (int i = 0; i < 9; ++i) + { heights[i] = new float[9]; + memset(heights[i], 0, sizeof(float) * 9); + } H2ORenderMask renderMask; if (information.LiquidType != 2) diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index debde08cda8..67f4061035e 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -31,7 +31,7 @@ void MapChunk::GenerateTriangles() if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) { MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; - uint32 maxHeight = std::max( + float maxHeight = std::max( std::max( std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), Vertices[bottomRight].z), Vertices[center].z); -- cgit v1.2.3 From 1a7f0658b2a78a2c082b5f648548375b5d0f29e9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 12:49:14 -0500 Subject: Tools/MeshExtractor: * Fixed some crashes * Added multithreading support, default to 4 threads. * Added some command line arguments --- src/tools/mesh_extractor/ADT.cpp | 9 +--- src/tools/mesh_extractor/Cache.h | 3 ++ src/tools/mesh_extractor/ContinentBuilder.cpp | 19 ++++--- src/tools/mesh_extractor/ContinentBuilder.h | 3 +- src/tools/mesh_extractor/LiquidHandler.cpp | 4 ++ src/tools/mesh_extractor/MPQManager.cpp | 9 ++-- src/tools/mesh_extractor/MPQManager.h | 4 +- src/tools/mesh_extractor/MeshExtractor.cpp | 74 ++++++++++++++++++++------- src/tools/mesh_extractor/TileBuilder.cpp | 8 +-- 9 files changed, 82 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 98bce8b2057..c564d7193cf 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -29,14 +29,7 @@ ADT::~ADT() void ADT::Read() { - Chunk* mhdr = Data->GetChunkByName("MHDR"); - if (!mhdr) - { - delete Data; - Data = NULL; - return; - } - Header.Read(mhdr->GetStream()); + Header.Read(Data->GetChunkByName("MHDR")->GetStream()); MapChunks.reserve(16 * 16); int mapChunkIndex = 0; diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 83b6ba6ca7a..49e268ec507 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -3,6 +3,7 @@ #include #include #include "Common.h" +#include "ace/Synch.h" class WorldModelRoot; class Model; @@ -20,6 +21,7 @@ public: { if (_items.size() > FlushLimit) Clear(); + ACE_GUARD(ACE_Thread_Mutex, g, mutex); _items[key] = val; } @@ -39,6 +41,7 @@ public: } private: std::map _items; + ACE_Thread_Mutex mutex; }; class CacheClass diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 9d3b18491f1..96f9085de8c 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -3,6 +3,7 @@ #include "WDT.h" #include "Utils.h" #include "DetourNavMesh.h" +#include "Cache.h" #include "ace/Task.h" class BuilderThread : public ACE_Task @@ -17,7 +18,7 @@ public: int svc() { Free = false; - printf("[%02i,%02i] Building tile", X, Y); + printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); @@ -63,14 +64,11 @@ void ContinentBuilder::Build() fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; - /*for (uint32 i = 0; i < 1; ++i) - Threads.push_back(new BuilderThread());*/ + for (uint32 i = 0; i < NumberOfThreads; ++i) + Threads.push_back(new BuilderThread()); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - BuilderThread th; - th.SetData(itr->X, itr->Y, MapId, Continent); - th.svc(); - /*bool next = false; + bool next = false; while (!next) { for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) @@ -85,13 +83,14 @@ void ContinentBuilder::Build() } // Wait for 20 seconds ACE_OS::sleep(ACE_Time_Value (0, 20000)); - }*/ + } } + Cache->Clear(); - /*// Free memory + // Free memory for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) { (*_th)->wait(); delete *_th; - }*/ + } } diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 92c97c5f7e0..d3da984595d 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,11 +7,12 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt) : MapId(mapId), Continent(continent), TileMap(wdt) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} void Build(); private: std::string Continent; WDT* TileMap; uint32 MapId; + uint32 NumberOfThreads; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index f6f8e5678c6..9a40e08b73a 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -25,7 +25,11 @@ void LiquidHandler::HandleNewLiquid() { H2OHeader h = header[i]; if (h.LayerCount == 0) + { + // Need to fill in missing data with dummies. + MCNKData.push_back(MCNKLiquidData(NULL, H2ORenderMask())); continue; + } fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); H2OInformation information = H2OInformation::Read(stream); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 24e7e827548..5ea6198e76d 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -3,6 +3,8 @@ #include "DBC.h" #include "Utils.h" +#include "ace/Synch.h" + char* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", @@ -27,12 +29,6 @@ void MPQManager::Initialize() } } -void MPQManager::LoadMaps() -{ - DBC* file = GetDBC("Map"); - printf("NAME %s\n", file->GetRecordById(608)->GetString(1).c_str()); -} - void MPQManager::InitializeDBC() { CurLocale = 0; @@ -54,6 +50,7 @@ void MPQManager::InitializeDBC() FILE* MPQManager::GetFile( std::string path ) { + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); MPQFile file(path.c_str()); if (file.isEof()) return NULL; diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 725e0168237..634c70cedeb 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -2,6 +2,7 @@ #define MPQ_MANAGER_H #include "MPQ.h" +#include "ace/Synch.h" class DBC; class MPQManager @@ -11,7 +12,6 @@ public: ~MPQManager() {} void Initialize(); - void LoadMaps(); FILE* GetFile(std::string path); DBC* GetDBC(std::string name); @@ -22,6 +22,8 @@ public: static char* Languages[]; protected: void InitializeDBC(); +private: + ACE_Thread_Mutex mutex; }; extern MPQManager* MPQHandler; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 7ae6afadb84..2884b998ac8 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -4,42 +4,73 @@ #include "Cache.h" #include "DBC.h" +#include + #include "Common.h" #include "LoginDatabase.h" +#include "Util.h" LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(uint32 onlyMap) +void ExtractAllMaps(std::set& mapIds, uint32 threads) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { uint32 mapId = (*itr)->Values[0]; - if (onlyMap && mapId != onlyMap) + + // Skip this map if a list of specific maps was provided and this one is not contained in it. + if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) continue; + std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) continue; printf("Building %s MapId %u\n", name.c_str(), mapId); - ContinentBuilder builder(name, mapId, &wdt); + ContinentBuilder builder(name, mapId, &wdt, threads); builder.Build(); } - /* - WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt"); - if (!wdt.IsValid) - return; - printf("Model valid!\n"); - if (wdt.IsGlobalModel) +} + +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList) +{ + char* param = NULL; + for (int i = 1; i < argc; ++i) { - printf("Unsupported\n"); - return; + if (strcmp(argv[i], "--threads") == 0) + { + param = argv[++i]; + if (!param) + return false; + + threads = atoi(param); + printf("Using %i threads\n", threads); + } + if (strcmp(argv[i], "--maps") == 0) + { + param = argv[++i]; + if (!param) + return false; + std::string maps = std::string(param); + Tokens tokens(maps, ','); + + for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) + mapList.insert(atoi(*itr)); + + printf("Extracting only provided list of maps (%u).\n", mapList.size()); + } } - ContinentBuilder builder("DalaranPrison", &wdt); - builder.Build(); - */ + return true; +} + +void PrintUsage() +{ + printf("MeshExtractor help.\n"); + printf("* Use \"--threads \" to specify threads, default to 4\n"); + printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); } int main(int argc, char* argv[]) @@ -48,11 +79,16 @@ int main(int argc, char* argv[]) Cache = new CacheClass(); MPQHandler = new MPQManager(); MPQHandler->Initialize(); - MPQHandler->LoadMaps(); - uint32 onlyMap = 0; - if (argc == 2) - onlyMap = uint32(atoi(argv[1])); - ExtractAllMaps(onlyMap); + uint32 threads = 4; + std::set mapIds; + + if (!HandleArgs(argc, argv, threads, mapIds)) + { + PrintUsage(); + return -1; + } + + ExtractAllMaps(mapIds, threads); return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index baf1fa0375c..926d2591f1a 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -9,6 +9,8 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" +#include "ace/Synch.h" + TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) { // Cell Size = TileSize / TileVoxelSize @@ -54,11 +56,6 @@ uint8* TileBuilder::Build() { adt = new ADT(Utils::GetAdtPath(World, X, Y)); adt->Read(); - if (!adt->Data) - { - delete adt; - return NULL; - } Cache->AdtCache.Insert(std::make_pair(X, Y), adt); } _Geometry->AddAdt(adt); @@ -234,7 +231,6 @@ uint8* TileBuilder::Build() DataSize = navDataSize; rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - Cache->Clear(); return navData; } -- cgit v1.2.3 From 987436ceeac3c463a81d3b2cab05ff3c532dbbf8 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 15:38:31 -0500 Subject: Tools/MeshExtractor: Get rid of some memory leaks --- src/tools/mesh_extractor/ChunkedData.cpp | 9 +++++++++ src/tools/mesh_extractor/ChunkedData.h | 1 + src/tools/mesh_extractor/DoodadHandler.cpp | 6 ++++++ src/tools/mesh_extractor/DoodadHandler.h | 2 ++ src/tools/mesh_extractor/LiquidHandler.h | 1 + src/tools/mesh_extractor/TileBuilder.cpp | 24 +++++++++++++++++++----- src/tools/mesh_extractor/TileBuilder.h | 2 ++ src/tools/mesh_extractor/WorldModelHandler.cpp | 8 +++++++- src/tools/mesh_extractor/WorldModelHandler.h | 1 + 9 files changed, 48 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 470b8b94f39..35b1bcd5af0 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -61,3 +61,12 @@ Chunk* ChunkedData::GetChunkByName( std::string name ) return Chunks[i]; return NULL; } + +ChunkedData::~ChunkedData() +{ + for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) + delete *itr; + + Chunks.clear(); + fclose(Stream); +} diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index 6e102828222..d36d0868859 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -9,6 +9,7 @@ class ChunkedData public: ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); ChunkedData(std::string file, uint32 chunksHint = 300); + ~ChunkedData(); int GetFirstIndex(std::string name); Chunk* GetChunkByName(std::string name); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 28bb9da5f21..6604aebe73a 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -99,3 +99,9 @@ void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* mode for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } + +DoodadHandler::~DoodadHandler() +{ + delete _definitions; + delete _paths; +} diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index aa7e3cac20d..2e00696f7e5 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -32,6 +32,8 @@ class DoodadHandler : public ObjectDataHandler { public: DoodadHandler(ADT* adt); + ~DoodadHandler(); + std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index 138b2da2ad9..6e8d0081adb 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -10,6 +10,7 @@ class LiquidHandler { public: LiquidHandler(ADT* adt); + ADT* Source; std::vector Vertices; std::vector > Triangles; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 926d2591f1a..5c2c4faab80 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -225,16 +225,30 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - if (result) + + // Free some memory + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete tilebMax; + delete tilebMin; + delete areas; + delete triangles; + delete vertices; + delete bbMax; + delete bbMin; + + if (result) { printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); return navData; } - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); return NULL; } + +TileBuilder::~TileBuilder() +{ + delete Context; + delete _Geometry; +} diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index f91a732f70c..e56b926e5a5 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -11,6 +11,8 @@ class TileBuilder { public: TileBuilder(std::string world, int x, int y, uint32 mapId); + ~TileBuilder(); + void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 636b06f6f73..edad6d1b6d8 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -24,7 +24,7 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) } -WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt) +WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { if (!adt->HasObjectData) return; @@ -190,3 +190,9 @@ void WorldModelHandler::ReadModelPaths() _paths->push_back(Utils::ReadString(dataStream)); } } + +WorldModelHandler::~WorldModelHandler() +{ + delete _definitions; + delete _paths; +} diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index daf0713ecd2..df5e3764eb5 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -29,6 +29,7 @@ class WorldModelHandler : public ObjectDataHandler { public: WorldModelHandler(ADT* adt); + ~WorldModelHandler(); std::vector Vertices; std::vector > Triangles; -- cgit v1.2.3 From 5c9e917e5e2a4c934aaa7d061624a46ff4269c8f Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 29 Sep 2012 16:19:33 -0500 Subject: Core/MMaps: Removed an incorrect call to GetHeight Tools/MeshExtractor: Fixed a crash caused by calling fclose in a NULL stream --- src/server/game/Movement/PathGenerator.cpp | 6 +----- src/tools/mesh_extractor/ChunkedData.cpp | 3 ++- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 9635399e71f..6e765b1ee27 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -58,12 +58,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; - float newDestZ = _sourceUnit->GetBaseMap()->GetHeight(_sourceUnit->GetPhaseMask(), x, y, z, true, MAX_FALL_DISTANCE); - if (newDestZ <= INVALID_HEIGHT) - return false; - Vector3 oldDest = GetEndPosition(); - Vector3 dest(destX, destY, newDestZ); + Vector3 dest(destX, destY, destZ); SetEndPosition(dest); Vector3 start(x, y, z); diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 35b1bcd5af0..4c59217ed33 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -68,5 +68,6 @@ ChunkedData::~ChunkedData() delete *itr; Chunks.clear(); - fclose(Stream); + if (Stream) + fclose(Stream); } -- cgit v1.2.3 From 14b304d4f726aeaf5f48fdac4cd9ce8aad66c5c9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 30 Sep 2012 08:27:56 -0500 Subject: Tools/MeshExtractor: * Removed the cache of ADTs * Add the correct geometry for neighbor ADTs * Fixes more crashes * Calculate the correct bounds for the map tiles. --- src/tools/mesh_extractor/ADT.cpp | 1 + src/tools/mesh_extractor/Cache.h | 11 +++--- src/tools/mesh_extractor/ContinentBuilder.cpp | 57 +++++++++++++++++++++++---- src/tools/mesh_extractor/TileBuilder.cpp | 30 ++++++-------- 4 files changed, 68 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index c564d7193cf..1684d0636f4 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -2,6 +2,7 @@ #include "DoodadHandler.h" #include "LiquidHandler.h" #include "WorldModelHandler.h" +#include "Cache.h" ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) { diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 49e268ec507..36bf4a7a693 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -7,7 +7,6 @@ class WorldModelRoot; class Model; -class ADT; template class GenericCache @@ -19,21 +18,23 @@ public: void Insert(K key, T* val) { + ACE_GUARD(ACE_Thread_Mutex, g, mutex); + if (_items.size() > FlushLimit) Clear(); - ACE_GUARD(ACE_Thread_Mutex, g, mutex); _items[key] = val; } T* Get(K key) { + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); typename std::map::iterator itr = _items.find(key); if (itr != _items.end()) return itr->second; return NULL; } - void Clear() + void Clear() { for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; @@ -50,10 +51,10 @@ public: CacheClass() {} GenericCache ModelCache; GenericCache WorldModelCache; - GenericCache, ADT> AdtCache; + void Clear() { - AdtCache.Clear(); + } }; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 96f9085de8c..cdfe0ca050a 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -5,6 +5,7 @@ #include "DetourNavMesh.h" #include "Cache.h" #include "ace/Task.h" +#include "Recast.h" class BuilderThread : public ACE_Task { @@ -21,18 +22,24 @@ public: printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y); + sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, X, Y); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { + printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); fclose(f); Free = true; - return 0; + return 1; } uint8* nav = builder.Build(); if (nav) { f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return -1; + } MmapTileHeader header; header.size = builder.DataSize; fwrite(&header, sizeof(MmapTileHeader), 1, f); @@ -48,17 +55,52 @@ public: bool Free; }; +void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +{ + // this is for elevation + if (verts && vertCount) + rcCalcBounds(verts, vertCount, bmin, bmax); + else + { + bmin[1] = FLT_MIN; + bmax[1] = FLT_MAX; + } + + // this is for width and depth + bmax[0] = (32 - int(tileX)) * Constants::TileSize; + bmax[2] = (32 - int(tileY)) * Constants::TileSize; + bmin[0] = bmax[0] - Constants::TileSize; + bmin[2] = bmax[2] - Constants::TileSize; +} + void ContinentBuilder::Build() { char buff[50]; - sprintf(buff, "%03u.mmap", MapId); + sprintf(buff, "mmaps/%03u.mmap", MapId); FILE* mmap = fopen(buff, "wb"); + if (!mmap) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + + int tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0; + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + { + tileXMax = std::max(itr->X, tileXMax); + tileXMin = std::min(itr->X, tileXMin); + + tileYMax = std::max(itr->Y, tileYMax); + tileYMin = std::min(itr->Y, tileYMin); + } + + float bmin[3], bmax[3]; + getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); + dtNavMeshParams params; params.maxPolys = 32768; - params.maxTiles = 4096; - params.orig[0] = -17066.666f; - params.orig[1] = 0.0f; - params.orig[2] = -17066.666f; + params.maxTiles = TileMap->TileTable.size(); + rcVcopy(params.orig, bmin); params.tileHeight = 533.33333f; params.tileWidth = 533.33333f; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); @@ -66,6 +108,7 @@ void ContinentBuilder::Build() std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread()); + printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5c2c4faab80..83137258710 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -51,14 +51,10 @@ uint8* TileBuilder::Build() { _Geometry = new Geometry(); _Geometry->Transform = true; - ADT* adt = Cache->AdtCache.Get(std::make_pair(X, Y)); - if (!adt) - { - adt = new ADT(Utils::GetAdtPath(World, X, Y)); - adt->Read(); - Cache->AdtCache.Insert(std::make_pair(X, Y), adt); - } + ADT* adt = new ADT(Utils::GetAdtPath(World, X, Y)); + adt->Read(); _Geometry->AddAdt(adt); + delete adt; if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; @@ -77,20 +73,16 @@ uint8* TileBuilder::Build() if (tx == X && ty == Y) continue; - ADT* _adt = Cache->AdtCache.Get(std::make_pair(tx, ty)); - if (!_adt) + ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); + // If this condition is met, it means that this wdt does not contain the ADT + if (!_adt->Data->Stream) { - _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); - // If this condition is met, it means that this wdt does not contain the ADT - if (!_adt->Data->Stream) - { - delete _adt; - continue; - } - _adt->Read(); - Cache->AdtCache.Insert(std::make_pair(tx, ty), _adt); + delete _adt; + continue; } - _Geometry->AddAdt(adt); + _adt->Read(); + _Geometry->AddAdt(_adt); + delete _adt; } } uint32 numVerts = _Geometry->Vertices.size(); -- cgit v1.2.3 From d63e1276d602b0172f2d32abe85ec718a7bc7912 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 30 Sep 2012 15:38:03 +0100 Subject: Tools/MeshExtractor: tabs2spaces --- src/tools/mesh_extractor/ChunkedData.cpp | 12 +++++------ src/tools/mesh_extractor/ChunkedData.h | 2 +- src/tools/mesh_extractor/DoodadHandler.cpp | 4 ++-- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 30 +++++++++++++------------- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 4 ++-- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 9 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4c59217ed33..725a6f45637 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -64,10 +64,10 @@ Chunk* ChunkedData::GetChunkByName( std::string name ) ChunkedData::~ChunkedData() { - for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) - delete *itr; - - Chunks.clear(); - if (Stream) - fclose(Stream); + for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) + delete *itr; + + Chunks.clear(); + if (Stream) + fclose(Stream); } diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index d36d0868859..e23648c845e 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -9,7 +9,7 @@ class ChunkedData public: ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); ChunkedData(std::string file, uint32 chunksHint = 300); - ~ChunkedData(); + ~ChunkedData(); int GetFirstIndex(std::string name); Chunk* GetChunkByName(std::string name); diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 6604aebe73a..363f07b4578 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -102,6 +102,6 @@ void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* mode DoodadHandler::~DoodadHandler() { - delete _definitions; - delete _paths; + delete _definitions; + delete _paths; } diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 2e00696f7e5..a212b032d1d 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -32,7 +32,7 @@ class DoodadHandler : public ObjectDataHandler { public: DoodadHandler(ADT* adt); - ~DoodadHandler(); + ~DoodadHandler(); std::vector Vertices; std::vector > Triangles; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 2884b998ac8..3dde9ac36f5 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -89,6 +89,6 @@ int main(int argc, char* argv[]) } ExtractAllMaps(mapIds, threads); - return 0; + return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 83137258710..e3694541be8 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -217,19 +217,19 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - - // Free some memory - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - delete tilebMax; - delete tilebMin; - delete areas; - delete triangles; - delete vertices; - delete bbMax; - delete bbMin; - - if (result) + + // Free some memory + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete tilebMax; + delete tilebMin; + delete areas; + delete triangles; + delete vertices; + delete bbMax; + delete bbMin; + + if (result) { printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); DataSize = navDataSize; @@ -241,6 +241,6 @@ uint8* TileBuilder::Build() TileBuilder::~TileBuilder() { - delete Context; - delete _Geometry; + delete Context; + delete _Geometry; } diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index e56b926e5a5..2ec45811676 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -11,7 +11,7 @@ class TileBuilder { public: TileBuilder(std::string world, int x, int y, uint32 mapId); - ~TileBuilder(); + ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax); uint8* Build(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index edad6d1b6d8..a0977c398c4 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -193,6 +193,6 @@ void WorldModelHandler::ReadModelPaths() WorldModelHandler::~WorldModelHandler() { - delete _definitions; - delete _paths; + delete _definitions; + delete _paths; } diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index df5e3764eb5..cccedfa60fb 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -29,7 +29,7 @@ class WorldModelHandler : public ObjectDataHandler { public: WorldModelHandler(ADT* adt); - ~WorldModelHandler(); + ~WorldModelHandler(); std::vector Vertices; std::vector > Triangles; -- cgit v1.2.3 From 4c3266c7af5f5840a212d46bf068a793150b34fc Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 30 Sep 2012 15:52:10 +0100 Subject: Tools&Core: Whitespace cleanup No one likes whitespace, right? --- src/server/game/Maps/Map.cpp | 2 +- src/server/game/Movement/MotionMaster.cpp | 2 +- .../MovementGenerators/TargetedMovementGenerator.cpp | 2 +- src/server/game/Movement/PathGenerator.cpp | 4 ++-- src/server/scripts/Commands/cs_mmaps.cpp | 4 ++-- src/tools/map_extractor/System.cpp | 2 +- src/tools/mesh_extractor/ADT.cpp | 2 +- src/tools/mesh_extractor/ADT.h | 2 +- src/tools/mesh_extractor/Cache.h | 10 +++++----- src/tools/mesh_extractor/ChunkedData.cpp | 4 ++-- src/tools/mesh_extractor/Geometry.cpp | 4 ++-- src/tools/mesh_extractor/Geometry.h | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 2 +- src/tools/mesh_extractor/MPQ.cpp | 10 +++++----- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MPQManager.h | 2 +- src/tools/mesh_extractor/MapChunk.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/ObjectDataHandler.h | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 14 +++++++------- src/tools/mesh_extractor/Utils.cpp | 2 +- src/tools/mesh_extractor/Utils.h | 4 ++-- src/tools/mesh_extractor/WDT.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 26 files changed, 49 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index ae192f16080..25ffc1d19f2 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -123,7 +123,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); - + if (mmapLoadResult) sLog->outInfo(LOG_FILTER_MAPS, "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); else diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 34be779a8b7..386a95fa838 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -428,7 +428,7 @@ void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) Vector3 dest = path.GetActualEndPosition(); MoveCharge(dest.x, dest.y, dest.z); - + Movement::MoveSplineInit init(_owner); init.MovebyPath(path.GetPath()); init.SetVelocity(speed); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index c275c33032f..7a6611ed2ca 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -124,7 +124,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d D::_clearUnitStateMove(owner); return true; } - + // prevent movement while casting spells with cast time or channel time if (owner->HasUnitState(UNIT_STATE_CASTING)) { diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 6e765b1ee27..3495c4d1218 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -469,7 +469,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin _pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]); NormalizePath(); - + // first point is always our current location - we need the next one SetActualEndPosition(_pathPoints[pointCount-1]); @@ -515,7 +515,7 @@ void PathGenerator::BuildShortcut() _pathPoints[1] = GetActualEndPosition(); NormalizePath(); - + _type = PATHFIND_SHORTCUT; } diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index be2d52b5925..c3f757614e2 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -152,7 +152,7 @@ public: // navmesh poly -> navmesh tile location dtQueryFilter filter = dtQueryFilter(); - dtPolyRef polyRef = INVALID_POLYREF; + dtPolyRef polyRef = INVALID_POLYREF; navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL); if (polyRef == INVALID_POLYREF) @@ -252,7 +252,7 @@ public: CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()) ); Cell cell(pair); cell.SetNoCreate(); - + std::list creatureList; Trinity::AnyUnitInObjectRangeCheck go_check(object, radius); diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 552bab30d50..2e117934679 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -852,7 +852,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, hasHoles = true; } } - + if (hasHoles) map.holesSize = sizeof(holes); else diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 1684d0636f4..a6c080cf0b0 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -18,7 +18,7 @@ ADT::~ADT() { delete ObjectData; delete Data; - + for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) delete *itr; diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 096f491eed8..133596eb024 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -12,7 +12,7 @@ class ADT public: ADT(std::string file); ~ADT(); - + void Read(); ChunkedData* ObjectData; diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 36bf4a7a693..90e2c138376 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -15,7 +15,7 @@ public: GenericCache() {} static const int32 FlushLimit = 1000; - + void Insert(K key, T* val) { ACE_GUARD(ACE_Thread_Mutex, g, mutex); @@ -35,10 +35,10 @@ public: } void Clear() - { - for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) + { + for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) delete itr->second; - _items.clear(); + _items.clear(); } private: std::map _items; @@ -54,7 +54,7 @@ public: void Clear() { - + } }; diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 725a6f45637..4431993e3d1 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -4,7 +4,7 @@ #include -ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : +ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : Stream(stream) { if (!Stream) @@ -66,7 +66,7 @@ ChunkedData::~ChunkedData() { for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) delete *itr; - + Chunks.clear(); if (Stream) fclose(Stream); diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 2fbe99e3211..2fc470e8e9f 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -63,7 +63,7 @@ void Geometry::AddData( std::vector& verts, std::vector::iterator itr = verts.begin(); itr != verts.end(); ++itr) Vertices.push_back(Transform ? Utils::ToRecast(*itr) : *itr); - + for (std::vector >::iterator itr = tris.begin(); itr != tris.end(); ++itr) Triangles.push_back(Triangle(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); } @@ -116,7 +116,7 @@ void Geometry::AddAdt( ADT* adt ) if (!adt->_DoodadHandler->Triangles.empty()) AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); - + if (!adt->_WorldModelHandler->Triangles.empty()) AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); } diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h index 9593c98044e..e445234dd12 100644 --- a/src/tools/mesh_extractor/Geometry.h +++ b/src/tools/mesh_extractor/Geometry.h @@ -9,7 +9,7 @@ class Geometry { public: Geometry(); - + void CalculateBoundingBox(float*& min, float*& max); void CalculateMinMaxHeight(float& min, float& max); void AddData(std::vector& verts, std::vector >& tris); diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 9a40e08b73a..5b998d75db9 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -20,7 +20,7 @@ void LiquidHandler::HandleNewLiquid() MCNKData.reserve(256); for (int i = 0; i < 256; i++) header[i] = H2OHeader::Read(stream); - + for (int i = 0; i < 256; i++) { H2OHeader h = header[i]; diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index fbae56cd7a0..699b0a5014c 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -7,9 +7,9 @@ MPQArchive::MPQArchive(const char* filename) { int result = libmpq__archive_open(&mpq_a, filename, -1); printf("Opening %s\n", filename); - if (result) + if (result) { - switch (result) + switch (result) { case LIBMPQ_ERROR_OPEN : printf("Error opening archive '%s': Does file really exist?\n", filename); @@ -46,7 +46,7 @@ eof(false), buffer(0), pointer(0), size(0) mpq_archive* mpq_a = (*i)->mpq_a; uint32_t filenum; - if(libmpq__file_number(mpq_a, filename, &filenum)) + if(libmpq__file_number(mpq_a, filename, &filenum)) continue; libmpq__off_t transferred; libmpq__file_unpacked_size(mpq_a, filenum, &size); @@ -72,7 +72,7 @@ eof(false), buffer(0), pointer(0), size(0) size_t MPQFile::Read(void* dest, size_t bytes) { - if (eof) + if (eof) return 0; size_t rpos = pointer + bytes; @@ -102,7 +102,7 @@ void MPQFile::seekRelative(int offset) void MPQFile::close() { - if (buffer) + if (buffer) delete[] buffer; buffer = 0; eof = true; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 5ea6198e76d..608eef1547a 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -5,7 +5,7 @@ #include "ace/Synch.h" -char* MPQManager::Files[] = { +char* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", "expansion.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 634c70cedeb..0050dc5218a 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -10,7 +10,7 @@ class MPQManager public: MPQManager() {} ~MPQManager() {} - + void Initialize(); FILE* GetFile(std::string path); DBC* GetDBC(std::string name); diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h index 61dcabac9b0..e7d835ae0e3 100644 --- a/src/tools/mesh_extractor/MapChunk.h +++ b/src/tools/mesh_extractor/MapChunk.h @@ -10,7 +10,7 @@ class MapChunk { public: MapChunk(ADT* _adt, Chunk* chunk); - + void GenerateTriangles(); void GenerateVertices(FILE* stream); static bool HasHole(uint32 map, int x, int y); diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 3dde9ac36f5..423095b22ca 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -56,7 +56,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis return false; std::string maps = std::string(param); Tokens tokens(maps, ','); - + for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h index 834bf66bcfb..75b4e45700c 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.h +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -7,7 +7,7 @@ class ObjectDataHandler { public: ObjectDataHandler(ADT* _adt) : Source(_adt) {} - + void ProcessMapChunk(MapChunk* chunk); virtual void ProcessInternal(ChunkedData* data) = 0; ADT* Source; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index e3694541be8..0c775b9b8c9 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -15,7 +15,7 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome { // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize - Config.cs = Constants::TileSize / 1800; + Config.cs = Constants::TileSize / 1800; // Cell Height Config.ch = 0.3f; // Min Region Area = 6^2 @@ -72,7 +72,7 @@ uint8* TileBuilder::Build() // don't load main tile again if (tx == X && ty == Y) continue; - + ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); // If this condition is met, it means that this wdt does not contain the ADT if (!_adt->Data->Stream) @@ -104,7 +104,7 @@ uint8* TileBuilder::Build() rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - + printf("[%02i,%02i] Triangles rasterized!\n", X, Y); // Once all geometry is rasterized, we do initial pass of filtering to @@ -113,7 +113,7 @@ uint8* TileBuilder::Build() rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - + printf("[%02i,%02i] Filtering done!\n", X, Y); // Compact the heightfield so that it is faster to handle from now on. @@ -132,13 +132,13 @@ uint8* TileBuilder::Build() rcBuildDistanceField(Context, *chf); // Partition the walkable surface into simple regions without holes. rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); - + printf("[%02i,%02i] Regions built!\n", X, Y); // Create contours. rcContourSet* cset = rcAllocContourSet(); rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); - + // Build polygon navmesh from the contours. rcPolyMesh* pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); @@ -217,7 +217,7 @@ uint8* TileBuilder::Build() uint8* navData; printf("[%02i,%02i] Creating the navmesh!\n", X, Y); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - + // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 2f07bd20080..3db387bc81a 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -133,7 +133,7 @@ Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) std::string Utils::GetPathBase( std::string path ) { - int lastIndex = path.find_last_of("."); + int lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) return path.substr(0, lastIndex); return path; diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c247169df73..c9d2746b7d8 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -551,8 +551,8 @@ public: static G3D::Matrix4 GetTransformation(IDefinition def); /// They say its better to declare template functions in the header files. template - static std::string ToString(T val) - { + static std::string ToString(T val) + { std::stringstream ss; ss << val; return ss.str(); diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index c06d8ac9677..f0c3091c04e 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -17,7 +17,7 @@ void WDT::ReadGlobalModel() Chunk* defChunk = Data->GetChunkByName("MODF"); if (!fileChunk || !defChunk) return; - + IsGlobalModel = true; ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); ModelFile = Utils::ReadString(fileChunk->GetStream()); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index a0977c398c4..b98a7aae826 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -103,7 +103,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v break; instances.push_back(root->DoodadInstances[i]); } - + for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) { Model* model = Cache->ModelCache.Get(instance->File); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 69ffad94eb7..754bced903c 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -161,7 +161,7 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - + for (int i = 0; i < threads; ++i) _threads.push_back(new BuilderThread(this)); @@ -241,7 +241,7 @@ namespace MMAP minX = 32 - bmax[0] / GRID_SIZE; minY = 32 - bmax[2] / GRID_SIZE; } - + void MapBuilder::buildMeshFromFile(char* name) { FILE* file = fopen(name, "rb"); @@ -253,7 +253,7 @@ namespace MMAP fread(&mapId, sizeof(int), 1, file); fread(&tileX, sizeof(int), 1, file); fread(&tileY, sizeof(int), 1, file); - + dtNavMesh* navMesh = NULL; buildNavMesh(mapId, navMesh); if (!navMesh) @@ -270,7 +270,7 @@ namespace MMAP float* verts = new float[verticesCount]; int* inds = new int[indicesCount]; - + fread(verts, sizeof(float), verticesCount, file); fread(inds, sizeof(int), indicesCount, file); @@ -648,7 +648,7 @@ namespace MMAP tile.chf = NULL; rcFreeContourSet(tile.cset); tile.cset = NULL; - + if (tile.pmesh) { pmmerge[nmerge] = tile.pmesh; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 7ee4dc7f46c..0159219c110 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -779,7 +779,7 @@ namespace MMAP continue; std::pair val; val.first = t[i]; - + index = val.first; val.second = count; -- cgit v1.2.3 From fa57ecddac2409307375a01c4214080c3ca1d44a Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 30 Sep 2012 15:47:39 -0500 Subject: Tools/MeshExtractor: * Added the option to output debug information on ADTs. * Tweaked rcConfig options and fixed some mistakes about it. * Generate 64 tiles per ADT, this should give us a more accurate mesh on large maps. * Speedup compilation time by moving function bodies from Utils.h to Utils.cpp --- src/tools/mesh_extractor/ADT.cpp | 1 - src/tools/mesh_extractor/ContinentBuilder.cpp | 17 +- src/tools/mesh_extractor/ContinentBuilder.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 23 ++- src/tools/mesh_extractor/TileBuilder.cpp | 46 +++-- src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 250 ++++++++++++++++++++++++++ src/tools/mesh_extractor/Utils.h | 250 ++------------------------ 8 files changed, 319 insertions(+), 272 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index a6c080cf0b0..8d7dce9ae11 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -2,7 +2,6 @@ #include "DoodadHandler.h" #include "LiquidHandler.h" #include "WorldModelHandler.h" -#include "Cache.h" ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index cdfe0ca050a..984f6170357 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -7,13 +7,14 @@ #include "ace/Task.h" #include "Recast.h" -class BuilderThread : public ACE_Task +class BuilderThread : public ACE_Task_Base { private: int X, Y, MapId; std::string Continent; + bool debug; public: - BuilderThread() : Free(true) {} + BuilderThread(bool deb) : Free(true), debug(deb) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -22,23 +23,23 @@ public: printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, X, Y); + sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); fclose(f); Free = true; - return 1; + return 0; } - uint8* nav = builder.Build(); + uint8* nav = builder.Build(debug); if (nav) { f = fopen(buff, "wb"); if (!f) { printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return -1; + return 0; } MmapTileHeader header; header.size = builder.DataSize; @@ -73,7 +74,7 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa bmin[2] = bmax[2] - Constants::TileSize; } -void ContinentBuilder::Build() +void ContinentBuilder::Build(bool debug) { char buff[50]; sprintf(buff, "mmaps/%03u.mmap", MapId); @@ -107,7 +108,7 @@ void ContinentBuilder::Build() fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread()); + Threads.push_back(new BuilderThread(debug)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index d3da984595d..c923498fc5e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -8,7 +8,7 @@ class ContinentBuilder { public: ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} - void Build(); + void Build(bool debug); private: std::string Continent; WDT* TileMap; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 423095b22ca..9d88fcdcdfc 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -14,7 +14,7 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(std::set& mapIds, uint32 threads) +void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) @@ -31,11 +31,11 @@ void ExtractAllMaps(std::set& mapIds, uint32 threads) continue; printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt, threads); - builder.Build(); + builder.Build(debug); } } -bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList) +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput) { char* param = NULL; for (int i = 1; i < argc; ++i) @@ -62,6 +62,14 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis printf("Extracting only provided list of maps (%u).\n", mapList.size()); } + if (strcmp(argv[i], "--debug") == 0) + { + param = argv[++i]; + if (!param) + return false; + debugOutput = atoi(param); + printf("Output will contain debug information (.obj files)\n"); + } } return true; } @@ -71,6 +79,7 @@ void PrintUsage() printf("MeshExtractor help.\n"); printf("* Use \"--threads \" to specify threads, default to 4\n"); printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); + printf("* Use \"--debug 1\" to generate debug information of the tiles.\n"); } int main(int argc, char* argv[]) @@ -81,14 +90,14 @@ int main(int argc, char* argv[]) MPQHandler->Initialize(); uint32 threads = 4; std::set mapIds; + bool debug = false; - if (!HandleArgs(argc, argv, threads, mapIds)) + if (!HandleArgs(argc, argv, threads, mapIds, debug)) { PrintUsage(); return -1; } - ExtractAllMaps(mapIds, threads); + ExtractAllMaps(mapIds, threads, debug); return 0; -} - +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 0c775b9b8c9..54b9e4865cd 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -17,20 +17,22 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome // 1800 = TileVoxelSize Config.cs = Constants::TileSize / 1800; // Cell Height - Config.ch = 0.3f; - // Min Region Area = 6^2 - Config.minRegionArea = 36; - // Merge Region Area = 12^2 - Config.mergeRegionArea = 144; + Config.ch = 0.4f; + // Min Region Area = 20^2 + Config.minRegionArea = 20*20; + // Merge Region Area = 40^2 + Config.mergeRegionArea = 40*40; + Config.tileSize = Constants::TileSize / 4; Config.walkableSlopeAngle = 50.0f; Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 2.1f / Config.ch; - Config.walkableRadius = 0.6f / Config.cs; + Config.walkableHeight = 1.652778f / Config.ch; + Config.walkableRadius = 0.2951389f / Config.cs; Config.maxEdgeLen = Config.walkableRadius * 8; - Config.borderSize = Config.walkableRadius + 8; - Config.width = 1800; + Config.borderSize = Config.walkableRadius + 4; + Config.width = 1800 + Config.borderSize * 2; + Config.height = 1800 + Config.borderSize * 2; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; @@ -47,7 +49,7 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::Build() +uint8* TileBuilder::Build(bool dbg) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -65,9 +67,9 @@ uint8* TileBuilder::Build() _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); // again, we load everything - wasteful but who cares - for (int ty = Y - 1; ty <= Y + 1; ty++) + for (int ty = Y - 4; ty <= Y + 4; ty++) { - for (int tx = X - 1; tx <= X + 1; tx++) + for (int tx = X - 4; tx <= X + 4; tx++) { // don't load main tile again if (tx == X && ty == Y) @@ -85,6 +87,19 @@ uint8* TileBuilder::Build() delete _adt; } } + + if (dbg) + { + char buff[100]; + sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); + FILE* debug = fopen(buff, "wb"); + for (int i = 0; i < _Geometry->Vertices.size(); ++i) + fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z); + for (int i = 0; i < _Geometry->Triangles.size(); ++i) + fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); + fclose(debug); + } + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -100,8 +115,7 @@ uint8* TileBuilder::Build() bbMax[0] += Config.borderSize * Config.cs; rcHeightfield* hf = rcAllocHeightfield(); - int width = Config.width + (Config.borderSize * 2); - rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch); + rcCreateHeightfield(Context, *hf, Config.width, Config.height, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); @@ -208,14 +222,14 @@ uint8* TileBuilder::Build() params.walkableRadius = Config.walkableRadius; params.tileX = X; params.tileY = Y; - params.tileSize = Config.width; + params.tileSize = 1800; // Offmesh-connection settings params.offMeshConCount = 0; // none for now int navDataSize; uint8* navData; - printf("[%02i,%02i] Creating the navmesh!\n", X, Y); + printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); // Free some memory diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 2ec45811676..72e275c75b7 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -14,7 +14,7 @@ public: ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax); - uint8* Build(); + uint8* Build(bool dbg); std::string World; int X; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 3db387bc81a..6389e0aa66e 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -180,3 +180,253 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD return scale * rotation * quatRotation ** translation * rootTransformation; } + +void MapChunkHeader::Read(FILE* stream) +{ + fread(&Flags, sizeof(uint32), 1, stream); + fread(&IndexX, sizeof(uint32), 1, stream); + fread(&IndexY, sizeof(uint32), 1, stream); + fread(&Layers, sizeof(uint32), 1, stream); + fread(&DoodadRefs, sizeof(uint32), 1, stream); + fread(&OffsetMCVT, sizeof(uint32), 1, stream); + fread(&OffsetMCNR, sizeof(uint32), 1, stream); + fread(&OffsetMCLY, sizeof(uint32), 1, stream); + fread(&OffsetMCRF, sizeof(uint32), 1, stream); + fread(&OffsetMCAL, sizeof(uint32), 1, stream); + fread(&SizeMCAL, sizeof(uint32), 1, stream); + fread(&OffsetMCSH, sizeof(uint32), 1, stream); + fread(&SizeMCSH, sizeof(uint32), 1, stream); + fread(&AreaId, sizeof(uint32), 1, stream); + fread(&MapObjectRefs, sizeof(uint32), 1, stream); + fread(&Holes, sizeof(uint32), 1, stream); + LowQualityTextureMap = new uint32[4]; + fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + fread(&PredTex, sizeof(uint32), 1, stream); + fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + fread(&OffsetMCSE, sizeof(uint32), 1, stream); + fread(&SoundEmitters, sizeof(uint32), 1, stream); + fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + fread(&SizeMCLQ, sizeof(uint32), 1, stream); + Position = Vector3::Read(stream); + fread(&OffsetMCCV, sizeof(uint32), 1, stream); +} + +void MHDR::Read(FILE* stream) +{ + fread(&Flags, sizeof(uint32), 1, stream); + fread(&OffsetMCIN, sizeof(uint32), 1, stream); + fread(&OffsetMTEX, sizeof(uint32), 1, stream); + fread(&OffsetMMDX, sizeof(uint32), 1, stream); + fread(&OffsetMMID, sizeof(uint32), 1, stream); + fread(&OffsetMWMO, sizeof(uint32), 1, stream); + fread(&OffsetMWID, sizeof(uint32), 1, stream); + fread(&OffsetMDDF, sizeof(uint32), 1, stream); + fread(&OffsetMODF, sizeof(uint32), 1, stream); + fread(&OffsetMFBO, sizeof(uint32), 1, stream); + fread(&OffsetMH2O, sizeof(uint32), 1, stream); + fread(&OffsetMTFX, sizeof(uint32), 1, stream); +} + +void ModelHeader::Read(FILE* stream) +{ + fread(&Magic, sizeof(char), 4, stream); + Magic[4] = '\0'; // null-terminate it. + fread(&Version, sizeof(uint32), 1, stream); + fread(&LengthModelName, sizeof(uint32), 1, stream); + fread(&OffsetName, sizeof(uint32), 1, stream); + fread(&ModelFlags, sizeof(uint32), 1, stream); + fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + fread(&CountAnimations, sizeof(uint32), 1, stream); + fread(&OffsetAnimations, sizeof(uint32), 1, stream); + fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + fread(&CountBones, sizeof(uint32), 1, stream); + fread(&OffsetBones, sizeof(uint32), 1, stream); + fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + fread(&CountVertices, sizeof(uint32), 1, stream); + fread(&OffsetVertices, sizeof(uint32), 1, stream); + fread(&CountViews, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + fread(&CountRenderFlags, sizeof(uint32), 1, stream); + fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + fread(&CountBoneLookup, sizeof(uint32), 1, stream); + fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + fread(&CountTexLookup, sizeof(uint32), 1, stream); + fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + fread(&CountTexUnits, sizeof(uint32), 1, stream); + fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + fread(&CountTransLookup, sizeof(uint32), 1, stream); + fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + fread(&CountColors, sizeof(uint32), 1, stream); + fread(&OffsetColors, sizeof(uint32), 1, stream); + fread(&CountTextures, sizeof(uint32), 1, stream); + fread(&OffsetTextures, sizeof(uint32), 1, stream); + fread(&CountTransparency, sizeof(uint32), 1, stream); + fread(&OffsetTransparency, sizeof(uint32), 1, stream); + fread(&CountUvAnimation, sizeof(uint32), 1, stream); + fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + fread(&CountTexReplace, sizeof(uint32), 1, stream); + fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + VertexBox[0] = Vector3::Read(stream); + VertexBox[1] = Vector3::Read(stream); + fread(&VertexRadius, sizeof(float), 1, stream); + BoundingBox[0] = Vector3::Read(stream); + BoundingBox[1] = Vector3::Read(stream); + fread(&BoundingRadius, sizeof(float), 1, stream); + fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); +} + +WorldModelHeader WorldModelHeader::Read(FILE* stream) +{ + WorldModelHeader ret; + fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + fread(&ret.CountGroups, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountLights, sizeof(uint32), 1, stream); + fread(&ret.CountModels, sizeof(uint32), 1, stream); + fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + fread(&ret.CountSets, sizeof(uint32), 1, stream); + fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + return ret; +} + +DoodadInstance DoodadInstance::Read(FILE* stream) +{ + DoodadInstance ret; + fread(&ret.FileOffset, sizeof(uint32), 1, stream); + ret.Position = Vector3::Read(stream); + fread(&ret.QuatW, sizeof(float), 1, stream); + fread(&ret.QuatX, sizeof(float), 1, stream); + fread(&ret.QuatY, sizeof(float), 1, stream); + fread(&ret.QuatZ, sizeof(float), 1, stream); + fread(&ret.Scale, sizeof(float), 1, stream); + fread(&ret.LightColor, sizeof(uint32), 1, stream); + return ret; +} + +DoodadSet DoodadSet::Read(FILE* stream) +{ + DoodadSet ret; + char name[21]; + fread(&name, sizeof(char), 20, stream); + name[20] = '\0'; + ret.Name = name; + fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + fread(&ret.CountInstances, sizeof(uint32), 1, stream); + fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + return ret; +} + +LiquidHeader LiquidHeader::Read(FILE* stream) +{ + LiquidHeader ret; + fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + fread(&ret.Width, sizeof(uint32), 1, stream); + fread(&ret.Height, sizeof(uint32), 1, stream); + ret.BaseLocation = Vector3::Read(stream); + fread(&ret.MaterialId, sizeof(uint16), 1, stream); + return ret; +} + +LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) +{ + LiquidData ret; + ret.HeightMap = new float*[header.CountXVertices]; + for (uint32 i = 0; i < header.CountXVertices; ++i) + ret.HeightMap[i] = new float[header.CountYVertices]; + + ret.RenderFlags = new uint8*[header.Width]; + for (uint32 i = 0; i < header.Width; ++i) + ret.RenderFlags[i] = new uint8[header.Height]; + + for (uint32 y = 0; y < header.CountYVertices; y++) + { + for (uint32 x = 0; x < header.CountXVertices; x++) + { + uint32 discard; + fread(&discard, sizeof(uint32), 1, stream); + float tmp; + fread(&tmp, sizeof(float), 1, stream); + ret.HeightMap[x][y] = tmp; + } + } + + for (uint32 y = 0; y < header.Height; y++) + { + for (uint32 x = 0; x < header.Width; x++) + { + uint8 tmp; + fread(&tmp, sizeof(uint8), 1, stream); + ret.RenderFlags[x][y] = tmp; + } + } + + return ret; +} + +H2ORenderMask H2ORenderMask::Read(FILE* stream) +{ + H2ORenderMask ret; + fread(&ret.Mask, sizeof(uint8), 8, stream); + return ret; +} + +bool MCNKLiquidData::IsWater(int x, int y, float height) +{ + if (!Heights) + return false; + if (!Mask.ShouldRender(x, y)) + return false; + float diff = Heights[x][y] - height; + if (diff > Constants::MaxStandableHeight) + return true; + return false; +} + +H2OHeader H2OHeader::Read(FILE* stream) +{ + H2OHeader ret; + fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + fread(&ret.LayerCount, sizeof(uint32), 1, stream); + fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + return ret; +} + +H2OInformation H2OInformation::Read(FILE* stream) +{ + H2OInformation ret; + fread(&ret.LiquidType, sizeof(uint16), 1, stream); + fread(&ret.Flags, sizeof(uint16), 1, stream); + fread(&ret.HeightLevel1, sizeof(float), 1, stream); + fread(&ret.HeightLevel2, sizeof(float), 1, stream); + fread(&ret.OffsetX, sizeof(uint8), 1, stream); + fread(&ret.OffsetY, sizeof(uint8), 1, stream); + fread(&ret.Width, sizeof(uint8), 1, stream); + fread(&ret.Height, sizeof(uint8), 1, stream); + fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + return ret; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c9d2746b7d8..a45c3659240 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -77,35 +77,7 @@ public: Vector3 Position; uint32 OffsetMCCV; - void Read(FILE* stream) - { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&IndexX, sizeof(uint32), 1, stream); - fread(&IndexY, sizeof(uint32), 1, stream); - fread(&Layers, sizeof(uint32), 1, stream); - fread(&DoodadRefs, sizeof(uint32), 1, stream); - fread(&OffsetMCVT, sizeof(uint32), 1, stream); - fread(&OffsetMCNR, sizeof(uint32), 1, stream); - fread(&OffsetMCLY, sizeof(uint32), 1, stream); - fread(&OffsetMCRF, sizeof(uint32), 1, stream); - fread(&OffsetMCAL, sizeof(uint32), 1, stream); - fread(&SizeMCAL, sizeof(uint32), 1, stream); - fread(&OffsetMCSH, sizeof(uint32), 1, stream); - fread(&SizeMCSH, sizeof(uint32), 1, stream); - fread(&AreaId, sizeof(uint32), 1, stream); - fread(&MapObjectRefs, sizeof(uint32), 1, stream); - fread(&Holes, sizeof(uint32), 1, stream); - LowQualityTextureMap = new uint32[4]; - fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - fread(&PredTex, sizeof(uint32), 1, stream); - fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - fread(&OffsetMCSE, sizeof(uint32), 1, stream); - fread(&SoundEmitters, sizeof(uint32), 1, stream); - fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - fread(&SizeMCLQ, sizeof(uint32), 1, stream); - Position = Vector3::Read(stream); - fread(&OffsetMCCV, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class MHDR @@ -125,21 +97,7 @@ public: uint32 OffsetMH2O; uint32 OffsetMTFX; - void Read(FILE* stream) - { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&OffsetMCIN, sizeof(uint32), 1, stream); - fread(&OffsetMTEX, sizeof(uint32), 1, stream); - fread(&OffsetMMDX, sizeof(uint32), 1, stream); - fread(&OffsetMMID, sizeof(uint32), 1, stream); - fread(&OffsetMWMO, sizeof(uint32), 1, stream); - fread(&OffsetMWID, sizeof(uint32), 1, stream); - fread(&OffsetMDDF, sizeof(uint32), 1, stream); - fread(&OffsetMODF, sizeof(uint32), 1, stream); - fread(&OffsetMFBO, sizeof(uint32), 1, stream); - fread(&OffsetMH2O, sizeof(uint32), 1, stream); - fread(&OffsetMTFX, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class ModelHeader @@ -196,72 +154,7 @@ public: uint32 CountBoundingNormals; uint32 OffsetBoundingNormals; - void Read(FILE* stream) - { - fread(&Magic, sizeof(char), 4, stream); - Magic[4] = '\0'; // null-terminate it. - fread(&Version, sizeof(uint32), 1, stream); - fread(&LengthModelName, sizeof(uint32), 1, stream); - fread(&OffsetName, sizeof(uint32), 1, stream); - fread(&ModelFlags, sizeof(uint32), 1, stream); - fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - fread(&CountAnimations, sizeof(uint32), 1, stream); - fread(&OffsetAnimations, sizeof(uint32), 1, stream); - fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - fread(&CountBones, sizeof(uint32), 1, stream); - fread(&OffsetBones, sizeof(uint32), 1, stream); - fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&CountVertices, sizeof(uint32), 1, stream); - fread(&OffsetVertices, sizeof(uint32), 1, stream); - fread(&CountViews, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - fread(&CountRenderFlags, sizeof(uint32), 1, stream); - fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - fread(&CountBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - fread(&CountTexLookup, sizeof(uint32), 1, stream); - fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - fread(&CountTexUnits, sizeof(uint32), 1, stream); - fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - fread(&CountTransLookup, sizeof(uint32), 1, stream); - fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - VertexBox[0] = Vector3::Read(stream); - VertexBox[1] = Vector3::Read(stream); - fread(&VertexRadius, sizeof(float), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); - fread(&BoundingRadius, sizeof(float), 1, stream); - fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - } + void Read(FILE* stream); }; class WorldModelHeader @@ -280,23 +173,7 @@ public: Vector3 BoundingBox[2]; uint32 LiquidTypeRelated; - static WorldModelHeader Read(FILE* stream) - { - WorldModelHeader ret; - fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - fread(&ret.CountGroups, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountLights, sizeof(uint32), 1, stream); - fread(&ret.CountModels, sizeof(uint32), 1, stream); - fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - fread(&ret.CountSets, sizeof(uint32), 1, stream); - fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); - ret.BoundingBox[0] = Vector3::Read(stream); - ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - return ret; - } + static WorldModelHeader Read(FILE* stream); }; class DoodadInstance @@ -313,19 +190,7 @@ public: float Scale; uint32 LightColor; - static DoodadInstance Read(FILE* stream) - { - DoodadInstance ret; - fread(&ret.FileOffset, sizeof(uint32), 1, stream); - ret.Position = Vector3::Read(stream); - fread(&ret.QuatW, sizeof(float), 1, stream); - fread(&ret.QuatX, sizeof(float), 1, stream); - fread(&ret.QuatY, sizeof(float), 1, stream); - fread(&ret.QuatZ, sizeof(float), 1, stream); - fread(&ret.Scale, sizeof(float), 1, stream); - fread(&ret.LightColor, sizeof(uint32), 1, stream); - return ret; - } + static DoodadInstance Read(FILE* stream); }; class DoodadSet @@ -337,18 +202,7 @@ public: uint32 CountInstances; uint32 UnknownZero; - static DoodadSet Read(FILE* stream) - { - DoodadSet ret; - char name[21]; - fread(&name, sizeof(char), 20, stream); - name[20] = '\0'; - ret.Name = name; - fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - fread(&ret.CountInstances, sizeof(uint32), 1, stream); - fread(&ret.UnknownZero, sizeof(uint32), 1, stream); - return ret; - } + static DoodadSet Read(FILE* stream); }; class LiquidHeader @@ -362,17 +216,7 @@ public: Vector3 BaseLocation; uint16 MaterialId; - static LiquidHeader Read(FILE* stream) - { - LiquidHeader ret; - fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - fread(&ret.Width, sizeof(uint32), 1, stream); - fread(&ret.Height, sizeof(uint32), 1, stream); - ret.BaseLocation = Vector3::Read(stream); - fread(&ret.MaterialId, sizeof(uint16), 1, stream); - return ret; - } + static LiquidHeader Read(FILE* stream); }; class LiquidData @@ -387,41 +231,7 @@ public: return RenderFlags[x][y] != 0x0F; } - static LiquidData Read(FILE* stream, LiquidHeader header) - { - LiquidData ret; - ret.HeightMap = new float*[header.CountXVertices]; - for (uint32 i = 0; i < header.CountXVertices; ++i) - ret.HeightMap[i] = new float[header.CountYVertices]; - - ret.RenderFlags = new uint8*[header.Width]; - for (uint32 i = 0; i < header.Width; ++i) - ret.RenderFlags[i] = new uint8[header.Height]; - - for (uint32 y = 0; y < header.CountYVertices; y++) - { - for (uint32 x = 0; x < header.CountXVertices; x++) - { - uint32 discard; - fread(&discard, sizeof(uint32), 1, stream); - float tmp; - fread(&tmp, sizeof(float), 1, stream); - ret.HeightMap[x][y] = tmp; - } - } - - for (uint32 y = 0; y < header.Height; y++) - { - for (uint32 x = 0; x < header.Width; x++) - { - uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); - ret.RenderFlags[x][y] = tmp; - } - } - - return ret; - } + static LiquidData Read(FILE* stream, LiquidHeader& header); }; class H2ORenderMask @@ -435,12 +245,7 @@ public: return (Mask[y] >> x & 1) != 0; } - static H2ORenderMask Read(FILE* stream) - { - H2ORenderMask ret; - fread(&ret.Mask, sizeof(uint8), 8, stream); - return ret; - } + static H2ORenderMask Read(FILE* stream); }; class MCNKLiquidData @@ -452,17 +257,7 @@ public: float** Heights; H2ORenderMask Mask; - bool IsWater(int x, int y, float height) - { - if (!Heights) - return false; - if (!Mask.ShouldRender(x, y)) - return false; - float diff = Heights[x][y] - height; - if (diff > Constants::MaxStandableHeight) - return true; - return false; - } + bool IsWater(int x, int y, float height); }; class H2OHeader @@ -473,14 +268,7 @@ public: uint32 LayerCount; uint32 OffsetRender; - static H2OHeader Read(FILE* stream) - { - H2OHeader ret; - fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - fread(&ret.LayerCount, sizeof(uint32), 1, stream); - fread(&ret.OffsetRender, sizeof(uint32), 1, stream); - return ret; - } + static H2OHeader Read(FILE* stream); }; class H2OInformation @@ -498,21 +286,7 @@ public: uint32 OffsetMask2; uint32 OffsetHeightmap; - static H2OInformation Read(FILE* stream) - { - H2OInformation ret; - fread(&ret.LiquidType, sizeof(uint16), 1, stream); - fread(&ret.Flags, sizeof(uint16), 1, stream); - fread(&ret.HeightLevel1, sizeof(float), 1, stream); - fread(&ret.HeightLevel2, sizeof(float), 1, stream); - fread(&ret.OffsetX, sizeof(uint8), 1, stream); - fread(&ret.OffsetY, sizeof(uint8), 1, stream); - fread(&ret.Width, sizeof(uint8), 1, stream); - fread(&ret.Height, sizeof(uint8), 1, stream); - fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); - return ret; - } + static H2OInformation Read(FILE* stream); }; // Dummy class to act as an interface. -- cgit v1.2.3 From e32ddea96a017c7d5ad22eca16764d74501b90f3 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Oct 2012 18:02:18 -0500 Subject: Tools/MeshExtractor: * Added the capability of extracting DBCs. * Fixed most compile warnings * Some work on the navigation mesh generation process (still not ready) --- src/tools/mesh_extractor/ChunkedData.cpp | 4 +- src/tools/mesh_extractor/Constants.h | 11 +++ src/tools/mesh_extractor/ContinentBuilder.cpp | 16 +++-- src/tools/mesh_extractor/DoodadHandler.cpp | 2 +- src/tools/mesh_extractor/LiquidHandler.cpp | 8 +-- src/tools/mesh_extractor/MPQ.cpp | 1 + src/tools/mesh_extractor/MPQ.h | 2 + src/tools/mesh_extractor/MPQManager.cpp | 61 ++++++++++++++--- src/tools/mesh_extractor/MPQManager.h | 6 +- src/tools/mesh_extractor/MeshExtractor.cpp | 93 ++++++++++++++++++++++---- src/tools/mesh_extractor/TileBuilder.cpp | 75 ++++++++++++--------- src/tools/mesh_extractor/TileBuilder.h | 4 +- src/tools/mesh_extractor/Utils.cpp | 38 +++++++++++ src/tools/mesh_extractor/Utils.h | 2 + src/tools/mesh_extractor/WorldModelGroup.cpp | 8 +-- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mesh_extractor/WorldModelRoot.cpp | 6 +- 17 files changed, 264 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4431993e3d1..4d609d8f6b2 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -48,7 +48,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) int ChunkedData::GetFirstIndex( std::string name ) { - for (int i = 0; i < Chunks.size(); ++i) + for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) return i; return -1; @@ -56,7 +56,7 @@ int ChunkedData::GetFirstIndex( std::string name ) Chunk* ChunkedData::GetChunkByName( std::string name ) { - for (int i = 0; i < Chunks.size(); ++i) + for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) return Chunks[i]; return NULL; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index f44d5f16797..f3b71812155 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -29,6 +29,17 @@ public: POLY_FLAG_SWIM = 2, POLY_FLAG_FLIGHTMASTER = 4 }; + + enum ExtractFlags + { + EXTRACT_FLAG_DBC = 1, + EXTRACT_FLAG_MAPS = 2, + EXTRACT_FLAG_VMAPS = 4, + EXTRACT_FLAG_GOB_MODELS = 8, + EXTRACT_FLAG_MMAPS = 16, + EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS + }; + static const float TileSize; static const float MaxXY; static const float ChunkSize; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 984f6170357..e4a1d2ca9f4 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -13,8 +13,9 @@ private: int X, Y, MapId; std::string Continent; bool debug; + dtNavMeshParams Params; public: - BuilderThread(bool deb) : Free(true), debug(deb) {} + BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -32,7 +33,7 @@ public: Free = true; return 0; } - uint8* nav = builder.Build(debug); + uint8* nav = builder.Build(debug, Params); if (nav) { f = fopen(buff, "wb"); @@ -101,14 +102,17 @@ void ContinentBuilder::Build(bool debug) dtNavMeshParams params; params.maxPolys = 32768; params.maxTiles = TileMap->TileTable.size(); - rcVcopy(params.orig, bmin); - params.tileHeight = 533.33333f; - params.tileWidth = 533.33333f; + // rcVcopy(params.orig, bmin); + params.orig[0] = Constants::Origin[0]; + params.orig[1] = 0; + params.orig[2] = Constants::Origin[2]; + params.tileHeight = Constants::TileSize; + params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(debug)); + Threads.push_back(new BuilderThread(debug, params)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 363f07b4578..4e8028b3dff 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -31,7 +31,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) { int32 index; fread(&index, sizeof(int32), 1, stream); - if (index < 0 || index >= _definitions->size()) + if (index < 0 || uint32(index) >= _definitions->size()) continue; DoodadDefinition doodad = (*_definitions)[index]; if (_drawn.find(doodad.UniqueId) != _drawn.end()) diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 5b998d75db9..7844130ab34 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -34,10 +34,10 @@ void LiquidHandler::HandleNewLiquid() H2OInformation information = H2OInformation::Read(stream); float** heights = new float*[9]; - for (int i = 0; i < 9; ++i) + for (int j = 0; j < 9; ++i) { - heights[i] = new float[9]; - memset(heights[i], 0, sizeof(float) * 9); + heights[j] = new float[9]; + memset(heights[j], 0, sizeof(float) * 9); } H2ORenderMask renderMask; @@ -52,7 +52,7 @@ void LiquidHandler::HandleNewLiquid() uint8* altMask = new uint8[size]; fread(altMask, sizeof(uint8), size, stream); - for (int mi = 0; mi < size; mi++) + for (uint32 mi = 0; mi < size; mi++) renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; delete[] altMask; } diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index 699b0a5014c..b7be181594d 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -31,6 +31,7 @@ MPQArchive::MPQArchive(const char* filename) break; } } + GetFileListTo(Files); } void MPQArchive::close() diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index dd566bccff5..15fce452726 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -16,6 +16,8 @@ class MPQArchive public: mpq_archive_s *mpq_a; + + vector Files; MPQArchive(const char* filename); void close(); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 608eef1547a..90491dfb945 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -15,7 +15,7 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; -char* MPQManager::Languages[] = { "esES", "enUS", "enGB", "esMX", "deDE" }; +char* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; void MPQManager::Initialize() { @@ -31,21 +31,38 @@ void MPQManager::Initialize() void MPQManager::InitializeDBC() { - CurLocale = 0; + BaseLocale = -1; std::string fileName; uint32 size = sizeof(Languages) / sizeof(char*); + MPQArchive* _baseLocale = NULL; for (uint32 i = 0; i < size; ++i) { - fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; - FILE* file = fopen(fileName.c_str(), "rb"); + std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; + FILE* file = fopen(_fileName.c_str(), "rb"); if (file) { - CurLocale = i; - break; + if (BaseLocale == -1) + { + BaseLocale = i; + _baseLocale = new MPQArchive(_fileName.c_str()); + fileName = _fileName; + LocaleFiles[i] = _baseLocale; + } + else + LocaleFiles[i] = new MPQArchive(_fileName.c_str()); + + AvailableLocales.insert(i); + printf("Detected locale: %s\n", Languages[i]); } } - Archives.push_front(new MPQArchive(fileName.c_str())); - printf("Using locale: %s\n", Languages[CurLocale]); + Archives.push_front(_baseLocale); + if (BaseLocale == -1) + { + printf("No locale data detected\n"); + ASSERT(false); + } + else + printf("Using default locale: %s\n", Languages[BaseLocale]); } FILE* MPQManager::GetFile( std::string path ) @@ -62,3 +79,31 @@ DBC* MPQManager::GetDBC( std::string name ) std::string path = "DBFilesClient\\" + name + ".dbc"; return new DBC(GetFile(path)); } + +FILE* MPQManager::GetFileFrom( std::string path, MPQArchive* file ) +{ + ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); + mpq_archive* mpq_a = file->mpq_a; + + uint32_t filenum; + if(libmpq__file_number(mpq_a, path.c_str(), &filenum)) + return NULL; + + libmpq__off_t transferred; + libmpq__off_t size = 0; + libmpq__file_unpacked_size(mpq_a, filenum, &size); + + // HACK: in patch.mpq some files don't want to open and give 1 for filesize + if (size <= 1) + return NULL; + + uint8* buffer = new uint8[size]; + + //libmpq_file_getdata + libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); + + // Pack the return into a FILE stream + FILE* ret = tmpfile(); + fwrite(buffer, sizeof(uint8), size, ret); + return ret; +} diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 0050dc5218a..c23d7177825 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -13,10 +13,14 @@ public: void Initialize(); FILE* GetFile(std::string path); + FILE* GetFileFrom(std::string path, MPQArchive* file); DBC* GetDBC(std::string name); + std::vector GetAllFiles(std::string extension); std::deque Archives; - uint32 CurLocale; + int32 BaseLocale; + std::set AvailableLocales; + std::map LocaleFiles; static char* Files[]; static char* Languages[]; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 9d88fcdcdfc..d6b701607ba 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -3,6 +3,7 @@ #include "ContinentBuilder.h" #include "Cache.h" #include "DBC.h" +#include "Constants.h" #include @@ -14,7 +15,7 @@ LoginDatabaseWorkerPool LoginDatabase; MPQManager* MPQHandler; CacheClass* Cache; -void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) +void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) { DBC* dbc = MPQHandler->GetDBC("Map"); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) @@ -35,9 +36,45 @@ void ExtractAllMaps(std::set& mapIds, uint32 threads, bool debug) } } -bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput) +void ExtractDBCs() +{ + printf("Extracting DBCs\n"); + // Create the filesystem structure + std::string baseDBCPath = "dbc/"; + Utils::CreateDir(baseDBCPath); + + // Populate list of DBC files + std::set DBCFiles; + for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) + if (itr->rfind(".dbc") == itr->length() - strlen(".dbc")) + DBCFiles.insert(*itr); + + // Iterate over all available locales + for (std::set::iterator itr = MPQHandler->AvailableLocales.begin(); itr != MPQHandler->AvailableLocales.end(); ++itr) + { + printf("Extracting DBCs for locale %s\n", MPQManager::Languages[*itr]); + std::string path = baseDBCPath; + if (*itr != MPQHandler->BaseLocale) + { + path += std::string(MPQManager::Languages[*itr]) + "/"; + Utils::CreateDir(path); + } + + std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; + // Extract the component file + Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); + // Extract the DBC files for the given locale + for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) + Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + strlen("DBFilesClient\\"))); + } + printf("DBC extraction finished!\n"); +} + +bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput, uint32& extractFlags) { char* param = NULL; + extractFlags = 0; + for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--threads") == 0) @@ -49,7 +86,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis threads = atoi(param); printf("Using %i threads\n", threads); } - if (strcmp(argv[i], "--maps") == 0) + else if (strcmp(argv[i], "--maps") == 0) { param = argv[++i]; if (!param) @@ -62,13 +99,32 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis printf("Extracting only provided list of maps (%u).\n", mapList.size()); } - if (strcmp(argv[i], "--debug") == 0) + else if (strcmp(argv[i], "--debug") == 0) { param = argv[++i]; if (!param) return false; debugOutput = atoi(param); - printf("Output will contain debug information (.obj files)\n"); + if (debugOutput) + printf("Output will contain debug information (.obj files)\n"); + } + else if (strcmp(argv[i], "--extract") == 0) + { + param = argv[++i]; + if (!param) + return false; + + extractFlags = atoi(param); + + if (!(extractFlags & Constants::EXTRACT_FLAG_ALLOWED)) // Tried to use an invalid flag + return false; + + printf("Detected flags: \n"); + printf("* Extract DBCs: %s\n", (extractFlags & Constants::EXTRACT_FLAG_DBC) ? "Yes" : "No"); + printf("* Extract Maps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MAPS) ? "Yes" : "No"); + printf("* Extract VMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_VMAPS) ? "Yes" : "No"); + printf("* Extract GameObject Models: %s\n", (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ? "Yes" : "No"); + printf("* Extract MMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ? "Yes" : "No"); } } return true; @@ -77,9 +133,17 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis void PrintUsage() { printf("MeshExtractor help.\n"); - printf("* Use \"--threads \" to specify threads, default to 4\n"); - printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n"); - printf("* Use \"--debug 1\" to generate debug information of the tiles.\n"); + printf("* Use \"--threads \" to specify threads, default to 4 (Only available when extracting MMaps)\n"); + printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified (Do not use spaces)\n"); + printf("* Use \"--debug 1\" to generate debug information of the tiles (Only available when extracting MMaps)\n"); + printf("* Use \"--extract X\" to extract the data specified by the flag X (Note: You can combine the flags with the bitwise OR operator |). Available flags are: \n"); + { + printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); + printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); + printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); + printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); + } } int main(int argc, char* argv[]) @@ -88,16 +152,21 @@ int main(int argc, char* argv[]) Cache = new CacheClass(); MPQHandler = new MPQManager(); MPQHandler->Initialize(); - uint32 threads = 4; + uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; - - if (!HandleArgs(argc, argv, threads, mapIds, debug)) + + if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags)) { PrintUsage(); return -1; } - ExtractAllMaps(mapIds, threads, debug); + if (extractFlags & Constants::EXTRACT_FLAG_DBC) + ExtractDBCs(); + + if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) + ExtractMMaps(mapIds, threads, debug); + return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 54b9e4865cd..5b3e181713e 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -26,9 +26,9 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Config.walkableSlopeAngle = 50.0f; Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; - Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 1.652778f / Config.ch; - Config.walkableRadius = 0.2951389f / Config.cs; + Config.walkableClimb = floorf(1.0f / Config.ch); + Config.walkableHeight = ceilf(1.652778f / Config.ch); + Config.walkableRadius = ceilf(0.2951389f / Config.cs); Config.maxEdgeLen = Config.walkableRadius * 8; Config.borderSize = Config.walkableRadius + 4; Config.width = 1800 + Config.borderSize * 2; @@ -39,17 +39,17 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Context = new rcContext; } -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax ) +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams ) { bmin = new float[3]; bmax = new float[3]; - bmin[0] = Constants::Origin[0] + (Constants::TileSize * X); - bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y); - bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1)); - bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1)); + bmin[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * X); + bmin[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * Y); + bmax[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * (X + 1)); + bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::Build(bool dbg) +uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -61,15 +61,10 @@ uint8* TileBuilder::Build(bool dbg) if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; - float* bbMin; - float* bbMax; - CalculateTileBounds(bbMin, bbMax); - _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); - // again, we load everything - wasteful but who cares - for (int ty = Y - 4; ty <= Y + 4; ty++) + for (int ty = Y - 2; ty <= Y + 2; ty++) { - for (int tx = X - 4; tx <= X + 4; tx++) + for (int tx = X - 2; tx <= X + 2; tx++) { // don't load main tile again if (tx == X && ty == Y) @@ -109,13 +104,23 @@ uint8* TileBuilder::Build(bool dbg) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - bbMin[0] -= Config.borderSize * Config.cs; + float bbMin[3]; + float bbMax[3]; + // CalculateTileBounds(bbMin, bbMax, navMeshParams); + rcCalcBounds(vertices, numVerts, bbMin, bbMax); + // _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); + + /*bbMin[0] -= Config.borderSize * Config.cs; bbMin[2] -= Config.borderSize * Config.cs; bbMax[0] += Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs; + bbMax[0] += Config.borderSize * Config.cs;*/ + rcHeightfield* hf = rcAllocHeightfield(); - rcCreateHeightfield(Context, *hf, Config.width, Config.height, bbMin, bbMax, Config.cs, Config.ch); + int height, width; + rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height); + printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width); + rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch); rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); @@ -168,29 +173,31 @@ uint8* TileBuilder::Build(bool dbg) rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); + /* + * Removed with RecastNavigation v292 // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { unsigned short* v = &pmesh->verts[i * 3]; v[0] -= (unsigned short)Config.borderSize; v[2] -= (unsigned short)Config.borderSize; - } + }*/ // Set flags according to area types (e.g. Swim for Water) for (int i = 0; i < pmesh->npolys; i++) { if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) pmesh->flags[i] = Constants::POLY_FLAG_WALK; - else if (pmesh->areas[i] == (int)Constants::POLY_AREA_WATER) + else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } // get original bounds - float* tilebMin; + /*float* tilebMin; float* tilebMax; - CalculateTileBounds(tilebMin, tilebMax); + CalculateTileBounds(tilebMin, tilebMax, navMeshParams); tilebMin[1] = bbMin[1]; - tilebMax[1] = bbMax[1]; + tilebMax[1] = bbMax[1];*/ dtNavMeshCreateParams params; // PolyMesh data @@ -208,12 +215,14 @@ uint8* TileBuilder::Build(bool dbg) params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; // Copy bounding box - params.bmin[0] = tilebMin[0]; + /*params.bmin[0] = tilebMin[0]; params.bmin[1] = tilebMin[1]; params.bmin[2] = tilebMin[2]; params.bmax[0] = tilebMax[0]; params.bmax[1] = tilebMax[1]; - params.bmax[2] = tilebMax[2]; + params.bmax[2] = tilebMax[2];*/ + rcVcopy(params.bmin, pmesh->bmin); + rcVcopy(params.bmax, pmesh->bmax); // General settings params.ch = Config.ch; params.cs = Config.cs; @@ -222,7 +231,11 @@ uint8* TileBuilder::Build(bool dbg) params.walkableRadius = Config.walkableRadius; params.tileX = X; params.tileY = Y; - params.tileSize = 1800; + int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize; + int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize; + printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]); + params.buildBvTree = true; + params.tileLayer = 0; // Offmesh-connection settings params.offMeshConCount = 0; // none for now @@ -235,13 +248,13 @@ uint8* TileBuilder::Build(bool dbg) // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - delete tilebMax; - delete tilebMin; + //delete tilebMax; + //delete tilebMin; delete areas; delete triangles; delete vertices; - delete bbMax; - delete bbMin; + //delete bbMax; + //delete bbMin; if (result) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 72e275c75b7..17d6e48095a 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -13,8 +13,8 @@ public: TileBuilder(std::string world, int x, int y, uint32 mapId); ~TileBuilder(); - void CalculateTileBounds(float*& bmin, float*& bmax); - uint8* Build(bool dbg); + void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); + uint8* Build(bool dbg, dtNavMeshParams& navMeshParams); std::string World; int X; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 6389e0aa66e..5b752885d17 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -5,6 +5,13 @@ #include "G3D/Matrix4.h" #include "G3D/Quat.h" +#ifdef _WIN32 + #include "direct.h" +#else + #include + #include +#endif + const float Constants::TileSize = 533.0f + (1/3.0f); const float Constants::MaxXY = 32.0f * Constants::TileSize; const float Constants::ChunkSize = Constants::TileSize / 16.0f; @@ -13,6 +20,15 @@ const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY } const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; +void Utils::CreateDir( const std::string& Path ) +{ +#ifdef _WIN32 + _mkdir( Path.c_str()); +#else + mkdir( Path.c_str(), 0777 ); +#endif +} + void Utils::Reverse(char word[]) { int len = strlen(word); @@ -181,6 +197,28 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD return scale * rotation * quatRotation ** translation * rootTransformation; } +void Utils::SaveToDisk( FILE* stream, std::string path ) +{ + FILE* disk = fopen(path.c_str(), "wb"); + if (!disk) + { + printf("Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); + return; + } + + uint32 size = Utils::Size(stream); + uint8* data = new uint8[size]; + // Read the data to an array + fread(data, 1, size, stream); + // And write it in the file + fwrite(data, 1, size, disk); + + // Close the filestream + fclose(disk); + // Free the used memory + delete data; +} + void MapChunkHeader::Read(FILE* stream) { fread(&Flags, sizeof(uint32), 1, stream); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index a45c3659240..c19bc1bb29c 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -349,5 +349,7 @@ public: } static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); + static void CreateDir( const std::string& Path ); + static void SaveToDisk(FILE* stream, std::string path); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index b4c963020c7..bd0d106dabb 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -36,7 +36,7 @@ void WorldModelGroup::ReadNormals() ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < normalCount; i++) + for (uint32 i = 0; i < normalCount; i++) Normals[i] = Vector3::Read(stream); } @@ -61,7 +61,7 @@ void WorldModelGroup::ReadVertices() uint32 verticeCount = chunk->Length / 12; Vertices.reserve(verticeCount); FILE* stream = chunk->GetStream(); - for (int i = 0; i < verticeCount; i++) + for (uint32 i = 0; i < verticeCount; i++) Vertices.push_back(Vector3::Read(stream)); } @@ -75,7 +75,7 @@ void WorldModelGroup::ReadTriangles() ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); FILE* stream = chunk->GetStream(); Triangles.reserve(triangleCount); - for (int i = 0; i < triangleCount; i++) + for (uint32 i = 0; i < triangleCount; i++) { uint16 v0; uint16 v1; @@ -97,7 +97,7 @@ void WorldModelGroup::ReadMaterials() uint32 triangleCount = chunk->Length / 2; TriangleFlags.reserve(triangleCount); TriangleMaterials.reserve(triangleCount); - for (int i = 0; i < triangleCount; i++) + for (uint32 i = 0; i < triangleCount; i++) { uint8 tmp; fread(&tmp, sizeof(uint8), 1, stream); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index b98a7aae826..7b60b9b2151 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -46,7 +46,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) int32 index; fread(&index, sizeof(int32), 1, stream); - if (index < 0 || index >= _definitions->size()) + if (index < 0 || uint32(index) >= _definitions->size()) continue; WorldModelDefinition wmo = (*_definitions)[index]; diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 3457a35f761..c34a77e4531 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -16,7 +16,7 @@ void WorldModelRoot::ReadGroups() { std::string pathBase = Utils::GetPathBase(Path); Groups.reserve(Header.CountGroups); - for (int i = 0; i < Header.CountGroups; i++) + for (uint32 i = 0; i < Header.CountGroups; i++) { char name[200]; sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); @@ -35,7 +35,7 @@ void WorldModelRoot::ReadDoodadSets() FILE* stream = chunk->GetStream(); ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); DoodadSets.reserve(Header.CountSets); - for (int i = 0; i < Header.CountSets; i++) + for (uint32 i = 0; i < Header.CountSets; i++) DoodadSets.push_back(DoodadSet::Read(stream)); } @@ -49,7 +49,7 @@ void WorldModelRoot::ReadDoodadInstances() const uint32 instanceSize = 40; uint32 countInstances = chunk->Length / instanceSize; DoodadInstances.reserve(countInstances); - for (int i = 0; i < countInstances; i++) + for (uint32 i = 0; i < countInstances; i++) { FILE* stream = chunk->GetStream(); fseek(stream, instanceSize * i, SEEK_CUR); -- cgit v1.2.3 From d2437407f4f7ad1af3baeb351626b41bd700065c Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Oct 2012 21:09:05 -0500 Subject: Tools/MeshExtractor: * Fixed a bunch of errors * Allow to extract m2 and mdx models, WMOs are still not being extracted. --- src/tools/mesh_extractor/Chunk.cpp | 2 +- src/tools/mesh_extractor/Constants.h | 2 + src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mesh_extractor/DBC.h | 5 +- src/tools/mesh_extractor/MeshExtractor.cpp | 123 ++++++++++++++++++++++++- src/tools/mesh_extractor/Model.cpp | 29 ++++-- src/tools/mesh_extractor/Model.h | 2 + src/tools/mesh_extractor/ObjectDataHandler.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 4 +- src/tools/mesh_extractor/Utils.cpp | 36 ++++++-- src/tools/mesh_extractor/Utils.h | 3 + src/tools/mesh_extractor/WorldModelGroup.cpp | 2 +- 12 files changed, 183 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index b41fa7d07d4..2f521f1badd 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -10,7 +10,7 @@ int32 Chunk::FindSubChunkOffset(std::string name) FILE* stream = GetStream(); uint32 matched = 0; - while (ftell(stream) < Utils::Size(stream)) + while (uint32(ftell(stream)) < Utils::Size(stream)) { char b; fread(&b, sizeof(char), 1, stream); diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index f3b71812155..89cd6da20a2 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -47,6 +47,8 @@ public: static const float Origin[]; static const float PI; static const float MaxStandableHeight; + static bool ToWoWCoords; + static const char* VMAPMagic; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index be04ce070ee..c50e02014da 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -38,7 +38,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) std::string DBC::GetStringByOffset( int offset ) { int len = 0; - for (int i = offset; i < StringBlockSize; i++) + for (uint32 i = offset; i < StringBlockSize; i++) { if (!StringBlock[i]) { diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 6c86c1391dd..0c857bd40ed 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -37,9 +37,10 @@ public: return Values[index]; } - float GetFloat(int index) + template + T GetValue(int index) { - return *(float*)(&Values[index]); + return *(T*)(&Values[index]); } std::string GetString(int index) diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index d6b701607ba..8eb6ba5cb6e 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -4,6 +4,7 @@ #include "Cache.h" #include "DBC.h" #include "Constants.h" +#include "Model.h" #include @@ -70,6 +71,116 @@ void ExtractDBCs() printf("DBC extraction finished!\n"); } +void ExtractGameobjectModels() +{ + Constants::ToWoWCoords = true; + printf("Extracting GameObject models\n"); + + std::string baseBuildingsPath = "Buildings/"; + std::string baseVmapsPath = "vmaps/"; + Utils::CreateDir(baseVmapsPath); + Utils::CreateDir(baseBuildingsPath); + + FILE* modelList = fopen((baseVmapsPath + "GameObjectModels.list").c_str(), "wb"); + if (!modelList) + { + printf("Could not create file vmaps/GameObjectModels.list, please make sure that you have the write permissions in the folder\n"); + return; + } + + DBC* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); + for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + { + std::string path = (*itr)->GetString(1); + std::string fileName = Utils::GetPlainName(path.c_str()); + std::string extension = Utils::GetExtension(fileName); + // Convert the extension to lowercase + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + if (extension == "mdx" || extension == "m2") + { + fileName = Utils::FixModelPath(fileName); + Model model(path); + + if (model.IsBad) + continue; + + FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); + if (!output) + { + printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); + continue; + } + // Placeholder for 0 values + int Nop[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + fwrite(Constants::VMAPMagic, 8, 1, output); + uint32 numVerts = model.Header.CountBoundingVertices; + fwrite(&numVerts, sizeof(uint32), 1, output); + uint32 numGroups = 1; + fwrite(&numGroups, sizeof(uint32), 1, output); + fwrite(Nop, 4 * 3 , 1, output); // rootwmoid, flags, groupid + fwrite(Nop, sizeof(float), 3 * 2, output);//bbox, only needed for WMO currently + fwrite(Nop, 4, 1, output);// liquidflags + fwrite("GRP ", 4, 1, output); + + uint32 branches = 1; + uint32 wsize = sizeof(branches) + sizeof(uint32) * branches; + fwrite(&wsize, sizeof(uint32), 1, output); + fwrite(&branches, sizeof(branches), 1, output); + uint32 numTris = model.Header.CountBoundingTriangles; + fwrite(&numTris, sizeof(uint32), 1, output); + fwrite("INDX", 4, 1, output); + wsize = sizeof(uint32) + sizeof(unsigned short) * numTris; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numTris, sizeof(uint32), 1, output); + uint16* indices = new uint16[numTris]; + + if (numTris > 0) + { + uint32 i = 0; + for (std::vector >::iterator itr2 = model.Triangles.begin(); itr2 != model.Triangles.end(); ++itr2, ++i) + { + indices[i * 3 + 0] = itr2->V0; + indices[i * 3 + 1] = itr2->V1; + indices[i * 3 + 2] = itr2->V2; + } + fwrite(indices, sizeof(uint16), numTris, output); + } + + + fwrite("VERT", 4, 1, output); + wsize = sizeof(int) + sizeof(float) * 3 * numVerts; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numVerts, sizeof(int), 1, output); + float* vertices = new float[numVerts*3]; + + if (numVerts > 0) + { + uint32 i = 0; + for (std::vector::iterator itr2 = model.Vertices.begin(); itr2 != model.Vertices.end(); ++itr2, ++i) + { + vertices[i * 3 + 0] = itr2->x; + vertices[i * 3 + 1] = itr2->y; + vertices[i * 3 + 2] = itr2->z; + } + + fwrite(vertices, sizeof(float), numVerts * 3, output); + } + + fclose(output); + delete[] indices; + delete[] vertices; + } + else if (extension == "wmo") + { + //WorldModelRoot model(path); + } + } + + printf("GameObject models extraction finished!"); + Constants::ToWoWCoords = false; +} + bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput, uint32& extractFlags) { char* param = NULL; @@ -141,7 +252,7 @@ void PrintUsage() printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } @@ -149,9 +260,6 @@ void PrintUsage() int main(int argc, char* argv[]) { system("pause"); - Cache = new CacheClass(); - MPQHandler = new MPQManager(); - MPQHandler->Initialize(); uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; @@ -162,11 +270,18 @@ int main(int argc, char* argv[]) return -1; } + Cache = new CacheClass(); + MPQHandler = new MPQManager(); + MPQHandler->Initialize(); + if (extractFlags & Constants::EXTRACT_FLAG_DBC) ExtractDBCs(); if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ExtractMMaps(mapIds, threads, debug); + + if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) + ExtractGameobjectModels(); return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index a1c67d23f28..10fde0ebc2d 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -2,9 +2,14 @@ #include "MPQManager.h" #include "Utils.h" -Model::Model( std::string path ) +Model::Model( std::string path ) : IsCollidable(false), IsBad(false) { Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + if (!Stream) + { + IsBad = true; + return; + } Header.Read(Stream); if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) @@ -16,26 +21,36 @@ Model::Model( std::string path ) } } +Model::~Model() +{ + if (Stream) + fclose(Stream); +} + void Model::ReadVertices( FILE* stream ) { fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); Vertices.reserve(Header.CountBoundingVertices); - for (int i = 0; i < Header.CountBoundingVertices; ++i) - Vertices[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) + { + Vertices.push_back(Vector3::Read(stream)); + if (Constants::ToWoWCoords) + Vertices[i] = Utils::ToWoWCoords(Vertices[i]); + } } void Model::ReadBoundingTriangles( FILE* stream ) { fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); Triangles.reserve(Header.CountBoundingTriangles / 3); - for (int i = 0; i < Header.CountBoundingTriangles / 3; i++) + for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; fread(&tri.V0, sizeof(uint16), 1, stream); fread(&tri.V1, sizeof(uint16), 1, stream); fread(&tri.V2, sizeof(uint16), 1, stream); - Triangles[i] = tri; + Triangles.push_back(tri); } } @@ -43,7 +58,7 @@ void Model::ReadBoundingNormals( FILE* stream ) { fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); Normals.reserve(Header.CountBoundingNormals); - for (int i = 0; i < Header.CountBoundingNormals; i++) - Normals[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingNormals; i++) + Normals.push_back(Vector3::Read(stream)); } diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h index a5b8338461d..ea9331e7c30 100644 --- a/src/tools/mesh_extractor/Model.h +++ b/src/tools/mesh_extractor/Model.h @@ -7,6 +7,7 @@ class Model { public: Model(std::string path); + ~Model(); void ReadVertices(FILE* stream); void ReadBoundingTriangles(FILE* stream); @@ -17,5 +18,6 @@ public: std::vector > Triangles; bool IsCollidable; FILE* Stream; + bool IsBad; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp index 3ed2ee49604..789efc6d62c 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -11,7 +11,7 @@ void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); if (firstIndex == -1) return; - if (firstIndex + chunk->Index > Source->ObjectData->Chunks.size()) + if (uint32(firstIndex + chunk->Index) > Source->ObjectData->Chunks.size()) return; Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; if (ourChunk->Length == 0) diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5b3e181713e..12213b16373 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -88,9 +88,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) char buff[100]; sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); FILE* debug = fopen(buff, "wb"); - for (int i = 0; i < _Geometry->Vertices.size(); ++i) + for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z); - for (int i = 0; i < _Geometry->Triangles.size(); ++i) + for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); fclose(debug); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 5b752885d17..5fccd319554 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -19,6 +19,8 @@ const float Constants::UnitSize = Constants::ChunkSize / 8.0f; const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; +const char* Constants::VMAPMagic = "VMAP042"; +bool Constants::ToWoWCoords = false; void Utils::CreateDir( const std::string& Path ) { @@ -219,6 +221,21 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) delete data; } +Vector3 Utils::ToWoWCoords( Vector3 vec ) +{ + return Vector3(vec.x, -vec.z, vec.y); +} + +std::string Utils::GetExtension( std::string path ) +{ + std::string::size_type idx = path.rfind('.'); + std::string extension = ""; + + if(idx != std::string::npos) + extension = path.substr(idx+1); + return extension; +} + void MapChunkHeader::Read(FILE* stream) { fread(&Flags, sizeof(uint32), 1, stream); @@ -308,16 +325,6 @@ void ModelHeader::Read(FILE* stream) fread(&OffsetTransLookup, sizeof(uint32), 1, stream); fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); fread(&VertexRadius, sizeof(float), 1, stream); @@ -468,3 +475,12 @@ H2OInformation H2OInformation::Read(FILE* stream) fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); return ret; } + +char* Utils::GetPlainName(const char* FileName) +{ + char* temp; + + if((temp = (char*)strrchr(FileName, '\\')) != NULL) + FileName = temp + 1; + return (char*)FileName; +} \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c19bc1bb29c..47a6354d3b2 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -351,5 +351,8 @@ public: static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); static void CreateDir( const std::string& Path ); static void SaveToDisk(FILE* stream, std::string path); + static Vector3 ToWoWCoords( Vector3 vec ); + static std::string GetExtension( std::string path ); + static char* GetPlainName(const char* FileName); }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index bd0d106dabb..c7e6f0c525e 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -37,7 +37,7 @@ void WorldModelGroup::ReadNormals() Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (uint32 i = 0; i < normalCount; i++) - Normals[i] = Vector3::Read(stream); + Normals.push_back(Vector3::Read(stream)); } void WorldModelGroup::ReadLiquid() -- cgit v1.2.3 From e31e251fda42f97844ad74892d364deb424a10b7 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Oct 2012 20:53:54 -0500 Subject: Tools/MeshExtractor: More progress on extracting GameObject models --- src/tools/mesh_extractor/MeshExtractor.cpp | 53 ++++++++++++++++++++++++++-- src/tools/mesh_extractor/Utils.cpp | 20 ++++++++++- src/tools/mesh_extractor/Utils.h | 19 ++++++++++ src/tools/mesh_extractor/WorldModelGroup.cpp | 27 ++++++++++---- src/tools/mesh_extractor/WorldModelGroup.h | 11 ++++-- 5 files changed, 117 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 8eb6ba5cb6e..117a398d5cf 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -170,13 +170,62 @@ void ExtractGameobjectModels() fclose(output); delete[] indices; delete[] vertices; + + uint32 displayId = (*itr)->Values[0]; + uint32 pathLength = fileName.size(); + fwrite(&displayId, sizeof(uint32), 1, modelList); + fwrite(&pathLength, sizeof(uint32), 1, modelList); + fwrite(fileName.c_str(), sizeof(char), pathLength, modelList); } else if (extension == "wmo") { - //WorldModelRoot model(path); + WorldModelRoot model(path); + + FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); + if (!output) + { + printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); + continue; + } + + fwrite(Constants::VMAPMagic, 1, 8, output); + uint32 numVertices = 0; + fwrite(&numVertices, sizeof(uint32), 1, output); // will be filled later + fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); + fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); + + uint32 i = 0; + for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) + { + fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output); + fwrite(&itr2->Header.WmoId, sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[0], sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[1], sizeof(uint32), 1, output); + uint32 LiquidFlags = itr2->HasLiquidData ? 1 : 0; + fwrite(&LiquidFlags, sizeof(uint32), 1, output); + + fwrite("GRP ", sizeof(char), 4, output); + uint32 k = 0; + uint32 mobaBatch = itr2->MOBALength / 12; + uint32* MobaEx = new uint32[mobaBatch*4]; + + for(uint32 i = 8; i < itr2->MOBALength; i += 12) + MobaEx[k++] = itr2->MOBA[i]; + + int mobaSizeGrp = mobaBatch * 4 + 4; + fwrite(&mobaSizeGrp, 4, 1, output); + fwrite(&mobaBatch, 4, 1, output); + fwrite(MobaEx, 4, k, output); + delete[] MobaEx; + + // Note: still not finished + } + + fclose(output); } } + fclose(modelList); printf("GameObject models extraction finished!"); Constants::ToWoWCoords = false; } @@ -252,7 +301,7 @@ void PrintUsage() printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished, you need to run VMapAssembler on the extracted files)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 4414a02d681..b1b054e942e 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -483,4 +483,22 @@ char* Utils::GetPlainName(const char* FileName) if((temp = (char*)strrchr(FileName, '\\')) != NULL) FileName = temp + 1; return (char*)FileName; -} \ No newline at end of file +} + +WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) +{ + WMOGroupHeader ret; + fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); + fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); + fread(&ret.Flags, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountBatches, sizeof(uint16), 4, stream); + fread(&ret.Fogs, sizeof(uint8), 4, stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + + return ret; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 47a6354d3b2..c5dd04fde06 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -289,6 +289,25 @@ public: static H2OInformation Read(FILE* stream); }; +class WMOGroupHeader +{ +public: + WMOGroupHeader() {} + + uint32 OffsetGroupName; + uint32 OffsetDescriptiveName; + uint32 Flags; + Vector3 BoundingBox[2]; + uint32 OffsetPortals; + uint32 CountPortals; + uint16 CountBatches[4]; + uint8 Fogs[4]; + uint32 LiquidTypeRelated; + uint32 WmoId; + + static WMOGroupHeader Read(FILE* stream); +}; + // Dummy class to act as an interface. class IDefinition { diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index c7e6f0c525e..35a5ba69782 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -1,8 +1,9 @@ #include "WorldModelGroup.h" #include "ChunkedData.h" #include "Chunk.h" +#include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL) { Data = new ChunkedData(path); if (!Data->Stream) @@ -14,16 +15,20 @@ WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupInde int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); if (firstSub == -1) return; + + Name = Utils::GetPlainName(path.c_str()); + FILE* stream = mainChunk->GetStream(); fseek(stream, firstSub, SEEK_SET); SubData = new ChunkedData(stream, mainChunk->Length - firstSub); - ReadBoundingBox(); + ReadHeader(); ReadMaterials(); ReadTriangles(); ReadVertices(); ReadNormals(); ReadLiquid(); + ReadBatches(); } void WorldModelGroup::ReadNormals() @@ -108,15 +113,23 @@ void WorldModelGroup::ReadMaterials() } } -void WorldModelGroup::ReadBoundingBox() +void WorldModelGroup::ReadHeader() { Chunk* chunk = Data->GetChunkByName("MOGP"); if (!chunk) return; FILE* stream = chunk->GetStream(); - fseek(stream, 8, SEEK_CUR); - fread(&Flags, sizeof(uint32), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); + Header = WMOGroupHeader::Read(stream); +} + +void WorldModelGroup::ReadBatches() +{ + Chunk* chunk = Data->GetChunkByName("MOBA"); + if (!chunk) + return; + + MOBALength = chunk->Length / 2; + MOBA = new uint16[MOBALength]; + fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); } diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h index 1dc754d0221..e4fe34cbc75 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.h +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -10,13 +10,17 @@ public: ChunkedData* Data; ChunkedData* SubData; int GroupIndex; - Vector3 BoundingBox[2]; - uint32 Flags; + std::string Name; + WMOGroupHeader Header; + std::vector TriangleFlags; std::vector TriangleMaterials; std::vector > Triangles; std::vector Vertices; std::vector Normals; + // @ToDo: Research. + uint16* MOBA; + uint32 MOBALength; bool HasLiquidData; bool IsBad; @@ -28,6 +32,7 @@ private: void ReadVertices(); void ReadTriangles(); void ReadMaterials(); - void ReadBoundingBox(); + void ReadHeader(); + void ReadBatches(); }; #endif \ No newline at end of file -- cgit v1.2.3 From 509c8d0baefa7d8e0edbca5c9f1bb2c0d81149a4 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Oct 2012 20:59:59 -0500 Subject: Tools/MeshExtractor: Fixed build --- src/tools/mesh_extractor/MeshExtractor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 117a398d5cf..accccf4460f 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -252,9 +252,9 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis if (!param) return false; std::string maps = std::string(param); - Tokens tokens(maps, ','); + Tokenizer tokens(maps, ','); - for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) + for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); printf("Extracting only provided list of maps (%u).\n", mapList.size()); -- cgit v1.2.3 From 19d7f68592d653067c3b84c3d409e59b2724a85d Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 20 Oct 2012 07:17:11 -0500 Subject: Tools/MeshExtractor: Changed some things, lots of thanks to Faramir. --- src/tools/mesh_extractor/Constants.h | 17 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 44 ++--- src/tools/mesh_extractor/ContinentBuilder.h | 10 +- src/tools/mesh_extractor/MeshExtractor.cpp | 82 +++++++++ src/tools/mesh_extractor/TileBuilder.cpp | 231 +++++++++++++++----------- src/tools/mesh_extractor/TileBuilder.h | 4 +- src/tools/mesh_extractor/Utils.cpp | 4 + 7 files changed, 265 insertions(+), 127 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 89cd6da20a2..54fa073fbef 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -32,12 +32,13 @@ public: enum ExtractFlags { - EXTRACT_FLAG_DBC = 1, - EXTRACT_FLAG_MAPS = 2, - EXTRACT_FLAG_VMAPS = 4, - EXTRACT_FLAG_GOB_MODELS = 8, - EXTRACT_FLAG_MMAPS = 16, - EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS + EXTRACT_FLAG_DBC = 0x01, + EXTRACT_FLAG_MAPS = 0x02, + EXTRACT_FLAG_VMAPS = 0x04, + EXTRACT_FLAG_GOB_MODELS = 0x08, + EXTRACT_FLAG_MMAPS = 0x10, + EXTRACT_FLAG_TEST = 0x20, + EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS | EXTRACT_FLAG_TEST }; static const float TileSize; @@ -49,6 +50,10 @@ public: static const float MaxStandableHeight; static bool ToWoWCoords; static const char* VMAPMagic; + static const float BaseUnitDim; + static const int VertexPerMap; + static const int VertexPerTile; + static const int TilesPerMap; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index e4a1d2ca9f4..013c0ff256a 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -14,15 +14,16 @@ private: std::string Continent; bool debug; dtNavMeshParams Params; + ContinentBuilder* cBuilder; public: - BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {} + BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params), cBuilder(_cBuilder) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() { Free = false; printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(Continent, X, Y, MapId); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); @@ -57,7 +58,7 @@ public: bool Free; }; -void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) { // this is for elevation if (verts && vertCount) @@ -75,18 +76,8 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa bmin[2] = bmax[2] - Constants::TileSize; } -void ContinentBuilder::Build(bool debug) +void ContinentBuilder::CalculateTileBounds() { - char buff[50]; - sprintf(buff, "mmaps/%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - if (!mmap) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return; - } - - int tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0; for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { tileXMax = std::max(itr->X, tileXMax); @@ -95,24 +86,33 @@ void ContinentBuilder::Build(bool debug) tileYMax = std::max(itr->Y, tileYMax); tileYMin = std::min(itr->Y, tileYMin); } - - float bmin[3], bmax[3]; getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); +} + +void ContinentBuilder::Build(bool debug) +{ + char buff[50]; + sprintf(buff, "mmaps/%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); + if (!mmap) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + CalculateTileBounds(); + dtNavMeshParams params; - params.maxPolys = 32768; + params.maxPolys = 1 << STATIC_POLY_BITS; params.maxTiles = TileMap->TileTable.size(); - // rcVcopy(params.orig, bmin); - params.orig[0] = Constants::Origin[0]; - params.orig[1] = 0; - params.orig[2] = Constants::Origin[2]; + rcVcopy(params.orig, bmin); params.tileHeight = Constants::TileSize; params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(debug, params)); + Threads.push_back(new BuilderThread(this, debug, params)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index c923498fc5e..4c16fa0727e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,12 +7,20 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} void Build(bool debug); + void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); + void CalculateTileBounds(); + float bmin[3]; + float bmax[3]; private: std::string Continent; WDT* TileMap; uint32 MapId; uint32 NumberOfThreads; + int tileXMin; + int tileYMin; + int tileXMax; + int tileYMax; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index accccf4460f..7379ba87117 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -6,6 +6,10 @@ #include "Constants.h" #include "Model.h" +#include "Recast.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" + #include #include "Common.h" @@ -306,6 +310,19 @@ void PrintUsage() } } +void LoadTile(dtNavMesh*& navMesh, const char* tile) +{ + FILE* f = fopen(tile, "rb"); + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, f); + uint8* nav = new uint8[header.size]; + fread(nav, header.size, 1, f); + + dtStatus res = navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); + + fclose(f); +} + int main(int argc, char* argv[]) { system("pause"); @@ -331,6 +348,71 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ExtractGameobjectModels(); + + if (extractFlags & Constants::EXTRACT_FLAG_TEST) + { + float start[] = { 0.0f, 0.0f, 0.0f }; + float end[] = { 0.0f, 0.0f, 0.0f }; + + // + float m_spos[3]; + m_spos[0] = -1.0f * start[1]; + m_spos[1] = start[2]; + m_spos[2] = -1.0f * start[0]; + + // + float m_epos[3]; + m_epos[0] = -1.0f * end[1]; + m_epos[1] = end[2]; + m_epos[2] = -1.0f * end[0]; + + // + dtQueryFilter m_filter; + m_filter.setIncludeFlags(0xffff) ; + m_filter.setExcludeFlags(0); + + // + float m_polyPickExt[3]; + m_polyPickExt[0] = 2; + m_polyPickExt[1] = 4; + m_polyPickExt[2] = 2; + + // + dtPolyRef m_startRef; + dtPolyRef m_endRef; + + FILE* mmap = fopen(".mmap", "rb"); + dtNavMeshParams params; + fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + + dtNavMesh* navMesh = new dtNavMesh(); + dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); + + navMesh->init(¶ms); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + LoadTile(navMesh, ".mmtile"); + + navMeshQuery->init(navMesh, 2048); + + float nearestPt[3]; + + dtStatus status = navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + status = navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + + // + if ( !m_startRef || !m_endRef ) + { + std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; + return 0; + } + + printf("Found!"); + } return 0; } \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 12213b16373..2a02bc50cd4 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,3 +1,4 @@ +#include "ContinentBuilder.h" #include "TileBuilder.h" #include "Geometry.h" #include "Constants.h" @@ -11,8 +12,10 @@ #include "ace/Synch.h" -TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) +TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), cBuilder(_cBuilder) { + /* + Test, non-working values // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize Config.cs = Constants::TileSize / 1800; @@ -35,6 +38,26 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Config.height = 1800 + Config.borderSize * 2; Config.maxVertsPerPoly = 6; Config.maxSimplificationError = 1.3f; + */ + + // All are in UNIT metrics! + memset(&Config, 0, sizeof(rcConfig)); + + Config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; + Config.cs = Constants::BaseUnitDim; + Config.ch = Constants::BaseUnitDim; + Config.walkableSlopeAngle = 60.0f; + Config.tileSize = Constants::VertexPerTile; + Config.walkableRadius = 1; + Config.borderSize = Config.walkableRadius + 3; + Config.maxEdgeLen = Constants::VertexPerTile + 1; //anything bigger than tileSize + Config.walkableHeight = 3; + Config.walkableClimb = 2; // keep less than walkableHeight + Config.minRegionArea = rcSqr(60); + Config.mergeRegionArea = rcSqr(50); + Config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) + Config.detailSampleDist = Config.cs * 64; + Config.detailSampleMaxError = Config.ch * 2; Context = new rcContext; } @@ -104,84 +127,101 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - float bbMin[3]; - float bbMax[3]; - // CalculateTileBounds(bbMin, bbMax, navMeshParams); - rcCalcBounds(vertices, numVerts, bbMin, bbMax); - // _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); - - /*bbMin[0] -= Config.borderSize * Config.cs; - bbMin[2] -= Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs;*/ - - - rcHeightfield* hf = rcAllocHeightfield(); - int height, width; - rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height); - printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width); - rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch); - rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - - printf("[%02i,%02i] Triangles rasterized!\n", X, Y); - - // Once all geometry is rasterized, we do initial pass of filtering to - // remove unwanted overhangs caused by the conservative rasterization - // as well as filter spans where the character cannot possibly stand. - rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); - rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - - printf("[%02i,%02i] Filtering done!\n", X, Y); - - // Compact the heightfield so that it is faster to handle from now on. - // This will result in more cache coherent data as well as the neighbours - // between walkable cells will be calculated. - rcCompactHeightfield* chf = rcAllocCompactHeightfield(); - rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); - - rcFreeHeightField(hf); - - printf("[%02i,%02i] Heightfield compressed!\n", X, Y); - - // Erode the walkable area by agent radius. - rcErodeWalkableArea(Context, Config.walkableRadius, *chf); - // Prepare for region partitioning, by calculating distance field along the walkable surface. - rcBuildDistanceField(Context, *chf); - // Partition the walkable surface into simple regions without holes. - rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + rcVcopy(Config.bmin, cBuilder->bmin); + rcVcopy(Config.bmax, cBuilder->bmax); + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height); + + // Initialize per tile config. + rcConfig tileCfg = Config; + tileCfg.width = Config.tileSize + Config.borderSize * 2; + tileCfg.height = Config.tileSize + Config.borderSize * 2; - printf("[%02i,%02i] Regions built!\n", X, Y); + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[Constants::TilesPerMap * Constants::TilesPerMap]; + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[Constants::TilesPerMap * Constants::TilesPerMap]; - // Create contours. - rcContourSet* cset = rcAllocContourSet(); - rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); + int nmerge = 0; + for (int y = 0; y < Constants::TilesPerMap; ++y) + { + for (int x = 0; x < Constants::TilesPerMap; ++x) + { + // Calculate the per tile bounding box. + tileCfg.bmin[0] = Config.bmin[0] + float(x * Config.tileSize - Config.borderSize) * Config.cs; + tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs; + tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs; + tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs; + + + rcHeightfield* hf = rcAllocHeightfield(); + rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch); + rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); + + // Once all geometry is rasterized, we do initial pass of filtering to + // remove unwanted overhangs caused by the conservative rasterization + // as well as filter spans where the character cannot possibly stand. + rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); + rcFilterLedgeSpans(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, tileCfg.walkableHeight, *hf); + + // Compact the heightfield so that it is faster to handle from now on. + // This will result in more cache coherent data as well as the neighbours + // between walkable cells will be calculated. + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf, *chf); + + rcFreeHeightField(hf); + + // Erode the walkable area by agent radius. + rcErodeWalkableArea(Context, Config.walkableRadius, *chf); + // Prepare for region partitioning, by calculating distance field along the walkable surface. + rcBuildDistanceField(Context, *chf); + // Partition the walkable surface into simple regions without holes. + rcBuildRegions(Context, *chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea); + + // Create contours. + rcContourSet* cset = rcAllocContourSet(); + rcBuildContours(Context, *chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *cset); + + // Build polygon navmesh from the contours. + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *cset, tileCfg.maxVertsPerPoly, *pmesh); + + // Build detail mesh. + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *dmesh); + + // Free memory + rcFreeCompactHeightfield(chf); + rcFreeContourSet(cset); + + pmmerge[nmerge] = pmesh; + dmmerge[nmerge] = dmesh; + ++nmerge; + } + } - // Build polygon navmesh from the contours. rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); - - printf("[%02i,%02i] Polymesh built!\n", X, Y); - - // Build detail mesh. + rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - - printf("[%02i,%02i] Polymesh detail built!\n", X, Y); - - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - - /* - * Removed with RecastNavigation v292 + rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); + + delete[] pmmerge; + delete[] dmmerge; + + printf("[%02i,%02i] Meshes merged!\n", X, Y); + // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { unsigned short* v = &pmesh->verts[i * 3]; v[0] -= (unsigned short)Config.borderSize; v[2] -= (unsigned short)Config.borderSize; - }*/ + } // Set flags according to area types (e.g. Swim for Water) for (int i = 0; i < pmesh->npolys; i++) @@ -192,14 +232,8 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } - // get original bounds - /*float* tilebMin; - float* tilebMax; - CalculateTileBounds(tilebMin, tilebMax, navMeshParams); - tilebMin[1] = bbMin[1]; - tilebMax[1] = bbMax[1];*/ - dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); // PolyMesh data params.verts = pmesh->verts; params.vertCount = pmesh->nverts; @@ -214,32 +248,39 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) params.detailVertsCount = dmesh->nverts; params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; - // Copy bounding box - /*params.bmin[0] = tilebMin[0]; - params.bmin[1] = tilebMin[1]; - params.bmin[2] = tilebMin[2]; - params.bmax[0] = tilebMax[0]; - params.bmax[1] = tilebMax[1]; - params.bmax[2] = tilebMax[2];*/ rcVcopy(params.bmin, pmesh->bmin); rcVcopy(params.bmax, pmesh->bmax); // General settings params.ch = Config.ch; params.cs = Config.cs; - params.walkableClimb = Config.walkableClimb; - params.walkableHeight = Config.walkableHeight; - params.walkableRadius = Config.walkableRadius; - params.tileX = X; - params.tileY = Y; - int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize; - int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize; - printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]); - params.buildBvTree = true; - params.tileLayer = 0; - + params.walkableClimb = Constants::BaseUnitDim * Config.walkableClimb; + params.walkableHeight = Constants::BaseUnitDim * Config.walkableHeight; + params.walkableRadius = Constants::BaseUnitDim * Config.walkableRadius; + params.tileX = (((cBuilder->bmin[0] + cBuilder->bmax[0]) / 2) - navMeshParams.orig[0]) / Constants::TileSize; + params.tileY = (((cBuilder->bmin[2] + cBuilder->bmax[2]) / 2) - navMeshParams.orig[2]) / Constants::TileSize; + + rcVcopy(params.bmin, cBuilder->bmin); + rcVcopy(params.bmax, cBuilder->bmax); + // Offmesh-connection settings params.offMeshConCount = 0; // none for now + + params.tileSize = Constants::VertexPerMap; + if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) + { + // we have flat tiles with no actual geometry - don't build those, its useless + // keep in mind that we do output those into debug info + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("[%02i,%02i] No polygons to build on tile, skipping.\n", X, Y); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete areas; + delete triangles; + delete vertices; + return NULL; + } + int navDataSize; uint8* navData; printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); @@ -248,13 +289,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - //delete tilebMax; - //delete tilebMin; delete areas; delete triangles; delete vertices; - //delete bbMax; - //delete bbMin; if (result) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 17d6e48095a..40c96f6ec42 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -5,12 +5,13 @@ #include "Geometry.h" +class ContinentBuilder; class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, uint32 mapId); + TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId); ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); @@ -24,5 +25,6 @@ public: rcContext* Context; Geometry* _Geometry; uint32 DataSize; + ContinentBuilder* cBuilder; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index b1b054e942e..3639cb88acf 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -21,6 +21,10 @@ const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; const char* Constants::VMAPMagic = "VMAP041"; bool Constants::ToWoWCoords = false; +const float Constants::BaseUnitDim = 0.533333f; +const int Constants::VertexPerMap = (Constants::TileSize / Constants::BaseUnitDim) + 0.5f; +const int Constants::VertexPerTile = 40; +const int Constants::TilesPerMap = Constants::VertexPerMap / Constants::VertexPerTile; void Utils::CreateDir( const std::string& Path ) { -- cgit v1.2.3 From 677ee02b8ea32aad12bce60db7527c60ef76f164 Mon Sep 17 00:00:00 2001 From: kaelima Date: Wed, 7 Nov 2012 16:42:22 +0100 Subject: Core/Movement: MovementGenerator fixes. - vmap height search in FleeingMovementGenerator and ConfusedMovementGenerator (until we can search for a nearby position properly) Should solve #7704, needs testing - Removed some unused code in CalculatePath and TargetedMovementGenerator. Ty faramir118 - Allow players to charge through slime and lava liquids. Closes #7967 --- .../ConfusedMovementGenerator.cpp | 22 +++-- .../FleeingMovementGenerator.cpp | 26 ++++-- .../TargetedMovementGenerator.cpp | 100 ++++++++------------- .../MovementGenerators/TargetedMovementGenerator.h | 3 +- src/server/game/Movement/PathGenerator.cpp | 25 +----- src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 +- 6 files changed, 79 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 4c269a1024a..4af5f7b4acb 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -70,18 +70,26 @@ bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) // start moving unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); - float x = i_x + 10.0f*((float)rand_norm() - 0.5f); - float y = i_y + 10.0f*((float)rand_norm() - 0.5f); - float z = i_z; + float x = i_x + (4.0f * (float)rand_norm() - 2.0f); + float y = i_y + (4.0f * (float)rand_norm() - 2.0f); - unit->UpdateAllowedPositionZ(x, y, z); + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + + float z = unit->GetBaseMap()->GetHeight(unit->GetPhaseMask(), x, y, 10.0f, true); + + if (z <= INVALID_HEIGHT || fabs(i_z - z) > 10.0f || !unit->IsWithinLOS(x, y, z)) + { + i_nextMoveTime.Reset(100); + return true; + } PathGenerator path(unit); - path.SetPathLengthLimit(30.0f); + path.SetPathLengthLimit(20.0f); bool result = path.CalculatePath(x, y, z); - if (!result || path.GetPathType() & PATHFIND_NOPATH) + if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { - i_nextMoveTime.Reset(urand(800, 1000)); + i_nextMoveTime.Reset(100); // short reset return true; } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index b8764bd5042..5cdbdb24341 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -39,16 +39,19 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) float x, y, z; if (!_getPoint(owner, x, y, z)) + { + i_nextCheckTime.Reset(100); return; + } owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); PathGenerator path(owner); - path.SetPathLengthLimit(30.0f); + path.SetPathLengthLimit(20.0f); bool result = path.CalculatePath(x, y, z); - if (!result || path.GetPathType() & PATHFIND_NOPATH) + if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { - i_nextCheckTime.Reset(urand(1000, 1500)); + i_nextCheckTime.Reset(100); return; } @@ -86,7 +89,7 @@ bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float dist = frand(0.4f, 1.3f)*(MIN_QUIET_DISTANCE - dist_from_caster); angle = angle_to_caster + frand(-static_cast(M_PI)/8, static_cast(M_PI)/8); } - else if(dist_from_caster > MAX_QUIET_DISTANCE) + else if (dist_from_caster > MAX_QUIET_DISTANCE) { dist = frand(0.4f, 1.0f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); angle = -angle_to_caster + frand(-static_cast(M_PI)/4, static_cast(M_PI)/4); @@ -102,9 +105,17 @@ bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float x = curr_x + dist * std::cos(angle); y = curr_y + dist * std::sin(angle); - z = curr_z; - owner->UpdateAllowedPositionZ(x, y, z); + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + + z = owner->GetBaseMap()->GetHeight(owner->GetPhaseMask(), x, y, 10.0f, true); + + if (z <= INVALID_HEIGHT) + return false; + + if (fabs(curr_z - z) > 10.0f || !owner->IsWithinLOS(x, y, z)) + return false; return true; } @@ -152,6 +163,7 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) { if (!owner || !owner->isAlive()) return false; + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE); @@ -159,7 +171,7 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) } i_nextCheckTime.Update(time_diff); - if (i_nextCheckTime.Passed() && owner->movespline->Finalized()) + if (i_nextCheckTime.Passed()) _setTargetLocation(owner); return true; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 7a6611ed2ca..dc6cc55b855 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -27,7 +27,7 @@ #include "Player.h" template -void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) +void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool updateDestination) { if (!i_target.isValid() || !i_target->IsInWorld()) return; @@ -40,37 +40,42 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) float x, y, z; - if (!i_offset) + if (updateDestination || !i_path) { - float dist = 0.0f; - - if (owner->getVictim() && owner->getVictim()->GetGUID() == i_target->GetGUID()) - dist = owner->GetFloatValue(UNIT_FIELD_COMBATREACH) + i_target->GetFloatValue(UNIT_FIELD_COMBATREACH) - i_target->GetObjectSize() - owner->GetObjectSize() - 1.0f; - - if (dist < 0.5f) - dist = 0.5f; - - if (owner->IsWithinLOSInMap(owner->getVictim())) - i_target->GetContactPoint(owner, x, y, z, dist); + if (!i_offset) + { + // to nearest contact position + i_target->GetContactPoint(owner, x, y, z); + } else - i_target->GetPosition(x, y, z); + { + // to at i_offset distance from target and i_angle from target facing + i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); + } } else { - // to at i_offset distance from target and i_angle from target facing - i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); + // the destination has not changed, we just need to refresh the path (usually speed change) + G3D::Vector3 end = i_path->GetEndPosition(); + x = end.x; + y = end.y; + z = end.z; } if (!i_path) i_path = new PathGenerator(owner); - // allow pets following their master to cheat while generating paths + // allow pets to use shortcut if no path found when following their master bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)); bool result = i_path->CalculatePath(x, y, z, forceDest); - if (!result || i_path->GetPathType() & PATHFIND_NOPATH) + if (!result || (i_path->GetPathType() & PATHFIND_NOPATH)) + { + // Cant reach target + i_recalculateTravel = true; return; + } D::_addUnitStateMove(owner); i_targetReached = false; @@ -79,37 +84,14 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->GetPath()); - init.SetFacing(i_target.getTarget()); + if (forceDest && updateDestination) + init.SetFacing(i_target.getTarget()->GetOrientation()); + else + init.SetFacing(i_target.getTarget()); init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float /*fDistance*/) -{ - // nothing to do for Player -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float /*fDistance*/) -{ - // nothing to do for Player -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float fDistance) -{ - i_offset = fDistance; - i_recalculateTravel = true; -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float fDistance) -{ - i_offset = fDistance; - i_recalculateTravel = true; -} - template bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_diff) { @@ -140,6 +122,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d return true; } + bool targetMoved = false; i_recheckDistance.Update(time_diff); if (i_recheckDistance.Passed()) { @@ -148,16 +131,15 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d float allowed_dist = owner->GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE); G3D::Vector3 dest = owner->movespline->FinalDestination(); - bool targetMoved = false; if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly()) targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); - - if (targetMoved || !owner->IsWithinLOSInMap(owner->getVictim())) - _setTargetLocation(owner); } + if (i_recalculateTravel || targetMoved) + _setTargetLocation(owner, targetMoved); + if (owner->movespline->Finalized()) { static_cast(this)->MovementInform(owner); @@ -170,11 +152,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d static_cast(this)->_reachTarget(owner); } } - else - { - if (i_recalculateTravel) - _setTargetLocation(owner); - } + return true; } @@ -190,7 +168,7 @@ template<> void ChaseMovementGenerator::Initialize(Player* owner) { owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template<> @@ -198,7 +176,7 @@ void ChaseMovementGenerator::Initialize(Creature* owner) { owner->SetWalk(false); owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template @@ -262,7 +240,7 @@ void FollowMovementGenerator::Initialize(Player* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template<> @@ -270,7 +248,7 @@ void FollowMovementGenerator::Initialize(Creature* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template @@ -300,10 +278,10 @@ void FollowMovementGenerator::MovementInform(Creature* unit) } //-----------------------------------------------// -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); template bool TargetedMovementGeneratorMedium >::Update(Creature*, const uint32&); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 064e5bfa1a2..f293d5976af 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -51,10 +51,9 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, Unit* GetTarget() const { return i_target.getTarget(); } void unitSpeedChanged() { i_recalculateTravel = true; } - void UpdateFinalDistance(float fDistance); bool IsReachable() const { return (i_path) ? (i_path->GetPathType() & PATHFIND_NORMAL) : true; } protected: - void _setTargetLocation(T*); + void _setTargetLocation(T* owner, bool updateDestination); TimeTrackerSmall i_recheckDistance; float i_offset; diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 3495c4d1218..71617f6a6ab 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -58,7 +58,6 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; - Vector3 oldDest = GetEndPosition(); Vector3 dest(destX, destY, destZ); SetEndPosition(dest); @@ -81,24 +80,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo UpdateFilter(); - // check if destination moved - if not we can optimize something here - // we are following old, precalculated path? - float dist = _sourceUnit->GetObjectSize(); - if (oldDest != Vector3::zero() && InRange(oldDest, dest, dist, dist) && _pathPoints.size() > 2) - { - // our target is not moving - we just coming closer - // we are moving on precalculated path - enjoy the ride - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath:: precalculated path\n"); - - _pathPoints.erase(_pathPoints.begin()); - return false; - } - else - { - // target moved, so we need to update the poly path - BuildPolyPath(start, dest); - return true; - } + BuildPolyPath(start, dest); + return true; } dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* point, float* distance) const @@ -534,10 +517,10 @@ void PathGenerator::CreateFilter() if (creature->canSwim()) includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim } - else if (_sourceUnit->GetTypeId() == TYPEID_PLAYER) + else // assume Player { // perfect support not possible, just stay 'safe' - includeFlags |= (NAV_GROUND | NAV_WATER); + includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME); } _filter.setIncludeFlags(includeFlags); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 67b019b93f7..b6cd1391ca3 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -98,7 +98,7 @@ namespace Movement if (!args.HasVelocity) args.velocity = unit->GetSpeed(SelectSpeedType(moveFlags)); - if (!args.Validate(&unit)) + if (!args.Validate(unit)) return 0; if (moveFlags & MOVEMENTFLAG_ROOT) -- cgit v1.2.3 From 7249865a12e6483b925fae468bd899b73c190e39 Mon Sep 17 00:00:00 2001 From: rocky517 Date: Mon, 12 Nov 2012 14:43:51 +0200 Subject: Update src/server/scripts/Commands/cs_mmaps.cpp --- src/server/scripts/Commands/cs_mmaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c3f757614e2..c17c01adc33 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -96,7 +96,7 @@ public: bool result = path.CalculatePath(x, y, z); PointsArray pointPath = path.GetPath(); - handler->PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName()); + handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); -- cgit v1.2.3 From 94cca94017d8652ce8efebed15894ea09dedf598 Mon Sep 17 00:00:00 2001 From: kaelima Date: Tue, 13 Nov 2012 15:44:42 +0100 Subject: Core/Movement: General improvements for confused/fleeing movement --- src/server/game/Movement/MotionMaster.cpp | 4 +- .../ConfusedMovementGenerator.cpp | 35 ++++++++------- .../FleeingMovementGenerator.cpp | 52 ++++++---------------- .../MovementGenerators/FleeingMovementGenerator.h | 2 +- 4 files changed, 35 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index b9cfbdf024f..48f17a0d0c6 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -651,9 +651,9 @@ void MotionMaster::DelayedDelete(_Ty curr) bool MotionMaster::GetDestination(float &x, float &y, float &z) { if (_owner->movespline->Finalized()) - return false; + return false; - const G3D::Vector3& dest = _owner->movespline->FinalDestination(); + G3D::Vector3 const& dest = _owner->movespline->FinalDestination(); x = dest.x; y = dest.y; z = dest.z; diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 4af5f7b4acb..a8b4d68c802 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -33,16 +33,25 @@ template void ConfusedMovementGenerator::Initialize(T* unit) { + unit->AddUnitState(UNIT_STATE_CONFUSED); + unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit->GetPosition(i_x, i_y, i_z); + + if (!unit->isAlive() || unit->IsStopped()) + return; + unit->StopMoving(); - unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit->AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); + unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); } template void ConfusedMovementGenerator::Reset(T* unit) { i_nextMoveTime.Reset(0); + + if (!unit->isAlive() || unit->IsStopped()) + return; + unit->StopMoving(); unit->AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } @@ -70,26 +79,18 @@ bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) // start moving unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); - float x = i_x + (4.0f * (float)rand_norm() - 2.0f); - float y = i_y + (4.0f * (float)rand_norm() - 2.0f); + float dest = 4.0f * (float)rand_norm() - 2.0f; - Trinity::NormalizeMapCoord(x); - Trinity::NormalizeMapCoord(y); - - float z = unit->GetBaseMap()->GetHeight(unit->GetPhaseMask(), x, y, 10.0f, true); - - if (z <= INVALID_HEIGHT || fabs(i_z - z) > 10.0f || !unit->IsWithinLOS(x, y, z)) - { - i_nextMoveTime.Reset(100); - return true; - } + Position pos; + pos.Relocate(i_x, i_y, i_z); + unit->MovePositionToFirstCollision(pos, dest, 0.0f); PathGenerator path(unit); - path.SetPathLengthLimit(20.0f); - bool result = path.CalculatePath(x, y, z); + path.SetPathLengthLimit(30.0f); + bool result = path.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ); if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { - i_nextMoveTime.Reset(100); // short reset + i_nextMoveTime.Reset(100); return true; } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 5cdbdb24341..578654ca162 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -37,17 +37,13 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) return; - float x, y, z; - if (!_getPoint(owner, x, y, z)) - { - i_nextCheckTime.Reset(100); - return; - } - owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); + float x, y, z; + _getPoint(owner, x, y, z); + PathGenerator path(owner); - path.SetPathLengthLimit(20.0f); + path.SetPathLengthLimit(30.0f); bool result = path.CalculatePath(x, y, z); if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { @@ -63,11 +59,8 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) } template -bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float &z) +void FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float &z) { - if (!owner) - return false; - float dist_from_caster, angle_to_caster; if (Unit* fright = ObjectAccessor::GetUnit(*owner, i_frightGUID)) { @@ -100,24 +93,11 @@ bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float angle = frand(0, 2*static_cast(M_PI)); } - float curr_x, curr_y, curr_z; - owner->GetPosition(curr_x, curr_y, curr_z); - - x = curr_x + dist * std::cos(angle); - y = curr_y + dist * std::sin(angle); - - Trinity::NormalizeMapCoord(x); - Trinity::NormalizeMapCoord(y); - - z = owner->GetBaseMap()->GetHeight(owner->GetPhaseMask(), x, y, 10.0f, true); - - if (z <= INVALID_HEIGHT) - return false; - - if (fabs(curr_z - z) > 10.0f || !owner->IsWithinLOS(x, y, z)) - return false; - - return true; + Position pos; + owner->GetFirstCollisionPosition(pos, dist, angle); + x = pos.m_positionX; + y = pos.m_positionY; + z = pos.m_positionZ; } template @@ -127,11 +107,7 @@ void FleeingMovementGenerator::Initialize(T* owner) return; owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - owner->AddUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); - - if (owner->GetTypeId() == TYPEID_UNIT) - return; - + owner->AddUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE); _setTargetLocation(owner); } @@ -171,7 +147,7 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) } i_nextCheckTime.Update(time_diff); - if (i_nextCheckTime.Passed()) + if (i_nextCheckTime.Passed() && owner->movespline->Finalized()) _setTargetLocation(owner); return true; @@ -179,8 +155,8 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) template void FleeingMovementGenerator::Initialize(Player*); template void FleeingMovementGenerator::Initialize(Creature*); -template bool FleeingMovementGenerator::_getPoint(Player*, float&, float&, float&); -template bool FleeingMovementGenerator::_getPoint(Creature*, float&, float&, float&); +template void FleeingMovementGenerator::_getPoint(Player*, float&, float&, float&); +template void FleeingMovementGenerator::_getPoint(Creature*, float&, float&, float&); template void FleeingMovementGenerator::_setTargetLocation(Player*); template void FleeingMovementGenerator::_setTargetLocation(Creature*); template void FleeingMovementGenerator::Reset(Player*); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index 88dedd31af6..ed1fe85a314 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -36,7 +36,7 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem private: void _setTargetLocation(T*); - bool _getPoint(T*, float &x, float &y, float &z); + void _getPoint(T*, float &x, float &y, float &z); uint64 i_frightGUID; TimeTracker i_nextCheckTime; -- cgit v1.2.3 From 0fa484793acb1f6b556569ebfc9ce472372d5d78 Mon Sep 17 00:00:00 2001 From: Nay Date: Fri, 23 Nov 2012 23:44:43 +0000 Subject: Fix a typo in previous merge --- .../game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 554e38d7efd..45c7c7c9ab2 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -55,10 +55,10 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool upd // We need to subtract GetObjectSize() because it gets added back further down the chain // and that makes pets too far away. Subtracting it allows pets to properly // be (GetCombatReach() + i_offset) away. - if (owner.isPet()) + if (owner->isPet()) size = i_target->GetCombatReach() - i_target->GetObjectSize(); else - size = owner.GetObjectSize(); + size = owner->GetObjectSize(); // to at i_offset distance from target and i_angle from target facing i_target->GetClosePoint(x, y, z, size, i_offset, i_angle); -- cgit v1.2.3 From 8f27dfda627903997b67cab9ebb4c5b365da201e Mon Sep 17 00:00:00 2001 From: Nay Date: Sat, 24 Nov 2012 23:48:30 +0000 Subject: Core/SAI: Add more details to an error log --- src/server/game/Conditions/ConditionMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 2f3cb0fbaaf..5fe81bcf89c 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1410,7 +1410,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) if (cond->ConditionTarget >= cond->GetMaxAvailableConditionTargets()) { - sLog->outError(LOG_FILTER_SQL, "SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry); + sLog->outError(LOG_FILTER_SQL, "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup); return false; } -- cgit v1.2.3 From a0239c2210a49a3b41a764d41d75098e8bb8ffeb Mon Sep 17 00:00:00 2001 From: kaelima Date: Sat, 22 Dec 2012 02:22:44 +0100 Subject: Fix last merge --- .../MovementGenerators/TargetedMovementGenerator.cpp | 14 +++++++++++++- src/server/game/Movement/Spline/MoveSpline.h | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 0cb46a11e2e..88eacccd0aa 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -49,16 +49,28 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool upd } else { + float dist; float size; // Pets need special handling. // We need to subtract GetObjectSize() because it gets added back further down the chain // and that makes pets too far away. Subtracting it allows pets to properly // be (GetCombatReach() + i_offset) away. - if (owner->isPet()) + // Only applies when i_target is pet's owner otherwise pets and mobs end up + // doing a "dance" while fighting + if (owner->isPet() && i_target->GetTypeId() == TYPEID_PLAYER) + { + dist = i_target->GetCombatReach(); size = i_target->GetCombatReach() - i_target->GetObjectSize(); + } else + { + dist = i_offset + 1.0f; size = owner->GetObjectSize(); + } + + if (i_target->IsWithinDistInMap(owner, dist)) + return; // to at i_offset distance from target and i_angle from target facing i_target->GetClosePoint(x, y, z, size, i_offset, i_angle); diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index edeff668e0c..938466cd475 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -78,11 +78,11 @@ namespace Movement UpdateResult _updateState(int32& ms_time_diff); int32 next_timestamp() const { return spline.length(point_Idx+1); } int32 segment_time_elapsed() const { return next_timestamp()-time_passed; } - int32 Duration() const { return spline.length(); } int32 timeElapsed() const { return Duration() - time_passed; } int32 timePassed() const { return time_passed; } public: + int32 Duration() const { return spline.length(); } const MySpline& _Spline() const { return spline; } int32 _currentSplineIdx() const { return point_Idx; } void _Finalize(); -- cgit v1.2.3 From 08f62d8313e05ed6eb1767eed07a7e31533e9bb6 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sun, 30 Dec 2012 21:09:21 +0100 Subject: Core/MMaps: use DisableMgr to disable pathfinding on a specific map --- sql/updates/world/2012_12_30_00_world_commands.sql | 4 +++ src/server/collision/Management/MMapFactory.cpp | 32 ++-------------------- src/server/collision/Management/MMapFactory.h | 1 - src/server/game/Conditions/DisableMgr.cpp | 31 ++++++++++++++++++++- src/server/game/Conditions/DisableMgr.h | 8 +++++- src/server/game/World/World.cpp | 1 - src/server/scripts/Commands/cs_disable.cpp | 32 ++++++++++++++++++++++ src/server/worldserver/worldserver.conf.dist | 7 ----- 8 files changed, 75 insertions(+), 41 deletions(-) create mode 100644 sql/updates/world/2012_12_30_00_world_commands.sql (limited to 'src') diff --git a/sql/updates/world/2012_12_30_00_world_commands.sql b/sql/updates/world/2012_12_30_00_world_commands.sql new file mode 100644 index 00000000000..fffd1a95cb5 --- /dev/null +++ b/sql/updates/world/2012_12_30_00_world_commands.sql @@ -0,0 +1,4 @@ +DELETE FROM `command` WHERE `name` LIKE 'disable add mmap' OR `name` LIKE 'disable remove mmap'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('disable add mmap', '3', 'Syntax: .disable add mmap $entry $flag $comment'), +('disable remove mmap', '3', 'Syntax: .disable remove mmap $entry'); diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp index f4b2f3d47e4..0b292b56dca 100644 --- a/src/server/collision/Management/MMapFactory.cpp +++ b/src/server/collision/Management/MMapFactory.cpp @@ -19,7 +19,7 @@ #include "MMapFactory.h" #include "World.h" #include "Config.h" -#include +#include "DisableMgr.h" namespace MMAP { @@ -27,9 +27,6 @@ namespace MMAP // our global singleton copy MMapManager *g_MMapManager = NULL; - // stores list of mapids which do not use pathfinding - std::set* g_mmapDisabledIds = NULL; - MMapManager* MMapFactory::createOrGetMMapManager() { if (g_MMapManager == NULL) @@ -38,39 +35,14 @@ namespace MMAP return g_MMapManager; } - void MMapFactory::preventPathfindingOnMaps(const char* ignoreMapIds) - { - if (!g_mmapDisabledIds) - g_mmapDisabledIds = new std::set(); - - uint32 strLenght = strlen(ignoreMapIds)+1; - char* mapList = new char[strLenght]; - memcpy(mapList, ignoreMapIds, sizeof(char)*strLenght); - - char* idstr = strtok(mapList, ","); - while (idstr) - { - g_mmapDisabledIds->insert(uint32(atoi(idstr))); - idstr = strtok(NULL, ","); - } - - delete[] mapList; - } - bool MMapFactory::IsPathfindingEnabled(uint32 mapId) { return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) - && g_mmapDisabledIds->find(mapId) == g_mmapDisabledIds->end(); + && !DisableMgr::IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING); } void MMapFactory::clear() { - if (g_mmapDisabledIds) - { - delete g_mmapDisabledIds; - g_mmapDisabledIds = NULL; - } - if (g_MMapManager) { delete g_MMapManager; diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h index ab047333a19..a006aedfa6d 100644 --- a/src/server/collision/Management/MMapFactory.h +++ b/src/server/collision/Management/MMapFactory.h @@ -42,7 +42,6 @@ namespace MMAP public: static MMapManager* createOrGetMMapManager(); static void clear(); - static void preventPathfindingOnMaps(const char* ignoreMapIds); static bool IsPathfindingEnabled(uint32 mapId); }; } diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index b544e966084..c9cef63907e 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -42,7 +42,7 @@ namespace DisableMap m_DisableMap; - uint8 MAX_DISABLE_TYPES = 7; + uint8 MAX_DISABLE_TYPES = 8; } void LoadDisables() @@ -222,6 +222,34 @@ void LoadDisables() } break; } + case DISABLE_TYPE_MMAP: + { + MapEntry const* mapEntry = sMapStore.LookupEntry(entry); + if (!mapEntry) + { + sLog->outError(LOG_FILTER_SQL, "Map entry %u from `disables` doesn't exist in dbc, skipped.", entry); + continue; + } + switch (mapEntry->map_type) + { + case MAP_COMMON: + sLog->outInfo(LOG_FILTER_GENERAL, "Pathfinding disabled for world map %u.", entry); + break; + case MAP_INSTANCE: + case MAP_RAID: + sLog->outInfo(LOG_FILTER_GENERAL, "Pathfinding disabled for instance map %u.", entry); + break; + case MAP_BATTLEGROUND: + sLog->outInfo(LOG_FILTER_GENERAL, "Pathfinding disabled for battleground map %u.", entry); + break; + case MAP_ARENA: + sLog->outInfo(LOG_FILTER_GENERAL, "Pathfinding disabled for arena map %u.", entry); + break; + default: + break; + } + break; + } default: break; } @@ -348,6 +376,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags case DISABLE_TYPE_BATTLEGROUND: case DISABLE_TYPE_OUTDOORPVP: case DISABLE_TYPE_ACHIEVEMENT_CRITERIA: + case DISABLE_TYPE_MMAP: return true; case DISABLE_TYPE_VMAP: return flags & itr->second.flags; diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index b1bb43315bd..379f0ac967b 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -31,7 +31,8 @@ enum DisableType DISABLE_TYPE_BATTLEGROUND = 3, DISABLE_TYPE_ACHIEVEMENT_CRITERIA = 4, DISABLE_TYPE_OUTDOORPVP = 5, - DISABLE_TYPE_VMAP = 6 + DISABLE_TYPE_VMAP = 6, + DISABLE_TYPE_MMAP = 7 }; enum SpellDisableTypes @@ -54,6 +55,11 @@ enum VmapDisableTypes VMAP_DISABLE_LIQUIDSTATUS = 0x8 }; +enum MMapDisableTypes +{ + MMAP_DISABLE_PATHFINDING = 0x0 +}; + namespace DisableMgr { void LoadDisables(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 81261138957..d09bea8b9a6 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1134,7 +1134,6 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); - MMAP::MMapFactory::preventPathfindingOnMaps(ConfigMgr::GetStringDefault("mmap.ignoreMapIds", "").c_str()); m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); bool enableIndoor = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", true); diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index cf0b1f08e53..e17cd35b329 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -48,6 +48,7 @@ public: { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleRemoveDisableAchievementCriteriaCommand, "", NULL }, { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleRemoveDisableOutdoorPvPCommand, "", NULL }, { "vmap", SEC_ADMINISTRATOR, true, &HandleRemoveDisableVmapCommand, "", NULL }, + { "mmap", SEC_ADMINISTRATOR, true, &HandleRemoveDisableMMapCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand addDisableCommandTable[] = @@ -59,6 +60,7 @@ public: { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleAddDisableAchievementCriteriaCommand, "", NULL }, { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleAddDisableOutdoorPvPCommand, "", NULL }, { "vmap", SEC_ADMINISTRATOR, true, &HandleAddDisableVmapCommand, "", NULL }, + { "mmap", SEC_ADMINISTRATOR, true, &HandleAddDisableMMapCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand disableCommandTable[] = @@ -172,6 +174,17 @@ public: disableTypeStr = "vmap"; break; } + case DISABLE_TYPE_MMAP: + { + if (!sMapStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "mmap"; + break; + } default: break; } @@ -256,6 +269,14 @@ public: return HandleAddDisables(handler, args, DISABLE_TYPE_VMAP); } + static bool HandleAddDisableMMapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_MMAP); + } + static bool HandleRemoveDisables(ChatHandler* handler, char const* args, uint8 disableType) { char* entryStr = strtok((char*)args, " "); @@ -289,6 +310,9 @@ public: case DISABLE_TYPE_VMAP: disableTypeStr = "vmap"; break; + case DISABLE_TYPE_MMAP: + disableTypeStr = "mmap"; + break; } PreparedStatement* stmt = NULL; @@ -367,6 +391,14 @@ public: return HandleRemoveDisables(handler, args, DISABLE_TYPE_VMAP); } + + static bool HandleRemoveDisableMMapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleRemoveDisables(handler, args, DISABLE_TYPE_MMAP); + } }; void AddSC_disable_commandscript() diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 426d4ab2d55..81b4dad8b06 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -276,13 +276,6 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1 mmap.enablePathFinding = 1 -# -# mmap.ignoreMapIds -# Disable mmap pathfinding on the listed maps. -# List of map ids with delimiter ',' - -mmap.ignoreMapIds = "" - # # vmap.enableLOS # vmap.enableHeight -- cgit v1.2.3 From 234f0971200a0d75db61b163afc433270bce632b Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 1 Jan 2013 23:06:37 +0100 Subject: Core: Fix build --- src/server/game/Movement/FollowerRefManager.h | 1 - src/server/game/Movement/FollowerReference.cpp | 1 - src/server/game/Movement/FollowerReference.h | 1 - src/server/game/Movement/MotionMaster.h | 1 - src/server/game/Movement/MovementGenerator.h | 15 ++------ src/server/game/Movement/MovementGeneratorImpl.h | 1 - .../ConfusedMovementGenerator.cpp | 23 ++++++----- .../MovementGenerators/ConfusedMovementGenerator.h | 9 ++--- .../FleeingMovementGenerator.cpp | 25 ++++++------ .../MovementGenerators/FleeingMovementGenerator.h | 9 ++--- .../MovementGenerators/HomeMovementGenerator.cpp | 8 ++-- .../MovementGenerators/HomeMovementGenerator.h | 9 ++--- .../MovementGenerators/IdleMovementGenerator.cpp | 1 - .../MovementGenerators/IdleMovementGenerator.h | 1 - .../MovementGenerators/PointMovementGenerator.cpp | 24 ++++++------ .../MovementGenerators/PointMovementGenerator.h | 9 ++--- .../MovementGenerators/RandomMovementGenerator.cpp | 12 +++--- .../MovementGenerators/RandomMovementGenerator.h | 11 +++--- .../TargetedMovementGenerator.cpp | 44 +++++++++++----------- .../MovementGenerators/TargetedMovementGenerator.h | 14 +++---- .../WaypointMovementGenerator.cpp | 20 +++++----- .../MovementGenerators/WaypointMovementGenerator.h | 21 +++++------ src/server/game/Movement/Waypoints/Path.h | 1 - .../game/Movement/Waypoints/WaypointManager.h | 1 - 24 files changed, 119 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/FollowerRefManager.h b/src/server/game/Movement/FollowerRefManager.h index 5066804d60f..48292efc016 100644 --- a/src/server/game/Movement/FollowerRefManager.h +++ b/src/server/game/Movement/FollowerRefManager.h @@ -29,4 +29,3 @@ class FollowerRefManager : public RefManagerstopFollowing(); } - diff --git a/src/server/game/Movement/FollowerReference.h b/src/server/game/Movement/FollowerReference.h index 6a1a3719cb8..647662eb066 100644 --- a/src/server/game/Movement/FollowerReference.h +++ b/src/server/game/Movement/FollowerReference.h @@ -32,4 +32,3 @@ class FollowerReference : public Reference void sourceObjectDestroyLink(); }; #endif - diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index b0676e02f51..f908b096455 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -201,4 +201,3 @@ class MotionMaster //: private std::stack uint8 _cleanFlag; }; #endif - diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 43d03160a41..b84899d9b12 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -55,32 +55,26 @@ class MovementGeneratorMedium : public MovementGenerator void Initialize(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Initialize(static_cast(u)); + (static_cast(this))->DoInitialize(static_cast(u)); } void Finalize(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Finalize(static_cast(u)); + (static_cast(this))->DoFinalize(static_cast(u)); } void Reset(Unit* u) { //u->AssertIsType(); - (static_cast(this))->Reset(static_cast(u)); + (static_cast(this))->DoReset(static_cast(u)); } bool Update(Unit* u, uint32 time_diff) { //u->AssertIsType(); - return (static_cast(this))->Update(static_cast(u), time_diff); + return (static_cast(this))->DoUpdate(static_cast(u), time_diff); } - public: - // will not link if not overridden in the generators - void Initialize(T* u); - void Finalize(T* u); - void Reset(T* u); - bool Update(T* u, const uint32& time_diff); }; struct SelectableMovement : public FactoryHolder @@ -100,4 +94,3 @@ typedef FactoryHolder MovementGenerato typedef FactoryHolder::FactoryHolderRegistry MovementGeneratorRegistry; typedef FactoryHolder::FactoryHolderRepository MovementGeneratorRepository; #endif - diff --git a/src/server/game/Movement/MovementGeneratorImpl.h b/src/server/game/Movement/MovementGeneratorImpl.h index 725b309e3f1..8d9c170bce8 100644 --- a/src/server/game/Movement/MovementGeneratorImpl.h +++ b/src/server/game/Movement/MovementGeneratorImpl.h @@ -28,4 +28,3 @@ MovementGeneratorFactory::Create(void * /*data*/) const return (new MOVEMENT_GEN()); } #endif - diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 9ccb13c32ee..e1893d499ca 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -31,7 +31,7 @@ #endif template -void ConfusedMovementGenerator::Initialize(T* unit) +void ConfusedMovementGenerator::DoInitialize(T* unit) { unit->AddUnitState(UNIT_STATE_CONFUSED); unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); @@ -45,7 +45,7 @@ void ConfusedMovementGenerator::Initialize(T* unit) } template -void ConfusedMovementGenerator::Reset(T* unit) +void ConfusedMovementGenerator::DoReset(T* unit) { i_nextMoveTime.Reset(0); @@ -57,7 +57,7 @@ void ConfusedMovementGenerator::Reset(T* unit) } template -bool ConfusedMovementGenerator::Update(T* unit, uint32 diff) +bool ConfusedMovementGenerator::DoUpdate(T* unit, uint32 diff) { if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; @@ -105,7 +105,7 @@ bool ConfusedMovementGenerator::Update(T* unit, uint32 diff) } template<> -void ConfusedMovementGenerator::Finalize(Player* unit) +void ConfusedMovementGenerator::DoFinalize(Player* unit) { unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit->ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); @@ -113,7 +113,7 @@ void ConfusedMovementGenerator::Finalize(Player* unit) } template<> -void ConfusedMovementGenerator::Finalize(Creature* unit) +void ConfusedMovementGenerator::DoFinalize(Creature* unit) { unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit->ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); @@ -121,10 +121,9 @@ void ConfusedMovementGenerator::Finalize(Creature* unit) unit->SetTarget(unit->getVictim()->GetGUID()); } -template void ConfusedMovementGenerator::Initialize(Player*); -template void ConfusedMovementGenerator::Initialize(Creature*); -template void ConfusedMovementGenerator::Reset(Player*); -template void ConfusedMovementGenerator::Reset(Creature*); -template bool ConfusedMovementGenerator::Update(Player*, uint32 diff); -template bool ConfusedMovementGenerator::Update(Creature*, uint32 diff); - +template void ConfusedMovementGenerator::DoInitialize(Player*); +template void ConfusedMovementGenerator::DoInitialize(Creature*); +template void ConfusedMovementGenerator::DoReset(Player*); +template void ConfusedMovementGenerator::DoReset(Creature*); +template bool ConfusedMovementGenerator::DoUpdate(Player*, uint32 diff); +template bool ConfusedMovementGenerator::DoUpdate(Creature*, uint32 diff); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index 22d9bcc1a07..dd130961ed8 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -28,10 +28,10 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov public: explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {} - void Initialize(T*); - void Finalize(T*); - void Reset(T*); - bool Update(T*, uint32); + void DoInitialize(T*); + void DoFinalize(T*); + void DoReset(T*); + bool DoUpdate(T*, uint32); MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } private: @@ -39,4 +39,3 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov float i_x, i_y, i_z; }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 7f9c7fac7e7..14215d22ad1 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -102,7 +102,7 @@ void FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float } template -void FleeingMovementGenerator::Initialize(T* owner) +void FleeingMovementGenerator::DoInitialize(T* owner) { if (!owner) return; @@ -113,7 +113,7 @@ void FleeingMovementGenerator::Initialize(T* owner) } template<> -void FleeingMovementGenerator::Finalize(Player* owner) +void FleeingMovementGenerator::DoFinalize(Player* owner) { owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); owner->ClearUnitState(UNIT_STATE_FLEEING | UNIT_STATE_FLEEING_MOVE); @@ -121,7 +121,7 @@ void FleeingMovementGenerator::Finalize(Player* owner) } template<> -void FleeingMovementGenerator::Finalize(Creature* owner) +void FleeingMovementGenerator::DoFinalize(Creature* owner) { owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); owner->ClearUnitState(UNIT_STATE_FLEEING|UNIT_STATE_FLEEING_MOVE); @@ -130,13 +130,13 @@ void FleeingMovementGenerator::Finalize(Creature* owner) } template -void FleeingMovementGenerator::Reset(T* owner) +void FleeingMovementGenerator::DoReset(T* owner) { - Initialize(owner); + DoInitialize(owner); } template -bool FleeingMovementGenerator::Update(T* owner, uint32 time_diff) +bool FleeingMovementGenerator::DoUpdate(T* owner, uint32 time_diff) { if (!owner || !owner->isAlive()) return false; @@ -154,16 +154,16 @@ bool FleeingMovementGenerator::Update(T* owner, uint32 time_diff) return true; } -template void FleeingMovementGenerator::Initialize(Player*); -template void FleeingMovementGenerator::Initialize(Creature*); +template void FleeingMovementGenerator::DoInitialize(Player*); +template void FleeingMovementGenerator::DoInitialize(Creature*); template void FleeingMovementGenerator::_getPoint(Player*, float&, float&, float&); template void FleeingMovementGenerator::_getPoint(Creature*, float&, float&, float&); template void FleeingMovementGenerator::_setTargetLocation(Player*); template void FleeingMovementGenerator::_setTargetLocation(Creature*); -template void FleeingMovementGenerator::Reset(Player*); -template void FleeingMovementGenerator::Reset(Creature*); -template bool FleeingMovementGenerator::Update(Player*, uint32); -template bool FleeingMovementGenerator::Update(Creature*, uint32); +template void FleeingMovementGenerator::DoReset(Player*); +template void FleeingMovementGenerator::DoReset(Creature*); +template bool FleeingMovementGenerator::DoUpdate(Player*, uint32); +template bool FleeingMovementGenerator::DoUpdate(Creature*, uint32); void TimedFleeingMovementGenerator::Finalize(Unit* owner) { @@ -198,4 +198,3 @@ bool TimedFleeingMovementGenerator::Update(Unit* owner, uint32 time_diff) // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly return MovementGeneratorMedium< Creature, FleeingMovementGenerator >::Update(owner, time_diff); } - diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index 05c3916ea8a..245c53513f3 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -27,10 +27,10 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem public: FleeingMovementGenerator(uint64 fright) : i_frightGUID(fright), i_nextCheckTime(0) {} - void Initialize(T*); - void Finalize(T*); - void Reset(T*); - bool Update(T*, uint32); + void DoInitialize(T*); + void DoFinalize(T*); + void DoReset(T*); + bool DoUpdate(T*, uint32); MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; } @@ -58,4 +58,3 @@ class TimedFleeingMovementGenerator : public FleeingMovementGenerator }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 78c1f80005c..f52120b6999 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -23,12 +23,12 @@ #include "MoveSplineInit.h" #include "MoveSpline.h" -void HomeMovementGenerator::Initialize(Creature* owner) +void HomeMovementGenerator::DoInitialize(Creature* owner) { _setTargetLocation(owner); } -void HomeMovementGenerator::Finalize(Creature* owner) +void HomeMovementGenerator::DoFinalize(Creature* owner) { if (arrived) { @@ -39,7 +39,7 @@ void HomeMovementGenerator::Finalize(Creature* owner) } } -void HomeMovementGenerator::Reset(Creature*) +void HomeMovementGenerator::DoReset(Creature*) { } @@ -64,7 +64,7 @@ void HomeMovementGenerator::_setTargetLocation(Creature* owner) owner->ClearUnitState(UNIT_STATE_ALL_STATE & ~UNIT_STATE_EVADE); } -bool HomeMovementGenerator::Update(Creature* owner, const uint32 /*time_diff*/) +bool HomeMovementGenerator::DoUpdate(Creature* owner, const uint32 /*time_diff*/) { arrived = owner->movespline->Finalized(); return !arrived; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index dfbea60d353..5217f14f75a 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -34,10 +34,10 @@ class HomeMovementGenerator : public MovementGeneratorMedium< Creature HomeMovementGenerator() : arrived(false) {} ~HomeMovementGenerator() {} - void Initialize(Creature*); - void Finalize(Creature*); - void Reset(Creature*); - bool Update(Creature*, const uint32); + void DoInitialize(Creature*); + void DoFinalize(Creature*); + void DoReset(Creature*); + bool DoUpdate(Creature*, const uint32); MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; } private: @@ -45,4 +45,3 @@ class HomeMovementGenerator : public MovementGeneratorMedium< Creature bool arrived; }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp index b33cddc6f6d..080ae1b5b89 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp @@ -103,4 +103,3 @@ void AssistanceDistractMovementGenerator::Finalize(Unit* unit) unit->ClearUnitState(UNIT_STATE_DISTRACTED); unit->ToCreature()->SetReactState(REACT_AGGRESSIVE); } - diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index 4a2a5e35d22..7be70990b22 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -76,4 +76,3 @@ class AssistanceDistractMovementGenerator : public DistractMovementGenerator }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 5d70b1aac3a..e7b61e30ea8 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -27,7 +27,7 @@ //----- Point Movement Generator template -void PointMovementGenerator::Initialize(T* unit) +void PointMovementGenerator::DoInitialize(T* unit) { if (!unit->IsStopped()) unit->StopMoving(); @@ -45,7 +45,7 @@ void PointMovementGenerator::Initialize(T* unit) } template -bool PointMovementGenerator::Update(T* unit, uint32 /*diff*/) +bool PointMovementGenerator::DoUpdate(T* unit, uint32 /*diff*/) { if (!unit) return false; @@ -72,7 +72,7 @@ bool PointMovementGenerator::Update(T* unit, uint32 /*diff*/) } template -void PointMovementGenerator::Finalize(T* unit) +void PointMovementGenerator::DoFinalize(T* unit) { if (unit->HasUnitState(UNIT_STATE_CHARGING)) unit->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); @@ -82,7 +82,7 @@ void PointMovementGenerator::Finalize(T* unit) } template -void PointMovementGenerator::Reset(T* unit) +void PointMovementGenerator::DoReset(T* unit) { if (!unit->IsStopped()) unit->StopMoving(); @@ -101,14 +101,14 @@ template <> void PointMovementGenerator::MovementInform(Creature* unit unit->AI()->MovementInform(POINT_MOTION_TYPE, id); } -template void PointMovementGenerator::Initialize(Player*); -template void PointMovementGenerator::Initialize(Creature*); -template void PointMovementGenerator::Finalize(Player*); -template void PointMovementGenerator::Finalize(Creature*); -template void PointMovementGenerator::Reset(Player*); -template void PointMovementGenerator::Reset(Creature*); -template bool PointMovementGenerator::Update(Player*, uint32); -template bool PointMovementGenerator::Update(Creature*, uint32); +template void PointMovementGenerator::DoInitialize(Player*); +template void PointMovementGenerator::DoInitialize(Creature*); +template void PointMovementGenerator::DoFinalize(Player*); +template void PointMovementGenerator::DoFinalize(Creature*); +template void PointMovementGenerator::DoReset(Player*); +template void PointMovementGenerator::DoReset(Creature*); +template bool PointMovementGenerator::DoUpdate(Player*, uint32); +template bool PointMovementGenerator::DoUpdate(Creature*, uint32); void AssistanceMovementGenerator::Finalize(Unit* unit) { diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index c26ff94c3a4..592fc7bc517 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -29,10 +29,10 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed), i_recalculateSpeed(false) {} - void Initialize(T*); - void Finalize(T*); - void Reset(T*); - bool Update(T*, uint32); + void DoInitialize(T*); + void DoFinalize(T*); + void DoReset(T*); + bool DoUpdate(T*, uint32); void MovementInform(T*); @@ -74,4 +74,3 @@ class EffectMovementGenerator : public MovementGenerator }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index a9d3c404a87..5b8bc6552d3 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -114,7 +114,7 @@ void RandomMovementGenerator::_setRandomLocation(Creature* creature) } template<> -void RandomMovementGenerator::Initialize(Creature* creature) +void RandomMovementGenerator::DoInitialize(Creature* creature) { if (!creature->isAlive()) return; @@ -127,20 +127,20 @@ void RandomMovementGenerator::Initialize(Creature* creature) } template<> -void RandomMovementGenerator::Reset(Creature* creature) +void RandomMovementGenerator::DoReset(Creature* creature) { - Initialize(creature); + DoInitialize(creature); } template<> -void RandomMovementGenerator::Finalize(Creature* creature) +void RandomMovementGenerator::DoFinalize(Creature* creature) { creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); creature->SetWalk(false); } template<> -bool RandomMovementGenerator::Update(Creature* creature, const uint32 diff) +bool RandomMovementGenerator::DoUpdate(Creature* creature, const uint32 diff) { if (creature->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) { @@ -159,7 +159,7 @@ bool RandomMovementGenerator::Update(Creature* creature, const uint32 } template<> -bool RandomMovementGenerator::GetResetPosition(Creature* creature, float& x, float& y, float& z) +bool RandomMovementGenerator::GetResetPos(Creature* creature, float& x, float& y, float& z) { float radius; creature->GetRespawnPosition(x, y, z, NULL, &radius); diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h index ca370de6ac3..80379dee632 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h @@ -28,11 +28,11 @@ class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovemen RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) {} void _setRandomLocation(T*); - void Initialize(T*); - void Finalize(T*); - void Reset(T*); - bool Update(T*, const uint32); - bool GetResetPosition(T*, float& x, float& y, float& z); + void DoInitialize(T*); + void DoFinalize(T*); + void DoReset(T*); + bool DoUpdate(T*, const uint32); + bool GetResetPos(T*, float& x, float& y, float& z); MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; } private: TimeTrackerSmall i_nextMoveTime; @@ -41,4 +41,3 @@ class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovemen float wander_distance; }; #endif - diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 88eacccd0aa..46db6b034c4 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -116,7 +116,7 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool upd } template -bool TargetedMovementGeneratorMedium::Update(T* owner, uint32 time_diff) +bool TargetedMovementGeneratorMedium::DoUpdate(T* owner, uint32 time_diff) { if (!i_target.isValid() || !i_target->IsInWorld()) return false; @@ -188,14 +188,14 @@ void ChaseMovementGenerator::_reachTarget(T* owner) } template<> -void ChaseMovementGenerator::Initialize(Player* owner) +void ChaseMovementGenerator::DoInitialize(Player* owner) { owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); _setTargetLocation(owner, true); } template<> -void ChaseMovementGenerator::Initialize(Creature* owner) +void ChaseMovementGenerator::DoInitialize(Creature* owner) { owner->SetWalk(false); owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); @@ -203,15 +203,15 @@ void ChaseMovementGenerator::Initialize(Creature* owner) } template -void ChaseMovementGenerator::Finalize(T* owner) +void ChaseMovementGenerator::DoFinalize(T* owner) { owner->ClearUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); } template -void ChaseMovementGenerator::Reset(T* owner) +void ChaseMovementGenerator::DoReset(T* owner) { - Initialize(owner); + DoInitialize(owner); } template @@ -259,7 +259,7 @@ void FollowMovementGenerator::_updateSpeed(Creature* u) } template<> -void FollowMovementGenerator::Initialize(Player* owner) +void FollowMovementGenerator::DoInitialize(Player* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); @@ -267,7 +267,7 @@ void FollowMovementGenerator::Initialize(Player* owner) } template<> -void FollowMovementGenerator::Initialize(Creature* owner) +void FollowMovementGenerator::DoInitialize(Creature* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); @@ -275,14 +275,14 @@ void FollowMovementGenerator::Initialize(Creature* owner) } template -void FollowMovementGenerator::Finalize(T* owner) +void FollowMovementGenerator::DoFinalize(T* owner) { owner->ClearUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); } template -void FollowMovementGenerator::Reset(T* owner) +void FollowMovementGenerator::DoReset(T* owner) { Initialize(owner); } @@ -305,21 +305,21 @@ template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*, bool); template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); -template bool TargetedMovementGeneratorMedium >::Update(Player*, uint32); -template bool TargetedMovementGeneratorMedium >::Update(Player*, uint32); -template bool TargetedMovementGeneratorMedium >::Update(Creature*, uint32); -template bool TargetedMovementGeneratorMedium >::Update(Creature*, uint32); +template bool TargetedMovementGeneratorMedium >::DoUpdate(Player*, uint32); +template bool TargetedMovementGeneratorMedium >::DoUpdate(Player*, uint32); +template bool TargetedMovementGeneratorMedium >::DoUpdate(Creature*, uint32); +template bool TargetedMovementGeneratorMedium >::DoUpdate(Creature*, uint32); template void ChaseMovementGenerator::_reachTarget(Player*); template void ChaseMovementGenerator::_reachTarget(Creature*); -template void ChaseMovementGenerator::Finalize(Player*); -template void ChaseMovementGenerator::Finalize(Creature*); -template void ChaseMovementGenerator::Reset(Player*); -template void ChaseMovementGenerator::Reset(Creature*); +template void ChaseMovementGenerator::DoFinalize(Player*); +template void ChaseMovementGenerator::DoFinalize(Creature*); +template void ChaseMovementGenerator::DoReset(Player*); +template void ChaseMovementGenerator::DoReset(Creature*); template void ChaseMovementGenerator::MovementInform(Player*); -template void FollowMovementGenerator::Finalize(Player*); -template void FollowMovementGenerator::Finalize(Creature*); -template void FollowMovementGenerator::Reset(Player*); -template void FollowMovementGenerator::Reset(Creature*); +template void FollowMovementGenerator::DoFinalize(Player*); +template void FollowMovementGenerator::DoFinalize(Creature*); +template void FollowMovementGenerator::DoReset(Player*); +template void FollowMovementGenerator::DoReset(Creature*); template void FollowMovementGenerator::MovementInform(Player*); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 987baa91133..6b47821bbaa 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -47,7 +47,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, ~TargetedMovementGeneratorMedium() { delete i_path; } public: - bool Update(T*, uint32); + bool DoUpdate(T*, uint32); Unit* GetTarget() const { return i_target.getTarget(); } void unitSpeedChanged() { i_recalculateTravel = true; } @@ -75,9 +75,9 @@ class ChaseMovementGenerator : public TargetedMovementGeneratorMediumClearUnitState(UNIT_STATE_CHASE_MOVE); } @@ -99,9 +99,9 @@ class FollowMovementGenerator : public TargetedMovementGeneratorMediumClearUnitState(UNIT_STATE_FOLLOW_MOVE); } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index d3b63ed6331..ffc4afebf2a 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -48,19 +48,19 @@ void WaypointMovementGenerator::LoadPath(Creature* creature) StartMoveNow(creature); } -void WaypointMovementGenerator::Initialize(Creature* creature) +void WaypointMovementGenerator::DoInitialize(Creature* creature) { LoadPath(creature); creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); } -void WaypointMovementGenerator::Finalize(Creature* creature) +void WaypointMovementGenerator::DoFinalize(Creature* creature) { creature->ClearUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); creature->SetWalk(false); } -void WaypointMovementGenerator::Reset(Creature* creature) +void WaypointMovementGenerator::DoReset(Creature* creature) { creature->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); StartMoveNow(creature); @@ -130,7 +130,7 @@ bool WaypointMovementGenerator::StartMove(Creature* creature) return true; } -bool WaypointMovementGenerator::Update(Creature* creature, uint32 diff) +bool WaypointMovementGenerator::DoUpdate(Creature* creature, uint32 diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff @@ -167,7 +167,7 @@ void WaypointMovementGenerator::MovementInform(Creature* creature) creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); } -bool WaypointMovementGenerator::GetResetPosition(Creature*, float& x, float& y, float& z) +bool WaypointMovementGenerator::GetResetPos(Creature*, float& x, float& y, float& z) { // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) @@ -196,13 +196,13 @@ uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const return i_path->size(); } -void FlightPathMovementGenerator::Initialize(Player* player) +void FlightPathMovementGenerator::DoInitialize(Player* player) { Reset(player); InitEndGridInfo(); } -void FlightPathMovementGenerator::Finalize(Player* player) +void FlightPathMovementGenerator::DoFinalize(Player* player) { // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack) player->ClearUnitState(UNIT_STATE_IN_FLIGHT); @@ -222,7 +222,7 @@ void FlightPathMovementGenerator::Finalize(Player* player) #define PLAYER_FLIGHT_SPEED 32.0f -void FlightPathMovementGenerator::Reset(Player* player) +void FlightPathMovementGenerator::DoReset(Player* player) { player->getHostileRefManager().setOnlineOfflineState(false); player->AddUnitState(UNIT_STATE_IN_FLIGHT); @@ -241,7 +241,7 @@ void FlightPathMovementGenerator::Reset(Player* player) init.Launch(); } -bool FlightPathMovementGenerator::Update(Player* player, uint32 /*diff*/) +bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/) { uint32 pointId = (uint32)player->movespline->currentPathIdx(); if (pointId > i_currentNode) @@ -288,7 +288,7 @@ void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry } } -bool FlightPathMovementGenerator::GetResetPosition(Player*, float& x, float& y, float& z) +bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z) { const TaxiPathNodeEntry& node = (*i_path)[i_currentNode]; x = node.x; y = node.y; z = node.z; diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index bf3f6f4cae3..5f468ffc3a4 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -65,10 +65,10 @@ class WaypointMovementGenerator : public MovementGeneratorMedium< Crea WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) : i_nextMoveTime(0), m_isArrivalDone(false), path_id(_path_id), repeating(_repeating) {} ~WaypointMovementGenerator() { i_path = NULL; } - void Initialize(Creature*); - void Finalize(Creature*); - void Reset(Creature*); - bool Update(Creature*, uint32 diff); + void DoInitialize(Creature*); + void DoFinalize(Creature*); + void DoReset(Creature*); + bool DoUpdate(Creature*, uint32 diff); void MovementInform(Creature*); @@ -77,7 +77,7 @@ class WaypointMovementGenerator : public MovementGeneratorMedium< Crea // now path movement implmementation void LoadPath(Creature*); - bool GetResetPosition(Creature*, float& x, float& y, float& z); + bool GetResetPos(Creature*, float& x, float& y, float& z); private: @@ -118,10 +118,10 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig i_path = &pathnodes; i_currentNode = startNode; } - void Initialize(Player*); - void Reset(Player*); - void Finalize(Player*); - bool Update(Player*, uint32); + void DoInitialize(Player*); + void DoReset(Player*); + void DoFinalize(Player*); + bool DoUpdate(Player*, uint32); MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } TaxiPathNodeList const& GetPath() { return *i_path; } @@ -131,7 +131,7 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig void SkipCurrentNode() { ++i_currentNode; } void DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure); - bool GetResetPosition(Player*, float& x, float& y, float& z); + bool GetResetPos(Player*, float& x, float& y, float& z); void InitEndGridInfo(); void PreloadEndGrid(); @@ -143,4 +143,3 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig uint32 _preloadTargetNode; //! node index where preloading starts }; #endif - diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h index 038958593fb..f86b62c8be8 100644 --- a/src/server/game/Movement/Waypoints/Path.h +++ b/src/server/game/Movement/Waypoints/Path.h @@ -98,4 +98,3 @@ class Path typedef Path SimplePath; #endif - diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index df20c513c90..3417b44ef09 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -68,4 +68,3 @@ class WaypointMgr #define sWaypointMgr ACE_Singleton::instance() #endif - -- cgit v1.2.3 From 05efdaf39349f057eabf58252532dff76511e7ef Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 2 Jan 2013 13:58:36 +0100 Subject: Core: Fix non pch build --- src/server/shared/Memory.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/server/shared/Memory.h b/src/server/shared/Memory.h index ac697f7a1af..25533638915 100644 --- a/src/server/shared/Memory.h +++ b/src/server/shared/Memory.h @@ -3,6 +3,8 @@ #ifndef _MEMORY_H #define _MEMORY_H +#include "DetourAlloc.h" + // memory management inline void* dtCustomAlloc(int size, dtAllocHint /*hint*/) { -- cgit v1.2.3 From 20ab789fe76b2b4e6c7dce006024aaba1b2a548b Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 8 Jan 2013 16:26:45 +0100 Subject: Core: Fix build with Debian 7.0 Closes #8882 --- .../game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 9d60fa11a2f..d03edeb9bab 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -284,7 +284,7 @@ void FollowMovementGenerator::DoFinalize(T* owner) template void FollowMovementGenerator::DoReset(T* owner) { - Initialize(owner); + DoInitialize(owner); } template -- cgit v1.2.3 From 5f15600e7a26170f0aacc77e9417df61db45a992 Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 9 Jan 2013 13:13:39 +0100 Subject: Core/Build: Fix linking and sooo many compile warnings --- src/server/collision/Management/MMapManager.cpp | 14 +- src/server/collision/Models/ModelInstance.h | 2 +- src/tools/map_extractor/adt.cpp | 21 +- src/tools/map_extractor/loadlib.cpp | 4 +- src/tools/map_extractor/loadlib/loadlib.h | 6 + src/tools/map_extractor/wdt.cpp | 12 +- src/tools/mesh_extractor/ADT.cpp | 4 +- src/tools/mesh_extractor/CMakeLists.txt | 3 +- src/tools/mesh_extractor/Cache.h | 4 +- src/tools/mesh_extractor/Chunk.cpp | 10 +- src/tools/mesh_extractor/ChunkedData.cpp | 3 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 4 +- src/tools/mesh_extractor/ContinentBuilder.h | 8 +- src/tools/mesh_extractor/DBC.cpp | 22 +- src/tools/mesh_extractor/DoodadHandler.cpp | 6 +- src/tools/mesh_extractor/DoodadHandler.h | 14 +- src/tools/mesh_extractor/LiquidHandler.cpp | 10 +- src/tools/mesh_extractor/MapChunk.cpp | 3 +- src/tools/mesh_extractor/MeshExtractor.cpp | 36 ++- src/tools/mesh_extractor/Model.cpp | 9 +- src/tools/mesh_extractor/TileBuilder.cpp | 5 +- src/tools/mesh_extractor/Utils.cpp | 354 ++++++++++++++---------- src/tools/mesh_extractor/Utils.h | 4 +- src/tools/mesh_extractor/WDT.cpp | 11 +- src/tools/mesh_extractor/WorldModelGroup.cpp | 22 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 20 +- src/tools/mmaps_generator/CMakeLists.txt | 2 +- src/tools/mmaps_generator/IntermediateValues.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 45 +-- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 92 +++--- src/tools/mmaps_generator/TerrainBuilder.h | 1 - src/tools/mmaps_generator/VMapExtensions.cpp | 2 +- src/tools/vmap4_extractor/adtfile.cpp | 3 +- src/tools/vmap4_extractor/model.cpp | 4 +- src/tools/vmap4_extractor/vmapexport.cpp | 3 +- src/tools/vmap4_extractor/wmo.cpp | 4 +- 37 files changed, 468 insertions(+), 303 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index c7dea358d92..1b6cf5c0260 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -52,8 +52,14 @@ namespace MMAP } dtNavMeshParams params; - fread(¶ms, sizeof(dtNavMeshParams), 1, file); + int count = fread(¶ms, sizeof(dtNavMeshParams), 1, file); fclose(file); + if (count != 1) + { + sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName); + delete [] fileName; + return false; + } dtNavMesh* mesh = dtAllocNavMesh(); ASSERT(mesh); @@ -82,7 +88,7 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles if (!loadMapData(mapId)) @@ -114,9 +120,7 @@ namespace MMAP // read header MmapTileHeader fileHeader; - fread(&fileHeader, sizeof(MmapTileHeader), 1, file); - - if (fileHeader.mmapMagic != MMAP_MAGIC) + if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC) { sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); return false; diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 6d1b7c68bd5..f26089bb46c 100644 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -75,7 +75,7 @@ namespace VMAP float iInvScale; WorldModel* iModel; public: - WorldModel* const getWorldModel(); + WorldModel* getWorldModel(); }; } // namespace VMAP diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index fde70681113..505813c4bd0 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -6,6 +6,13 @@ int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; +u_map_fcc MHDRMagic = { {'M','H','D','R'} }; +u_map_fcc MCINMagic = { {'M','C','I','N'} }; +u_map_fcc MH20Magic = { {'M','H','2','0'} }; +u_map_fcc MCNKMagic = { {'M','C','N','K'} }; +u_map_fcc MCVTMagic = { {'M','C','V','T'} }; +u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; + bool isHole(int holes, int i, int j) { int testi = i / 2; @@ -53,7 +60,7 @@ bool ADT_file::prepareLoadedData() bool adt_MHDR::prepareLoadedData() { - if (fcc != 'MHDR') + if (fcc != MHDRMagic.fcc) return false; if (size!=sizeof(adt_MHDR)-8) @@ -72,7 +79,7 @@ bool adt_MHDR::prepareLoadedData() bool adt_MCIN::prepareLoadedData() { - if (fcc != 'MCIN') + if (fcc != MCINMagic.fcc) return false; // Check cells data @@ -86,7 +93,7 @@ bool adt_MCIN::prepareLoadedData() bool adt_MH2O::prepareLoadedData() { - if (fcc != 'MH2O') + if (fcc != MH20Magic.fcc) return false; // Check liquid data @@ -98,7 +105,7 @@ bool adt_MH2O::prepareLoadedData() bool adt_MCNK::prepareLoadedData() { - if (fcc != 'MCNK') + if (fcc != MCNKMagic.fcc) return false; // Check height map @@ -113,7 +120,7 @@ bool adt_MCNK::prepareLoadedData() bool adt_MCVT::prepareLoadedData() { - if (fcc != 'MCVT') + if (fcc != MCVTMagic.fcc) return false; if (size != sizeof(adt_MCVT)-8) @@ -124,8 +131,8 @@ bool adt_MCVT::prepareLoadedData() bool adt_MCLQ::prepareLoadedData() { - if (fcc != 'MCLQ') + if (fcc != MCLQMagic.fcc) return false; return true; -} \ No newline at end of file +} diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 465eb04083f..d1ea40110de 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -6,6 +6,8 @@ class MPQFile; +u_map_fcc MverMagic = { {'M','V','E','R'} }; + FileLoader::FileLoader() { data = 0; @@ -49,7 +51,7 @@ bool FileLoader::prepareLoadedData() { // Check version version = (file_MVER *) data; - if (version->fcc != 'MVER') + if (version->fcc != MverMagic.fcc) return false; if (version->ver != FILE_FORMAT_VERSION) return false; diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index bf6c0706d46..f32f46c63b9 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -29,6 +29,12 @@ typedef uint8_t uint8; #define FILE_FORMAT_VERSION 18 +union u_map_fcc +{ + char fcc_txt[4]; + uint32 fcc; +}; + // // File version chunk // diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index dedefbb64e5..90a07eafab3 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -2,23 +2,27 @@ #include "wdt.h" +u_map_fcc MWMOMagic = { {'M', 'W', 'M', 'O'} }; +u_map_fcc MPHDMagic = { {'M', 'P', 'H', 'D'} }; +u_map_fcc MAINMagic = { {'M', 'A', 'I', 'N'} }; + bool wdt_MWMO::prepareLoadedData() { - if (fcc != 'MWMO') + if (fcc != MWMOMagic.fcc) return false; return true; } bool wdt_MPHD::prepareLoadedData() { - if (fcc != 'MPHD') + if (fcc != MPHDMagic.fcc) return false; return true; } bool wdt_MAIN::prepareLoadedData() { - if (fcc != 'MAIN') + if (fcc != MAINMagic.fcc) return false; return true; } @@ -59,4 +63,4 @@ bool WDT_file::prepareLoadedData() if (!wmo->prepareLoadedData()) return false; return true; -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 8d7dce9ae11..c2ac19d5be0 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -3,7 +3,8 @@ #include "LiquidHandler.h" #include "WorldModelHandler.h" -ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false) +ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), HasObjectData(false), + _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL) { Data = new ChunkedData(file); ObjectData = new ChunkedData(Utils::Replace(file, ".adt", "_obj0.adt")); @@ -31,7 +32,6 @@ void ADT::Read() { Header.Read(Data->GetChunkByName("MHDR")->GetStream()); MapChunks.reserve(16 * 16); - int mapChunkIndex = 0; for (std::vector::iterator itr = Data->Chunks.begin(); itr != Data->Chunks.end(); ++itr) if ((*itr)->Name == "MCNK") diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 8ef48a90742..29c571d9301 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -26,6 +26,7 @@ if( UNIX ) ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -77,4 +78,4 @@ if( UNIX ) install(TARGETS MeshExtractor DESTINATION bin) elseif( WIN32 ) install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() \ No newline at end of file +endif() diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 90e2c138376..34293b14b54 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -14,7 +14,7 @@ class GenericCache public: GenericCache() {} - static const int32 FlushLimit = 1000; + static const uint32 FlushLimit = 1000; void Insert(K key, T* val) { @@ -59,4 +59,4 @@ public: }; extern CacheClass* Cache; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index 2f521f1badd..9f2898a46e0 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -12,12 +12,12 @@ int32 Chunk::FindSubChunkOffset(std::string name) uint32 matched = 0; while (uint32(ftell(stream)) < Utils::Size(stream)) { - char b; - fread(&b, sizeof(char), 1, stream); - if (b == name[matched]) - ++matched; - else + char b = 0; + if (fread(&b, sizeof(char), 1, stream) != 1 || b != name[matched]) matched = 0; + else + ++matched; + if (matched == 4) return ftell(stream) - 4; } diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index 4d609d8f6b2..e0db12a6be7 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -36,7 +36,8 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) // Utils::Reverse(nameBytes); name = std::string(name.rbegin(), name.rend()); uint32 length; - fread(&length, sizeof(uint32), 1, Stream); + if (fread(&length, sizeof(uint32), 1, Stream) != 1) + continue; calcOffset += 8; Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); calcOffset += length; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 013c0ff256a..9b5c9f9c77b 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -16,7 +16,7 @@ private: dtNavMeshParams Params; ContinentBuilder* cBuilder; public: - BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params), cBuilder(_cBuilder) {} + BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : debug(deb), Params(params), cBuilder(_cBuilder), Free(true) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -113,7 +113,7 @@ void ContinentBuilder::Build(bool debug) std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, debug, params)); - printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); + printf("Map %s ( %i ) has %u tiles. Building them with %i threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 4c16fa0727e..3d7b879879e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,7 +7,11 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : + Continent(continent), TileMap(wdt), MapId(mapId), + NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) + {} + void Build(bool debug); void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); void CalculateTileBounds(); @@ -23,4 +27,4 @@ private: int tileXMax; int tileYMax; }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index c50e02014da..5c54d975487 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -2,16 +2,19 @@ #include "DBC.h" #include "Common.h" -DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) +DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { char magic[5]; - fread(&magic, sizeof(char), 4, stream); + uint count = 0; + count += fread(&magic, sizeof(char), 4, stream); magic[4] = '\0'; - fread(&RecordCount, sizeof(uint32), 1, stream); + count += fread(&RecordCount, sizeof(uint32), 1, stream); Records.reserve(RecordCount); - fread(&Fields, sizeof(uint32), 1, stream); - fread(&RecordSize, sizeof(uint32), 1, stream); - fread(&StringBlockSize, sizeof(uint32), 1, stream); + count += fread(&Fields, sizeof(uint32), 1, stream); + count += fread(&RecordSize, sizeof(uint32), 1, stream); + count += fread(&StringBlockSize, sizeof(uint32), 1, stream); + if (count != 8) + printf("DBC::DBC: Failed to read some data expected 8, read %u\n", count); for (int i = 0; i < RecordCount; i++) { @@ -26,13 +29,16 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) break; } uint32 tmp; - fread(&tmp, sizeof(uint32), 1, stream); + if (fread(&tmp, sizeof(uint32), 1, stream) != 1) + printf("DBC::DBC: Failed to read some data expected 1, read 0\n"); rec->Values.push_back(tmp); size += 4; } } StringBlock = new uint8[StringBlockSize]; - fread(StringBlock, sizeof(uint8), StringBlockSize, stream); + count = fread(StringBlock, sizeof(uint8), StringBlockSize, stream); + if (count != StringBlockSize) + printf("DBC::DBC: Failed to read some data expected %u, read %u\n", StringBlockSize, count); } std::string DBC::GetStringByOffset( int offset ) diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 4e8028b3dff..56c2a7986f8 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -30,7 +30,8 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) for (uint32 i = 0; i < refCount; i++) { int32 index; - fread(&index, sizeof(int32), 1, stream); + if (int count = fread(&index, sizeof(int32), 1, stream) != 1) + printf("DoodadHandler::ProcessInternal: Failed to read some data expected 1, read %d\n", count); if (index < 0 || uint32(index) >= _definitions->size()) continue; DoodadDefinition doodad = (*_definitions)[index]; @@ -81,7 +82,8 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) FILE* idStream = id->GetStream(); fseek(idStream, i * 4, SEEK_CUR); uint32 offset; - fread(&offset, sizeof(uint32), 1, idStream); + if (fread(&offset, sizeof(uint32), 1, idStream) != 1) + printf("DoodadHandler::ReadDoodadPaths: Failed to read some data expected 1, read 0\n"); FILE* dataStream = data->GetStream(); fseek(dataStream, offset + data->Offset, SEEK_SET); _paths->push_back(Utils::ReadString(dataStream)); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index a212b032d1d..981834ec7ac 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -19,12 +19,16 @@ public: void Read(FILE* stream) { - fread(&MmidIndex, sizeof(uint32), 1, stream); - fread(&UniqueId, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&MmidIndex, sizeof(uint32), 1, stream); + count += fread(&UniqueId, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); Rotation = Vector3::Read(stream); - fread(&DecimalScale, sizeof(uint16), 1, stream); - fread(&Flags, sizeof(uint16), 1, stream); + count += fread(&DecimalScale, sizeof(uint16), 1, stream); + count += fread(&Flags, sizeof(uint16), 1, stream); + if (count != 4) + printf("DoodadDefinition::Read: Failed to read some data expected 4, read %d\n", count); } }; @@ -50,4 +54,4 @@ private: std::vector* _definitions; std::vector* _paths; }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 7844130ab34..285ea1a5b74 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -50,17 +50,17 @@ void LiquidHandler::HandleNewLiquid() fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); uint32 size = ceil(information.Width * information.Height / 8.0f); uint8* altMask = new uint8[size]; - fread(altMask, sizeof(uint8), size, stream); - - for (uint32 mi = 0; mi < size; mi++) - renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; + if (fread(altMask, sizeof(uint8), size, stream) == size) + for (uint32 mi = 0; mi < size; mi++) + renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; delete[] altMask; } fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) - fread(&heights[x][y], sizeof(float), 1, stream); + if (fread(&heights[x][y], sizeof(float), 1, stream) != 1) + return; } else { diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 67f4061035e..8fe40773d43 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -58,7 +58,8 @@ void MapChunk::GenerateVertices( FILE* stream ) for (int i = 0; i < values; i++) { float tmp; - fread(&tmp, sizeof(float), 1, stream); + if (fread(&tmp, sizeof(float), 1, stream) != 1) + printf("MapChunk::GenerateVertices: Failed to read some data expected 1, read 0\n"); Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); if (values == 8) vert.y -= Constants::UnitSize * 0.5f; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 7379ba87117..b164ff5861d 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -59,7 +59,7 @@ void ExtractDBCs() { printf("Extracting DBCs for locale %s\n", MPQManager::Languages[*itr]); std::string path = baseDBCPath; - if (*itr != MPQHandler->BaseLocale) + if (*itr != uint32(MPQHandler->BaseLocale)) { path += std::string(MPQManager::Languages[*itr]) + "/"; Utils::CreateDir(path); @@ -198,7 +198,6 @@ void ExtractGameobjectModels() fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); - uint32 i = 0; for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) { fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output); @@ -261,7 +260,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) mapList.insert(atoi(*itr)); - printf("Extracting only provided list of maps (%u).\n", mapList.size()); + printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); } else if (strcmp(argv[i], "--debug") == 0) { @@ -314,18 +313,27 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) { FILE* f = fopen(tile, "rb"); MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, f); + + if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1) + return; + uint8* nav = new uint8[header.size]; - fread(nav, header.size, 1, f); + if (fread(nav, header.size, 1, f) != 1) + return; - dtStatus res = navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); + navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); fclose(f); } int main(int argc, char* argv[]) { - system("pause"); + if (!system("pause")) + { + printf("main: Error in system call to pause\n"); + return -1; + } + uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; @@ -383,8 +391,13 @@ int main(int argc, char* argv[]) FILE* mmap = fopen(".mmap", "rb"); dtNavMeshParams params; - fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); + int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); + if (count != 1) + { + printf("main: Error reading from .mmap\n"); + return 0; + } dtNavMesh* navMesh = new dtNavMesh(); dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); @@ -401,10 +414,9 @@ int main(int argc, char* argv[]) float nearestPt[3]; - dtStatus status = navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); - status = navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); - // if ( !m_startRef || !m_endRef ) { std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; @@ -415,4 +427,4 @@ int main(int argc, char* argv[]) } return 0; -} \ No newline at end of file +} diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index 10fde0ebc2d..77b1adbeaa0 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -47,9 +47,12 @@ void Model::ReadBoundingTriangles( FILE* stream ) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; - fread(&tri.V0, sizeof(uint16), 1, stream); - fread(&tri.V1, sizeof(uint16), 1, stream); - fread(&tri.V2, sizeof(uint16), 1, stream); + int count = 0; + count += fread(&tri.V0, sizeof(uint16), 1, stream); + count += fread(&tri.V1, sizeof(uint16), 1, stream); + count += fread(&tri.V2, sizeof(uint16), 1, stream); + if (count != 3) + printf("Model::ReadBoundingTriangles: Error reading data, expected 3, read %d\n", count); Triangles.push_back(tri); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 2a02bc50cd4..4a14cbbd51d 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -12,7 +12,8 @@ #include "ace/Synch.h" -TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), cBuilder(_cBuilder) +TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : + World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) { /* Test, non-working values @@ -62,7 +63,7 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, Context = new rcContext; } -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams ) +void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& /*navMeshParams*/ ) { bmin = new float[3]; bmax = new float[3]; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 3639cb88acf..119ac94f94f 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -53,8 +53,7 @@ std::string Utils::ReadString( FILE* file ) while (true) { char b; - fread(&b, sizeof(char), 1, file); - if (b == 0) + if (fread(&b, sizeof(char), 1, file) != 1 || b == 0) break; ret[i++] = b; } @@ -155,7 +154,7 @@ Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) std::string Utils::GetPathBase( std::string path ) { - int lastIndex = path.find_last_of("."); + size_t lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) return path.substr(0, lastIndex); return path; @@ -164,11 +163,12 @@ std::string Utils::GetPathBase( std::string path ) Vector3 Vector3::Read( FILE* file ) { Vector3 ret; - fread(&ret, sizeof(Vector3), 1, file); + if (fread(&ret, sizeof(Vector3), 1, file) != 1) + printf("Vector3::Read: Failed to read some data expected 1, read 0\n"); return ret; } -Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y) +Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int /*x*/, int /*y*/) { if (Utils::Distance(height, 0.0f) > 0.5f) basePosition.z = 0.0f; @@ -208,14 +208,18 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) FILE* disk = fopen(path.c_str(), "wb"); if (!disk) { - printf("Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); + printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); return; } uint32 size = Utils::Size(stream); uint8* data = new uint8[size]; // Read the data to an array - fread(data, 1, size, stream); + if (fread(data, 1, size, stream) != 1) + { + printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str()); + return; + } // And write it in the file fwrite(data, 1, size, disk); @@ -242,136 +246,164 @@ std::string Utils::GetExtension( std::string path ) void MapChunkHeader::Read(FILE* stream) { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&IndexX, sizeof(uint32), 1, stream); - fread(&IndexY, sizeof(uint32), 1, stream); - fread(&Layers, sizeof(uint32), 1, stream); - fread(&DoodadRefs, sizeof(uint32), 1, stream); - fread(&OffsetMCVT, sizeof(uint32), 1, stream); - fread(&OffsetMCNR, sizeof(uint32), 1, stream); - fread(&OffsetMCLY, sizeof(uint32), 1, stream); - fread(&OffsetMCRF, sizeof(uint32), 1, stream); - fread(&OffsetMCAL, sizeof(uint32), 1, stream); - fread(&SizeMCAL, sizeof(uint32), 1, stream); - fread(&OffsetMCSH, sizeof(uint32), 1, stream); - fread(&SizeMCSH, sizeof(uint32), 1, stream); - fread(&AreaId, sizeof(uint32), 1, stream); - fread(&MapObjectRefs, sizeof(uint32), 1, stream); - fread(&Holes, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&Flags, sizeof(uint32), 1, stream); + count += fread(&IndexX, sizeof(uint32), 1, stream); + count += fread(&IndexY, sizeof(uint32), 1, stream); + count += fread(&Layers, sizeof(uint32), 1, stream); + count += fread(&DoodadRefs, sizeof(uint32), 1, stream); + count += fread(&OffsetMCVT, sizeof(uint32), 1, stream); + count += fread(&OffsetMCNR, sizeof(uint32), 1, stream); + count += fread(&OffsetMCLY, sizeof(uint32), 1, stream); + count += fread(&OffsetMCRF, sizeof(uint32), 1, stream); + count += fread(&OffsetMCAL, sizeof(uint32), 1, stream); + count += fread(&SizeMCAL, sizeof(uint32), 1, stream); + count += fread(&OffsetMCSH, sizeof(uint32), 1, stream); + count += fread(&SizeMCSH, sizeof(uint32), 1, stream); + count += fread(&AreaId, sizeof(uint32), 1, stream); + count += fread(&MapObjectRefs, sizeof(uint32), 1, stream); + count += fread(&Holes, sizeof(uint32), 1, stream); LowQualityTextureMap = new uint32[4]; - fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - fread(&PredTex, sizeof(uint32), 1, stream); - fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - fread(&OffsetMCSE, sizeof(uint32), 1, stream); - fread(&SoundEmitters, sizeof(uint32), 1, stream); - fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - fread(&SizeMCLQ, sizeof(uint32), 1, stream); + count += fread(LowQualityTextureMap, sizeof(uint32), 4, stream); + count += fread(&PredTex, sizeof(uint32), 1, stream); + count += fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); + count += fread(&OffsetMCSE, sizeof(uint32), 1, stream); + count += fread(&SoundEmitters, sizeof(uint32), 1, stream); + count += fread(&OffsetMCLQ, sizeof(uint32), 1, stream); + count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); - fread(&OffsetMCCV, sizeof(uint32), 1, stream); + count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); + + if (count != 27) + printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); } void MHDR::Read(FILE* stream) { - fread(&Flags, sizeof(uint32), 1, stream); - fread(&OffsetMCIN, sizeof(uint32), 1, stream); - fread(&OffsetMTEX, sizeof(uint32), 1, stream); - fread(&OffsetMMDX, sizeof(uint32), 1, stream); - fread(&OffsetMMID, sizeof(uint32), 1, stream); - fread(&OffsetMWMO, sizeof(uint32), 1, stream); - fread(&OffsetMWID, sizeof(uint32), 1, stream); - fread(&OffsetMDDF, sizeof(uint32), 1, stream); - fread(&OffsetMODF, sizeof(uint32), 1, stream); - fread(&OffsetMFBO, sizeof(uint32), 1, stream); - fread(&OffsetMH2O, sizeof(uint32), 1, stream); - fread(&OffsetMTFX, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&Flags, sizeof(uint32), 1, stream); + count += fread(&OffsetMCIN, sizeof(uint32), 1, stream); + count += fread(&OffsetMTEX, sizeof(uint32), 1, stream); + count += fread(&OffsetMMDX, sizeof(uint32), 1, stream); + count += fread(&OffsetMMID, sizeof(uint32), 1, stream); + count += fread(&OffsetMWMO, sizeof(uint32), 1, stream); + count += fread(&OffsetMWID, sizeof(uint32), 1, stream); + count += fread(&OffsetMDDF, sizeof(uint32), 1, stream); + count += fread(&OffsetMODF, sizeof(uint32), 1, stream); + count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); + count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); + count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); + + if (count != 12) + printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); } void ModelHeader::Read(FILE* stream) { - fread(&Magic, sizeof(char), 4, stream); + int count = 0; + + count += fread(&Magic, sizeof(char), 4, stream); Magic[4] = '\0'; // null-terminate it. - fread(&Version, sizeof(uint32), 1, stream); - fread(&LengthModelName, sizeof(uint32), 1, stream); - fread(&OffsetName, sizeof(uint32), 1, stream); - fread(&ModelFlags, sizeof(uint32), 1, stream); - fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - fread(&CountAnimations, sizeof(uint32), 1, stream); - fread(&OffsetAnimations, sizeof(uint32), 1, stream); - fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - fread(&CountBones, sizeof(uint32), 1, stream); - fread(&OffsetBones, sizeof(uint32), 1, stream); - fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - fread(&CountVertices, sizeof(uint32), 1, stream); - fread(&OffsetVertices, sizeof(uint32), 1, stream); - fread(&CountViews, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - fread(&CountRenderFlags, sizeof(uint32), 1, stream); - fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - fread(&CountBoneLookup, sizeof(uint32), 1, stream); - fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - fread(&CountTexLookup, sizeof(uint32), 1, stream); - fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - fread(&CountTexUnits, sizeof(uint32), 1, stream); - fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - fread(&CountTransLookup, sizeof(uint32), 1, stream); - fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); + count += fread(&Version, sizeof(uint32), 1, stream); + count += fread(&LengthModelName, sizeof(uint32), 1, stream); + count += fread(&OffsetName, sizeof(uint32), 1, stream); + count += fread(&ModelFlags, sizeof(uint32), 1, stream); + count += fread(&CountGlobalSequences, sizeof(uint32), 1, stream); + count += fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); + count += fread(&CountAnimations, sizeof(uint32), 1, stream); + count += fread(&OffsetAnimations, sizeof(uint32), 1, stream); + count += fread(&CountAnimationLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); + count += fread(&CountBones, sizeof(uint32), 1, stream); + count += fread(&OffsetBones, sizeof(uint32), 1, stream); + count += fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); + count += fread(&CountVertices, sizeof(uint32), 1, stream); + count += fread(&OffsetVertices, sizeof(uint32), 1, stream); + count += fread(&CountViews, sizeof(uint32), 1, stream); + count += fread(&CountColors, sizeof(uint32), 1, stream); + count += fread(&OffsetColors, sizeof(uint32), 1, stream); + count += fread(&CountTextures, sizeof(uint32), 1, stream); + count += fread(&OffsetTextures, sizeof(uint32), 1, stream); + count += fread(&CountTransparency, sizeof(uint32), 1, stream); + count += fread(&OffsetTransparency, sizeof(uint32), 1, stream); + count += fread(&CountUvAnimation, sizeof(uint32), 1, stream); + count += fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); + count += fread(&CountTexReplace, sizeof(uint32), 1, stream); + count += fread(&OffsetTexReplace, sizeof(uint32), 1, stream); + count += fread(&CountRenderFlags, sizeof(uint32), 1, stream); + count += fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); + count += fread(&CountBoneLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); + count += fread(&CountTexLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetTexLookup, sizeof(uint32), 1, stream); + count += fread(&CountTexUnits, sizeof(uint32), 1, stream); + count += fread(&OffsetTexUnits, sizeof(uint32), 1, stream); + count += fread(&CountTransLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetTransLookup, sizeof(uint32), 1, stream); + count += fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); + count += fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); - fread(&VertexRadius, sizeof(float), 1, stream); + count += fread(&VertexRadius, sizeof(float), 1, stream); BoundingBox[0] = Vector3::Read(stream); BoundingBox[1] = Vector3::Read(stream); - fread(&BoundingRadius, sizeof(float), 1, stream); - fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + count += fread(&BoundingRadius, sizeof(float), 1, stream); + count += fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); + count += fread(&CountBoundingVertices, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); + count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); + count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); + + if (count != 51) + printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); + } WorldModelHeader WorldModelHeader::Read(FILE* stream) { WorldModelHeader ret; - fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - fread(&ret.CountGroups, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountLights, sizeof(uint32), 1, stream); - fread(&ret.CountModels, sizeof(uint32), 1, stream); - fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - fread(&ret.CountSets, sizeof(uint32), 1, stream); - fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&ret.CountMaterials, sizeof(uint32), 1, stream); + count += fread(&ret.CountGroups, sizeof(uint32), 1, stream); + count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountLights, sizeof(uint32), 1, stream); + count += fread(&ret.CountModels, sizeof(uint32), 1, stream); + count += fread(&ret.CountDoodads, sizeof(uint32), 1, stream); + count += fread(&ret.CountSets, sizeof(uint32), 1, stream); + count += fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); + count += fread(&ret.WmoId, sizeof(uint32), 1, stream); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + + if (count != 10) + printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); + return ret; } DoodadInstance DoodadInstance::Read(FILE* stream) { DoodadInstance ret; - fread(&ret.FileOffset, sizeof(uint32), 1, stream); + int count = 0; + + count += fread(&ret.FileOffset, sizeof(uint32), 1, stream); ret.Position = Vector3::Read(stream); - fread(&ret.QuatW, sizeof(float), 1, stream); - fread(&ret.QuatX, sizeof(float), 1, stream); - fread(&ret.QuatY, sizeof(float), 1, stream); - fread(&ret.QuatZ, sizeof(float), 1, stream); - fread(&ret.Scale, sizeof(float), 1, stream); - fread(&ret.LightColor, sizeof(uint32), 1, stream); + count += fread(&ret.QuatW, sizeof(float), 1, stream); + count += fread(&ret.QuatX, sizeof(float), 1, stream); + count += fread(&ret.QuatY, sizeof(float), 1, stream); + count += fread(&ret.QuatZ, sizeof(float), 1, stream); + count += fread(&ret.Scale, sizeof(float), 1, stream); + count += fread(&ret.LightColor, sizeof(uint32), 1, stream); + + if (count != 7) + printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); + return ret; } @@ -379,24 +411,35 @@ DoodadSet DoodadSet::Read(FILE* stream) { DoodadSet ret; char name[21]; - fread(&name, sizeof(char), 20, stream); + int count = 0; + + count += fread(&name, sizeof(char), 20, stream); name[20] = '\0'; ret.Name = name; - fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - fread(&ret.CountInstances, sizeof(uint32), 1, stream); - fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + count += fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); + count += fread(&ret.CountInstances, sizeof(uint32), 1, stream); + count += fread(&ret.UnknownZero, sizeof(uint32), 1, stream); + + if (count != 23) + printf("DoodadSet::Read: Failed to read some data expected 23, read %d\n", count); + return ret; } LiquidHeader LiquidHeader::Read(FILE* stream) { LiquidHeader ret; - fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - fread(&ret.Width, sizeof(uint32), 1, stream); - fread(&ret.Height, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.CountXVertices, sizeof(uint32), 1, stream); + count += fread(&ret.CountYVertices, sizeof(uint32), 1, stream); + count += fread(&ret.Width, sizeof(uint32), 1, stream); + count += fread(&ret.Height, sizeof(uint32), 1, stream); ret.BaseLocation = Vector3::Read(stream); - fread(&ret.MaterialId, sizeof(uint16), 1, stream); + count += fread(&ret.MaterialId, sizeof(uint16), 1, stream); + + if (count != 5) + printf("LiquidHeader::Read: Failed to read some data expected 5, read %d\n", count); + return ret; } @@ -416,10 +459,12 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) for (uint32 x = 0; x < header.CountXVertices; x++) { uint32 discard; - fread(&discard, sizeof(uint32), 1, stream); float tmp; - fread(&tmp, sizeof(float), 1, stream); - ret.HeightMap[x][y] = tmp; + if (fread(&discard, sizeof(uint32), 1, stream) == 1 && + fread(&tmp, sizeof(float), 1, stream) == 1) + { + ret.HeightMap[x][y] = tmp; + } } } @@ -427,9 +472,9 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) { for (uint32 x = 0; x < header.Width; x++) { - uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); - ret.RenderFlags[x][y] = tmp; + uint8 tmp = 0; + if (fread(&tmp, sizeof(uint8), 1, stream) == 1) + ret.RenderFlags[x][y] = tmp; } } @@ -439,7 +484,8 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) H2ORenderMask H2ORenderMask::Read(FILE* stream) { H2ORenderMask ret; - fread(&ret.Mask, sizeof(uint8), 8, stream); + if (int count = fread(&ret.Mask, sizeof(uint8), 8, stream) != 8) + printf("H2OHeader::Read: Failed to read some data expected 8, read %d\n", count); return ret; } @@ -458,25 +504,35 @@ bool MCNKLiquidData::IsWater(int x, int y, float height) H2OHeader H2OHeader::Read(FILE* stream) { H2OHeader ret; - fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - fread(&ret.LayerCount, sizeof(uint32), 1, stream); - fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); + count += fread(&ret.LayerCount, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetRender, sizeof(uint32), 1, stream); + + if (count != 3) + printf("H2OHeader::Read: Failed to read some data expected 3, read %d\n", count); + return ret; } H2OInformation H2OInformation::Read(FILE* stream) { H2OInformation ret; - fread(&ret.LiquidType, sizeof(uint16), 1, stream); - fread(&ret.Flags, sizeof(uint16), 1, stream); - fread(&ret.HeightLevel1, sizeof(float), 1, stream); - fread(&ret.HeightLevel2, sizeof(float), 1, stream); - fread(&ret.OffsetX, sizeof(uint8), 1, stream); - fread(&ret.OffsetY, sizeof(uint8), 1, stream); - fread(&ret.Width, sizeof(uint8), 1, stream); - fread(&ret.Height, sizeof(uint8), 1, stream); - fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.LiquidType, sizeof(uint16), 1, stream); + count += fread(&ret.Flags, sizeof(uint16), 1, stream); + count += fread(&ret.HeightLevel1, sizeof(float), 1, stream); + count += fread(&ret.HeightLevel2, sizeof(float), 1, stream); + count += fread(&ret.OffsetX, sizeof(uint8), 1, stream); + count += fread(&ret.OffsetY, sizeof(uint8), 1, stream); + count += fread(&ret.Width, sizeof(uint8), 1, stream); + count += fread(&ret.Height, sizeof(uint8), 1, stream); + count += fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); + + if (count != 10) + printf("H2OInformation::Read: Failed to read some data expected 10, read %d\n", count); + return ret; } @@ -492,17 +548,21 @@ char* Utils::GetPlainName(const char* FileName) WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) { WMOGroupHeader ret; - fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); - fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); - fread(&ret.Flags, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); + count += fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); + count += fread(&ret.Flags, sizeof(uint32), 1, stream); ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); - fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); - fread(&ret.CountPortals, sizeof(uint32), 1, stream); - fread(&ret.CountBatches, sizeof(uint16), 4, stream); - fread(&ret.Fogs, sizeof(uint8), 4, stream); - fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - fread(&ret.WmoId, sizeof(uint32), 1, stream); - + count += fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); + count += fread(&ret.CountBatches, sizeof(uint16), 4, stream); + count += fread(&ret.Fogs, sizeof(uint8), 4, stream); + count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + count += fread(&ret.WmoId, sizeof(uint32), 1, stream); + + if (count != 15) + printf("WMOGroupHeader::Read: Failed to read some data expected 15, read %d\n", count); + return ret; } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c5dd04fde06..e7380ed8142 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -40,7 +40,7 @@ template struct Triangle { Triangle() {} - Triangle(Constants::TriangleType type, T v0, T v1, T v2) : Type(type), V0(v0), V1(v1), V2(v2) {} + Triangle(Constants::TriangleType type, T v0, T v1, T v2) : V0(v0), V1(v1), V2(v2), Type(type) {} T V0; T V1; T V2; @@ -374,4 +374,4 @@ public: static std::string GetExtension( std::string path ); static char* GetPlainName(const char* FileName); }; -#endif \ No newline at end of file +#endif diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index f0c3091c04e..70d140e79ed 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -4,7 +4,7 @@ #include "Utils.h" #include "WorldModelHandler.h" -WDT::WDT(std::string file) : IsValid(false), IsGlobalModel(false) +WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false) { Data = new ChunkedData(file, 2); ReadTileTable(); @@ -37,8 +37,13 @@ void WDT::ReadTileTable() const uint32 hasTileFlag = 0x1; uint32 flags; uint32 discard; - fread(&flags, sizeof(uint32), 1, stream); - fread(&discard, sizeof(uint32), 1, stream); + int count = 0; + count += fread(&flags, sizeof(uint32), 1, stream); + count += fread(&discard, sizeof(uint32), 1, stream); + + if (count != 2) + printf("WDT::ReadTileTable: Failed to read some data expected 2, read %d\n", count); + if (flags & hasTileFlag) TileTable.push_back(TilePos(x, y)); diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 35a5ba69782..5eeef824b1a 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -3,7 +3,7 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false) { Data = new ChunkedData(path); if (!Data->Stream) @@ -85,9 +85,13 @@ void WorldModelGroup::ReadTriangles() uint16 v0; uint16 v1; uint16 v2; - fread(&v0, sizeof(uint16), 1, stream); - fread(&v1, sizeof(uint16), 1, stream); - fread(&v2, sizeof(uint16), 1, stream); + int count = 0; + count += fread(&v0, sizeof(uint16), 1, stream); + count += fread(&v1, sizeof(uint16), 1, stream); + count += fread(&v2, sizeof(uint16), 1, stream); + if (count != 3) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 3, read %d\n", count); + Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); } } @@ -105,10 +109,12 @@ void WorldModelGroup::ReadMaterials() for (uint32 i = 0; i < triangleCount; i++) { uint8 tmp; - fread(&tmp, sizeof(uint8), 1, stream); + if (fread(&tmp, sizeof(uint8), 1, stream) != 1) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); TriangleFlags.push_back(tmp); // Read again for material. - fread(&tmp, sizeof(uint8), 1, stream); + if (fread(&tmp, sizeof(uint8), 1, stream) != 1) + printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); TriangleMaterials.push_back(tmp); } } @@ -131,5 +137,7 @@ void WorldModelGroup::ReadBatches() MOBALength = chunk->Length / 2; MOBA = new uint16[MOBALength]; - fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + int count = fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + if (count != MOBALength) + printf("WorldModelGroup::ReadBatches: Error reading data, expected %d, read %d\n", MOBALength, count); } diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 7b60b9b2151..6ce41807492 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -10,16 +10,20 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) { WorldModelDefinition ret; - fread(&ret.MwidIndex, sizeof(uint32), 1, file); - fread(&ret.UniqueId, sizeof(uint32), 1, file); + int count = 0; + count += fread(&ret.MwidIndex, sizeof(uint32), 1, file); + count += fread(&ret.UniqueId, sizeof(uint32), 1, file); ret.Position = Vector3::Read(file); ret.Rotation = Vector3::Read(file); ret.UpperExtents = Vector3::Read(file); ret.LowerExtents = Vector3::Read(file); - fread(&ret.Flags, sizeof(uint16), 1, file); - fread(&ret.DoodadSet, sizeof(uint16), 1, file); + count += fread(&ret.Flags, sizeof(uint16), 1, file); + count += fread(&ret.DoodadSet, sizeof(uint16), 1, file); uint32 discard; - fread(&discard, sizeof(uint32), 1, file); + count += fread(&discard, sizeof(uint32), 1, file); + + if (count != 5) + printf("WorldModelDefinition::Read: Error reading data, expected 5, read %d\n", count); return ret; } @@ -44,7 +48,8 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) for (uint32 i = 0; i < refCount; i++) { int32 index; - fread(&index, sizeof(int32), 1, stream); + if (fread(&index, sizeof(int32), 1, stream) != 1) + printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); if (index < 0 || uint32(index) >= _definitions->size()) continue; @@ -184,7 +189,8 @@ void WorldModelHandler::ReadModelPaths() FILE* stream = mwid->GetStream(); fseek(stream, i * 4, SEEK_CUR); uint32 offset; - fread(&offset, sizeof(uint32), 1, stream); + if (fread(&offset, sizeof(uint32), 1, stream) != 1) + printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); FILE* dataStream = mwmo->GetStream(); fseek(dataStream, offset + mwmo->Offset, SEEK_SET); _paths->push_back(Utils::ReadString(dataStream)); diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 46bf9d00d43..229a2cd808f 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -22,13 +22,13 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/dep/bzip2 - ${CMAKE_SOURCE_DIR}/dep/acelite ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Database ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation + ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index a267a0f6412..98042e1b917 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -35,7 +35,7 @@ namespace MMAP rcPolyMesh* polyMesh; rcPolyMeshDetail* polyMeshDetail; - IntermediateValues() : compactHeightfield(NULL), heightfield(NULL), + IntermediateValues() : heightfield(NULL), compactHeightfield(NULL), contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {} ~IntermediateValues(); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 754bced903c..689ccdc906d 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -29,7 +29,7 @@ // These make the linker happy. LoginDatabaseWorkerPool LoginDatabase; -uint32 GetLiquidFlags(uint32 liquidType) +uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; } @@ -37,7 +37,7 @@ uint32 GetLiquidFlags(uint32 liquidType) #include "DisableMgr.h" namespace DisableMgr { - bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags) + bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/) { return 0; } @@ -50,15 +50,15 @@ namespace MMAP MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, bool debugOutput, bool bigBaseUnit, const char* offMeshFilePath) : - m_terrainBuilder(NULL), + m_terrainBuilder (NULL), m_debugOutput (debugOutput), + m_offMeshFilePath (offMeshFilePath), m_skipContinents (skipContinents), m_skipJunkMaps (skipJunkMaps), m_skipBattlegrounds (skipBattlegrounds), m_maxWalkableAngle (maxWalkableAngle), m_bigBaseUnit (bigBaseUnit), - m_rcContext (NULL), - m_offMeshFilePath (offMeshFilePath) + m_rcContext (NULL) { m_terrainBuilder = new TerrainBuilder(skipLiquid); @@ -250,9 +250,12 @@ namespace MMAP printf("Building mesh from file\n"); int tileX, tileY, mapId; - fread(&mapId, sizeof(int), 1, file); - fread(&tileX, sizeof(int), 1, file); - fread(&tileY, sizeof(int), 1, file); + if (fread(&mapId, sizeof(int), 1, file) != 1) + return; + if (fread(&tileX, sizeof(int), 1, file) != 1) + return; + if (fread(&tileY, sizeof(int), 1, file) != 1) + return; dtNavMesh* navMesh = NULL; buildNavMesh(mapId, navMesh); @@ -263,23 +266,26 @@ namespace MMAP return; } - - int verticesCount, indicesCount; - fread(&verticesCount, sizeof(int), 1, file); - fread(&indicesCount, sizeof(int), 1, file); + uint verticesCount, indicesCount; + if (fread(&verticesCount, sizeof(uint), 1, file) != 1) + return; + if (fread(&indicesCount, sizeof(uint), 1, file) != 1) + return; float* verts = new float[verticesCount]; int* inds = new int[indicesCount]; - fread(verts, sizeof(float), verticesCount, file); - fread(inds, sizeof(int), indicesCount, file); + if (fread(verts, sizeof(float), verticesCount, file) != verticesCount) + return; + if (fread(inds, sizeof(int), indicesCount, file) != indicesCount) + return; MeshData data; - for (int i = 0; i < verticesCount; ++i) + for (uint i = 0; i < verticesCount; ++i) data.solidVerts.append(verts[i]); - for (int i = 0; i < indicesCount; ++i) + for (uint i = 0; i < indicesCount; ++i) data.solidTris.append(inds[i]); TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); @@ -310,7 +316,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildMap(uint32 mapID) { - printf("[Thread %i] Building map %03u:\n", ACE_Thread::self(), mapID); + printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID); set* tiles = getTileList(mapID); @@ -409,7 +415,6 @@ namespace MMAP //if (tileBits < 1) tileBits = 1; // need at least one bit! //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits; - int tileBits = STATIC_TILE_BITS; int polyBits = STATIC_POLY_BITS; int maxTiles = tiles->size(); @@ -955,8 +960,10 @@ namespace MMAP return false; MmapTileHeader header; - fread(&header, sizeof(MmapTileHeader), 1, file); + int count = fread(&header, sizeof(MmapTileHeader), 1, file); fclose(file); + if (count != 1) + return false; if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) return false; diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index fd02ec02d50..966c12ec19e 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -75,7 +75,7 @@ namespace MMAP LISTFILE_OK = 1 }; - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*", bool includeSubDirs = false) + inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*") { #ifdef WIN32 HANDLE hFind; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 0159219c110..22946df478a 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -27,6 +27,9 @@ namespace MMAP { + + char const* MAP_VERSION_MAGIC = "v1.3"; + TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } @@ -86,9 +89,8 @@ namespace MMAP return false; map_fileheader fheader; - fread(&fheader, sizeof(map_fileheader), 1, mapFile); - - if (fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) + if (fread(&fheader, sizeof(map_fileheader), 1, mapFile) != 1 || + fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC))) { fclose(mapFile); printf("%s is the wrong version, please extract new .map files\n", mapFileName); @@ -97,10 +99,14 @@ namespace MMAP map_heightHeader hheader; fseek(mapFile, fheader.heightMapOffset, SEEK_SET); - fread(&hheader, sizeof(map_heightHeader), 1, mapFile); - bool haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); - bool haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + bool haveTerrain = false; + bool haveLiquid = false; + if (fread(&hheader, sizeof(map_heightHeader), 1, mapFile) == 1) + { + haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT); + haveLiquid = fheader.liquidMapOffset && !m_skipLiquid; + } // no data in this map file if (!haveTerrain && !haveLiquid) @@ -120,42 +126,53 @@ namespace MMAP // terrain data if (haveTerrain) { - int i; float heightMultiplier; float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ]; + int expected = V9_SIZE_SQ + V8_SIZE_SQ; if (hheader.flags & MAP_HEIGHT_AS_INT8) { uint8 v9[V9_SIZE_SQ]; uint8 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile); + count += fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; } else if (hheader.flags & MAP_HEIGHT_AS_INT16) { uint16 v9[V9_SIZE_SQ]; uint16 v8[V8_SIZE_SQ]; - fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); - fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile); + count += fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight; - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight; } else { - fread (V9, sizeof(float), V9_SIZE_SQ, mapFile); - fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + int count = 0; + count += fread(V9, sizeof(float), V9_SIZE_SQ, mapFile); + count += fread(V8, sizeof(float), V8_SIZE_SQ, mapFile); + if (count != expected) + printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); } // hole data @@ -163,7 +180,8 @@ namespace MMAP { memset(holes, 0, fheader.holesSize); fseek(mapFile, fheader.holesOffset, SEEK_SET); - fread(holes, fheader.holesSize, 1, mapFile); + if (fread(holes, fheader.holesSize, 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } int count = meshData.solidVerts.size() / 3; @@ -172,7 +190,7 @@ namespace MMAP float coord[3]; - for (i = 0; i < V9_SIZE_SQ; ++i) + for (int i = 0; i < V9_SIZE_SQ; ++i) { getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); meshData.solidVerts.append(coord[0]); @@ -180,7 +198,7 @@ namespace MMAP meshData.solidVerts.append(coord[1]); } - for (i = 0; i < V8_SIZE_SQ; ++i) + for (int i = 0; i < V8_SIZE_SQ; ++i) { getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); meshData.solidVerts.append(coord[0]); @@ -188,10 +206,10 @@ namespace MMAP meshData.solidVerts.append(coord[1]); } - int j, indices[3], loopStart, loopEnd, loopInc; + int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0; getLoopVars(portion, loopStart, loopEnd, loopInc); - for (i = loopStart; i < loopEnd; i+=loopInc) - for (j = TOP; j <= BOTTOM; j+=1) + for (int i = loopStart; i < loopEnd; i+=loopInc) + for (int j = TOP; j <= BOTTOM; j+=1) { getHeightTriangle(i, Spot(j), indices); ttriangles.append(indices[2] + count); @@ -205,19 +223,25 @@ namespace MMAP { map_liquidHeader lheader; fseek(mapFile, fheader.liquidMapOffset, SEEK_SET); - fread(&lheader, sizeof(map_liquidHeader), 1, mapFile); + if (fread(&lheader, sizeof(map_liquidHeader), 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); + float* liquid_map = NULL; if (!(lheader.flags & MAP_LIQUID_NO_TYPE)) - fread(liquid_type, sizeof(liquid_type), 1, mapFile); + if (fread(liquid_type, sizeof(liquid_type), 1, mapFile) != 1) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - liquid_map = new float [lheader.width*lheader.height]; - fread(liquid_map, sizeof(float), lheader.width*lheader.height, mapFile); + uint toRead = lheader.width*lheader.height; + liquid_map = new float [toRead]; + if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) + printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } + // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" if (liquid_type && liquid_map) { int count = meshData.liquidVerts.size() / 3; @@ -263,9 +287,8 @@ namespace MMAP delete [] liquid_map; - int indices[3], loopStart, loopEnd, loopInc, triInc; + int indices[3], loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP; getLoopVars(portion, loopStart, loopEnd, loopInc); - triInc = BOTTOM-TOP; // generate triangles for (int i = loopStart; i < loopEnd; i+=loopInc) @@ -283,7 +306,7 @@ namespace MMAP // now that we have gathered the data, we can figure out which parts to keep: // liquid above ground, ground above liquid - int loopStart, loopEnd, loopInc, tTriCount = 4; + int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4; bool useTerrain, useLiquid; float* lverts = meshData.liquidVerts.getCArray(); @@ -313,6 +336,7 @@ namespace MMAP useTerrain = true; useLiquid = true; uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; + // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) @@ -825,13 +849,13 @@ namespace MMAP while(fgets(buf, 512, fp)) { float p0[3], p1[3]; - int mid, tx, ty; + uint32 mid, tx, ty; float size; - if (10 != sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, - &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size)) + if (sscanf(buf, "%d %d,%d (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty, + &p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10) continue; - if (mapID == mid, tileX == tx, tileY == ty) + if (mapID == mid && tileX == tx && tileY == ty) { meshData.offMeshConnections.append(p0[1]); meshData.offMeshConnections.append(p0[2]); diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6d478753279..7a24146946b 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -62,7 +62,6 @@ namespace MMAP // see following files: // contrib/extractor/system.cpp // src/game/Map.cpp - static char const* MAP_VERSION_MAGIC = "v1.3"; struct MeshData { diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 4f203e11c21..2b525fbf353 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -57,7 +57,7 @@ namespace VMAP } // declared in src/shared/vmap/ModelInstance.h - WorldModel* const ModelInstance::getWorldModel() + WorldModel* ModelInstance::getWorldModel() { return iModel; } diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index a605118eead..56e62d474d1 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -69,8 +69,7 @@ void fixname2(char* name, size_t len) char* GetExtension(char* FileName) { - char* szTemp; - if (szTemp = strrchr(FileName, '.')) + if (char* szTemp = strrchr(FileName, '.')) return szTemp; return NULL; } diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index c642f73ccae..b950db023fe 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -152,10 +152,10 @@ ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID fseek(input, 8, SEEK_SET); // get the correct no of vertices int nVertices; - fread(&nVertices, sizeof (int), 1, input); + int count = fread(&nVertices, sizeof (int), 1, input); fclose(input); - if(nVertices == 0) + if (count != 1 || nVertices == 0) return; uint16 adtId = 0;// not used for models diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 186f9c8606e..89e4b850dac 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -461,8 +461,7 @@ int main(int argc, char ** argv) printf("Your output directory seems to be polluted, please use an empty directory!\n"); printf(""); char garbage[2]; - scanf("%c", garbage); - return 1; + return scanf("%c", garbage); } } diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 0bc749b9bd5..7c9f23c5a95 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -521,10 +521,10 @@ WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint fseek(input, 8, SEEK_SET); // get the correct no of vertices int nVertices; - fread(&nVertices, sizeof (int), 1, input); + int count = fread(&nVertices, sizeof (int), 1, input); fclose(input); - if(nVertices == 0) + if (count != 1 || nVertices == 0) return; float x,z; -- cgit v1.2.3 From cbf9324f61984727163150ed09a72288da45e3a4 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 9 Jan 2013 21:01:39 +0100 Subject: Core: Fix build --- src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 10 +++++----- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 5c54d975487..3c846363d06 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -5,7 +5,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { char magic[5]; - uint count = 0; + uint32 count = 0; count += fread(&magic, sizeof(char), 4, stream); magic[4] = '\0'; count += fread(&RecordCount, sizeof(uint32), 1, stream); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 689ccdc906d..29591a406df 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -266,10 +266,10 @@ namespace MMAP return; } - uint verticesCount, indicesCount; - if (fread(&verticesCount, sizeof(uint), 1, file) != 1) + uint32 verticesCount, indicesCount; + if (fread(&verticesCount, sizeof(uint32), 1, file) != 1) return; - if (fread(&indicesCount, sizeof(uint), 1, file) != 1) + if (fread(&indicesCount, sizeof(uint32), 1, file) != 1) return; float* verts = new float[verticesCount]; @@ -282,10 +282,10 @@ namespace MMAP MeshData data; - for (uint i = 0; i < verticesCount; ++i) + for (uint32 i = 0; i < verticesCount; ++i) data.solidVerts.append(verts[i]); - for (uint i = 0; i < indicesCount; ++i) + for (uint32 i = 0; i < indicesCount; ++i) data.solidTris.append(inds[i]); TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 966c12ec19e..8fad880212b 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -90,7 +90,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if (includeSubDirs || (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + if (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) fileList.push_back(string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 22946df478a..97e504d5160 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -235,7 +235,7 @@ namespace MMAP if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - uint toRead = lheader.width*lheader.height; + uint8 toRead = lheader.width*lheader.height; liquid_map = new float [toRead]; if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); -- cgit v1.2.3 From 7210ffe34d2052c1aee642ac3af40425c8ba137e Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 9 Jan 2013 21:14:12 +0100 Subject: Core: Fix warnings --- src/server/scripts/Commands/cs_mmaps.cpp | 10 +++++----- src/tools/mmaps_generator/PathCommon.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c17c01adc33..09e777e4047 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -117,7 +117,7 @@ public: return true; } - static bool HandleMmapLocCommand(ChatHandler* handler, const char* args) + static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/) { handler->PSendSysMessage("mmap tileloc:"); @@ -171,7 +171,7 @@ public: return true; } - static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, const char* args) + static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/) { uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid); @@ -196,7 +196,7 @@ public: return true; } - static bool HandleMmapStatsCommand(ChatHandler* handler, const char* args) + static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/) { uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); handler->PSendSysMessage("mmap stats:"); @@ -244,12 +244,12 @@ public: return true; } - static bool HandleMmapTestArea(ChatHandler* handler, const char* args) + static bool HandleMmapTestArea(ChatHandler* handler, char const* /*args*/) { float radius = 40.0f; WorldObject* object = handler->GetSession()->GetPlayer(); - CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()) ); + CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY())); Cell cell(pair); cell.SetNoCreate(); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 8fad880212b..820ff34d425 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -90,7 +90,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if (findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0) + if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) fileList.push_back(string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); -- cgit v1.2.3 From 1154c62b65af70e7801bb280aa90a98581d0c1ec Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 10 Jan 2013 12:40:26 +0100 Subject: Core/Tools: Fix logic fail for mmaps generator (thx armano2) --- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 97e504d5160..d3c3772532d 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -235,7 +235,7 @@ namespace MMAP if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT)) { - uint8 toRead = lheader.width*lheader.height; + uint32 toRead = lheader.width * lheader.height; liquid_map = new float [toRead]; if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead) printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); -- cgit v1.2.3 From dfbf318a4feb48d412391d7da1df9381310858ab Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 10 Jan 2013 15:29:08 +0100 Subject: Typo fix --- src/tools/map_extractor/adt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index 505813c4bd0..eeb69134fab 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -8,7 +8,7 @@ int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; u_map_fcc MHDRMagic = { {'M','H','D','R'} }; u_map_fcc MCINMagic = { {'M','C','I','N'} }; -u_map_fcc MH20Magic = { {'M','H','2','0'} }; +u_map_fcc MH2OMagic = { {'M','H','2','O'} }; u_map_fcc MCNKMagic = { {'M','C','N','K'} }; u_map_fcc MCVTMagic = { {'M','C','V','T'} }; u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; @@ -93,7 +93,7 @@ bool adt_MCIN::prepareLoadedData() bool adt_MH2O::prepareLoadedData() { - if (fcc != MH20Magic.fcc) + if (fcc != MH2OMagic.fcc) return false; // Check liquid data -- cgit v1.2.3 From e783349803e64d0fd1879a97dcb4749435a87f05 Mon Sep 17 00:00:00 2001 From: Spp Date: Sat, 12 Jan 2013 02:15:10 +0100 Subject: Use correct initialization of some vars --- src/tools/map_extractor/adt.cpp | 12 ++++++------ src/tools/map_extractor/loadlib.cpp | 2 +- src/tools/map_extractor/wdt.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index eeb69134fab..a93ead838fe 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -6,12 +6,12 @@ int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; -u_map_fcc MHDRMagic = { {'M','H','D','R'} }; -u_map_fcc MCINMagic = { {'M','C','I','N'} }; -u_map_fcc MH2OMagic = { {'M','H','2','O'} }; -u_map_fcc MCNKMagic = { {'M','C','N','K'} }; -u_map_fcc MCVTMagic = { {'M','C','V','T'} }; -u_map_fcc MCLQMagic = { {'M','C','L','Q'} }; +u_map_fcc MHDRMagic = { {'R','D','H','M'} }; +u_map_fcc MCINMagic = { {'N','I','C','M'} }; +u_map_fcc MH2OMagic = { {'0','2','H','M'} }; +u_map_fcc MCNKMagic = { {'K','N','C','M'} }; +u_map_fcc MCVTMagic = { {'T','V','C','M'} }; +u_map_fcc MCLQMagic = { {'Q','L','C','M'} }; bool isHole(int holes, int i, int j) { diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index d1ea40110de..5dcb479a11c 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -6,7 +6,7 @@ class MPQFile; -u_map_fcc MverMagic = { {'M','V','E','R'} }; +u_map_fcc MverMagic = { {'R','E','V','M'} }; FileLoader::FileLoader() { diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index 90a07eafab3..ff255145583 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -2,9 +2,9 @@ #include "wdt.h" -u_map_fcc MWMOMagic = { {'M', 'W', 'M', 'O'} }; -u_map_fcc MPHDMagic = { {'M', 'P', 'H', 'D'} }; -u_map_fcc MAINMagic = { {'M', 'A', 'I', 'N'} }; +u_map_fcc MWMOMagic = { {'O', 'M', 'W', 'M'} }; +u_map_fcc MPHDMagic = { {'D', 'H', 'P', 'M'} }; +u_map_fcc MAINMagic = { {'N', 'I', 'A', 'M'} }; bool wdt_MWMO::prepareLoadedData() { -- cgit v1.2.3 From 32e08bcd122fce70ae33eed3f0ec44d35a60eff2 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 13 Jan 2013 02:11:21 +0000 Subject: Tools/Extractor: Fix yet another typo in ADT. Fixes extracting. Closes #8900 --- src/tools/map_extractor/adt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index a93ead838fe..30524dbd640 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -8,7 +8,7 @@ int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; u_map_fcc MHDRMagic = { {'R','D','H','M'} }; u_map_fcc MCINMagic = { {'N','I','C','M'} }; -u_map_fcc MH2OMagic = { {'0','2','H','M'} }; +u_map_fcc MH2OMagic = { {'O','2','H','M'} }; u_map_fcc MCNKMagic = { {'K','N','C','M'} }; u_map_fcc MCVTMagic = { {'T','V','C','M'} }; u_map_fcc MCLQMagic = { {'Q','L','C','M'} }; -- cgit v1.2.3 From 65cd79dc779e1900cb82e862ffab9ef3a20771ac Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Mon, 14 Jan 2013 17:42:06 +0100 Subject: Core/Misc: Update headers to 2013 --- src/server/collision/Management/MMapFactory.cpp | 2 +- src/server/collision/Management/MMapFactory.h | 2 +- src/server/collision/Management/MMapManager.cpp | 2 +- src/server/collision/Management/MMapManager.h | 2 +- src/server/scripts/Commands/cs_mmaps.cpp | 2 +- src/tools/mesh_extractor/CMakeLists.txt | 2 +- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/IntermediateValues.h | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.h | 2 +- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 2 +- src/tools/mmaps_generator/TerrainBuilder.h | 2 +- src/tools/mmaps_generator/VMapExtensions.cpp | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp index 0b292b56dca..7adf7fbfa66 100644 --- a/src/server/collision/Management/MMapFactory.cpp +++ b/src/server/collision/Management/MMapFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h index a006aedfa6d..00f19a194d3 100644 --- a/src/server/collision/Management/MMapFactory.h +++ b/src/server/collision/Management/MMapFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 1b6cf5c0260..e3ed8f3310a 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h index 23b7d5fc6f8..56b1b856d65 100644 --- a/src/server/collision/Management/MMapManager.h +++ b/src/server/collision/Management/MMapManager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2010 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 09e777e4047..4649e13e1c4 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * * 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 diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 29c571d9301..b8bd9f54331 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2005-2009 MaNGOS project -# Copyright (C) 2008-2012 TrinityCore +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index b473d6472a0..6fad96887a2 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index 98042e1b917..89a5c3ae4c2 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 29591a406df..9e6acd71a72 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 61a71ff6d5b..c083e0b680a 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 820ff34d425..413f2b8735d 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index d3c3772532d..f7cf76e9718 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 7a24146946b..6ad4284f416 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 2b525fbf353..37b7d94af55 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify it -- cgit v1.2.3 From 98f502f32f092fe1bcb9e19c32c189d2ea552d19 Mon Sep 17 00:00:00 2001 From: MrSmite Date: Mon, 14 Jan 2013 21:42:23 -0500 Subject: Fix passive pets not using spells when commanded to attack Closes #8941 --- src/server/game/AI/CoreAI/PetAI.cpp | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index a8d2a2248ad..2792f68004f 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -432,29 +432,23 @@ void PetAI::HandleReturnMovement() if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning()) { // Return to previous position where stay was clicked - if (!me->GetCharmInfo()->IsCommandAttack()) - { - float x, y, z; + float x, y, z; - me->GetCharmInfo()->GetStayPosition(x, y, z); - ClearCharmInfoFlags(); - me->GetCharmInfo()->SetIsReturning(true); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(me->GetGUIDLow(), x, y, z); - } + me->GetCharmInfo()->GetStayPosition(x, y, z); + ClearCharmInfoFlags(); + me->GetCharmInfo()->SetIsReturning(true); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(me->GetGUIDLow(), x, y, z); } } else // COMMAND_FOLLOW { if (!me->GetCharmInfo()->IsFollowing() && !me->GetCharmInfo()->IsReturning()) { - if (!me->GetCharmInfo()->IsCommandAttack()) - { - ClearCharmInfoFlags(); - me->GetCharmInfo()->SetIsReturning(true); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveFollow(me->GetCharmerOrOwner(), PET_FOLLOW_DIST, me->GetFollowAngle()); - } + ClearCharmInfoFlags(); + me->GetCharmInfo()->SetIsReturning(true); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveFollow(me->GetCharmerOrOwner(), PET_FOLLOW_DIST, me->GetFollowAngle()); } } } @@ -473,12 +467,13 @@ void PetAI::DoAttack(Unit* target, bool chase) if (me->HasReactState(REACT_AGGRESSIVE) && !me->GetCharmInfo()->IsCommandAttack()) me->SendPetAIReaction(me->GetGUID()); - if (chase) { - ClearCharmInfoFlags(); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveChase(target); + bool oldCmdAttack = me->GetCharmInfo()->IsCommandAttack(); // This needs to be reset after other flags are cleared + ClearCharmInfoFlags(); + me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveChase(target); } else // (Stay && ((Aggressive || Defensive) && In Melee Range))) { -- cgit v1.2.3 From 6191642e5902fe8e670c8172a1a918d48a84683f Mon Sep 17 00:00:00 2001 From: Naios Date: Thu, 17 Jan 2013 14:04:20 +0100 Subject: Core/SmartScripts: Check Conditions also for timed Events * some cleanup work in SmartScripts.cpp Core/SmartScripts: Some Corrections to last commit --- src/server/game/AI/SmartScripts/SmartScript.cpp | 64 +++++++++++-------------- src/server/game/AI/SmartScripts/SmartScript.h | 1 + 2 files changed, 29 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 84c9dffabd2..86d86739bc9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2011,6 +2011,17 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } } +void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob) +{ + ConditionList const conds = sConditionMgr->GetConditionsForSmartEvent(e.entryOrGuid, e.event_id, e.source_type); + ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject()); + + if (sConditionMgr->IsObjectMeetToConditions(info, conds)) + ProcessAction(e, unit, var0, var1, bvar, spell, gob); + + RecalcTimer(e, min, max); +} + void SmartScript::InstallTemplate(SmartScriptHolder const& e) { if (!GetBaseObject()) @@ -2409,20 +2420,17 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui break; //called from Update tick case SMART_EVENT_UPDATE: - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; case SMART_EVENT_UPDATE_OOC: if (me && me->isInCombat()) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; case SMART_EVENT_UPDATE_IC: if (!me || !me->isInCombat()) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; case SMART_EVENT_HEALT_PCT: { @@ -2431,8 +2439,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui uint32 perc = (uint32)me->GetHealthPct(); if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; } case SMART_EVENT_TARGET_HEALTH_PCT: @@ -2442,8 +2449,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui uint32 perc = (uint32)me->getVictim()->GetHealthPct(); if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e, me->getVictim()); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->getVictim()); break; } case SMART_EVENT_MANA_PCT: @@ -2453,8 +2459,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui uint32 perc = uint32(100.0f * me->GetPower(POWER_MANA) / me->GetMaxPower(POWER_MANA)); if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); break; } case SMART_EVENT_TARGET_MANA_PCT: @@ -2464,8 +2469,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui uint32 perc = uint32(100.0f * me->getVictim()->GetPower(POWER_MANA) / me->getVictim()->GetMaxPower(POWER_MANA)); if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e, me->getVictim()); + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->getVictim()); break; } case SMART_EVENT_RANGE: @@ -2474,18 +2478,15 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui return; if (me->IsInRange(me->getVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) - { - ProcessAction(e, me->getVictim()); - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - } + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->getVictim()); break; } case SMART_EVENT_TARGET_CASTING: { if (!me || !me->isInCombat() || !me->getVictim() || !me->getVictim()->IsNonMeleeSpellCasted(false, false, true)) return; - ProcessAction(e, me->getVictim()); - RecalcTimer(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax); + + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->getVictim()); } case SMART_EVENT_FRIENDLY_HEALTH: { @@ -2495,8 +2496,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealt.radius, e.event.friendlyHealt.hpDeficit); if (!target) return; - ProcessAction(e, target); - RecalcTimer(e, e.event.friendlyHealt.repeatMin, e.event.friendlyHealt.repeatMax); + ProcessTimedAction(e, e.event.friendlyHealt.repeatMin, e.event.friendlyHealt.repeatMax, target); break; } case SMART_EVENT_FRIENDLY_IS_CC: @@ -2508,8 +2508,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui DoFindFriendlyCC(pList, (float)e.event.friendlyCC.radius); if (pList.empty()) return; - ProcessAction(e, *(pList.begin())); - RecalcTimer(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax); + ProcessTimedAction(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax, *pList.begin()); break; } case SMART_EVENT_FRIENDLY_MISSING_BUFF: @@ -2519,8 +2518,8 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (pList.empty()) return; - ProcessAction(e, *(pList.begin())); - RecalcTimer(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax); + + ProcessTimedAction(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax, *pList.begin()); break; } case SMART_EVENT_HAS_AURA: @@ -2529,10 +2528,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui return; uint32 count = me->GetAuraCount(e.event.aura.spell); if ((!e.event.aura.count && !count) || (e.event.aura.count && count >= e.event.aura.count)) - { - ProcessAction(e); - RecalcTimer(e, e.event.aura.repeatMin, e.event.aura.repeatMax); - } + ProcessTimedAction(e, e.event.aura.repeatMin, e.event.aura.repeatMax); break; } case SMART_EVENT_TARGET_BUFFED: @@ -2542,8 +2538,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui uint32 count = me->getVictim()->GetAuraCount(e.event.aura.spell); if (count < e.event.aura.count) return; - ProcessAction(e); - RecalcTimer(e, e.event.aura.repeatMin, e.event.aura.repeatMax); + ProcessTimedAction(e, e.event.aura.repeatMin, e.event.aura.repeatMax); break; } //no params @@ -2578,10 +2573,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (Unit* victim = me->getVictim()) { if (!victim->HasInArc(static_cast(M_PI), me)) - { - ProcessAction(e, victim); - RecalcTimer(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax); - } + ProcessTimedAction(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax, victim); } break; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index d0d0221493f..28b328a2947 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -45,6 +45,7 @@ class SmartScript void UpdateTimer(SmartScriptHolder& e, uint32 const diff); void InitTimer(SmartScriptHolder& e); void ProcessAction(SmartScriptHolder& e, Unit* unit = NULL, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = NULL, GameObject* gob = NULL); + void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = NULL, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = NULL, GameObject* gob = NULL); ObjectList* GetTargets(SmartScriptHolder const& e, Unit* invoker = NULL); ObjectList* GetWorldObjectsInDist(float dist); void InstallTemplate(SmartScriptHolder const& e); -- cgit v1.2.3 From ed44eea699379b4da814b85c22c0f87682cccc0c Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 19 Jan 2013 20:28:29 +0100 Subject: Core: Fix warnings --- .../scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp | 4 ++-- .../scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp index 58e130ce644..19660cec4af 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp @@ -66,8 +66,8 @@ enum eMisc Position const PosMove[2] = { - { 299.4884f, 92.76137f, 105.6335f }, - { 314.8673f, 90.30210f, 101.6459f } + { 299.4884f, 92.76137f, 105.6335f, 0.0f }, + { 314.8673f, 90.30210f, 101.6459f, 0.0f } }; class boss_kirtonos_the_herald : public CreatureScript diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 7f8108e5e71..6039e01b901 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -359,7 +359,7 @@ class boss_halion : public CreatureScript if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TWILIGHT_HALION))) if (twilightHalion->isAlive()) twilightHalion->Kill(twilightHalion); - + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER))) if (controller->isAlive()) controller->Kill(controller); -- cgit v1.2.3 From e524539d90f7c1b3393754641729fa844119b881 Mon Sep 17 00:00:00 2001 From: Gacko Date: Sat, 19 Jan 2013 19:17:31 +0100 Subject: Core/CS: More npcflag info in .npc info --- .../world/2013_01_19_06_world_trinity_string.sql | 28 ++++++++++++++ src/server/game/Miscellaneous/Language.h | 27 ++++++++++++- src/server/scripts/Commands/cs_npc.cpp | 44 +++++++++++++++++++--- 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 sql/updates/world/2013_01_19_06_world_trinity_string.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_19_06_world_trinity_string.sql b/sql/updates/world/2013_01_19_06_world_trinity_string.sql new file mode 100644 index 00000000000..322d43a7720 --- /dev/null +++ b/sql/updates/world/2013_01_19_06_world_trinity_string.sql @@ -0,0 +1,28 @@ +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 820 AND 842; +INSERT INTO `trinity_string`(`entry`,`content_default`) VALUES +(820,'* has gossip (%u)'), +(821,'* is quest giver (%u)'), +(822,'* is class trainer (%u)'), +(823,'* is profession trainer(%u)'), +(824,'* is ammo vendor (%u)'), +(825,'* is food vendor(%u)'), +(826,'* is poison vendor (%u)'), +(827,'* is reagent vendor (%u)'), +(828,'* can repair (%u)'), +(829,'* is flight master (%u)'), +(830,'* is spirit healer (%u)'), +(831,'* is spirit guide (%u)'), +(832,'* is innkeeper (%u)'), +(833,'* is banker (%u)'), +(834,'* is petitioner (%u)'), +(835,'* is tabard designer (%u)'), +(836,'* is battle master (%u)'), +(837,'* is auctioneer (%u)'), +(838,'* is stable master (%u)'), +(839,'* is guild banker (%u)'), +(840,'* has spell click (%u)'), +(841,'* is mailbox (%u)'), +(842,'* is player vehicle (%u)'); + +UPDATE `trinity_string` SET `content_default`='* is vendor (%u)' WHERE `entry`=545; +UPDATE `trinity_string` SET `content_default`='* is trainer (%u)' WHERE `entry`=546; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 292833c3955..35b0a6f8569 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -742,7 +742,32 @@ enum TrinityStrings LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818, LANG_CHANNEL_CITY = 819, - // Room for in-game strings 820-999 not used + + LANG_NPCINFO_GOSSIP = 820, + LANG_NPCINFO_QUESTGIVER = 821, + LANG_NPCINFO_TRAINER_CLASS = 822, + LANG_NPCINFO_TRAINER_PROFESSION = 823, + LANG_NPCINFO_VENDOR_AMMO = 824, + LANG_NPCINFO_VENDOR_FOOD = 825, + LANG_NPCINFO_VENDOR_POISON = 826, + LANG_NPCINFO_VENDOR_REAGENT = 827, + LANG_NPCINFO_REPAIR = 828, + LANG_NPCINFO_FLIGHTMASTER = 829, + LANG_NPCINFO_SPIRITHEALER = 830, + LANG_NPCINFO_SPIRITGUIDE = 831, + LANG_NPCINFO_INNKEEPER = 832, + LANG_NPCINFO_BANKER = 833, + LANG_NPCINFO_PETITIONER = 834, + LANG_NPCINFO_TABARDDESIGNER = 835, + LANG_NPCINFO_BATTLEMASTER = 836, + LANG_NPCINFO_AUCTIONEER = 837, + LANG_NPCINFO_STABLEMASTER = 838, + LANG_NPCINFO_GUILD_BANKER = 839, + LANG_NPCINFO_SPELLCLICK = 840, + LANG_NPCINFO_MAILBOX = 841, + LANG_NPCINFO_PLAYER_VEHICLE = 842, + + // Room for in-game strings 843-999 not used // Level 4 (CLI only commands) LANG_COMMAND_EXIT = 1000, diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 8679e288282..7ccd5ed1177 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -33,6 +33,42 @@ EndScriptData */ #include "Player.h" #include "Pet.h" +struct NpcFlagText +{ + uint32 flag; + int32 text; +}; + +#define NPCFLAG_COUNT 24 + +const NpcFlagText npcFlagTexts[NPCFLAG_COUNT] = +{ + { UNIT_NPC_FLAG_AUCTIONEER, LANG_NPCINFO_AUCTIONEER }, + { UNIT_NPC_FLAG_BANKER, LANG_NPCINFO_BANKER }, + { UNIT_NPC_FLAG_BATTLEMASTER, LANG_NPCINFO_BATTLEMASTER }, + { UNIT_NPC_FLAG_FLIGHTMASTER, LANG_NPCINFO_FLIGHTMASTER }, + { UNIT_NPC_FLAG_GOSSIP, LANG_NPCINFO_GOSSIP }, + { UNIT_NPC_FLAG_GUILD_BANKER, LANG_NPCINFO_GUILD_BANKER }, + { UNIT_NPC_FLAG_INNKEEPER, LANG_NPCINFO_INNKEEPER }, + { UNIT_NPC_FLAG_PETITIONER, LANG_NPCINFO_PETITIONER }, + { UNIT_NPC_FLAG_PLAYER_VEHICLE, LANG_NPCINFO_PLAYER_VEHICLE }, + { UNIT_NPC_FLAG_QUESTGIVER, LANG_NPCINFO_QUESTGIVER }, + { UNIT_NPC_FLAG_REPAIR, LANG_NPCINFO_REPAIR }, + { UNIT_NPC_FLAG_SPELLCLICK, LANG_NPCINFO_SPELLCLICK }, + { UNIT_NPC_FLAG_SPIRITGUIDE, LANG_NPCINFO_SPIRITGUIDE }, + { UNIT_NPC_FLAG_SPIRITHEALER, LANG_NPCINFO_SPIRITHEALER }, + { UNIT_NPC_FLAG_STABLEMASTER, LANG_NPCINFO_STABLEMASTER }, + { UNIT_NPC_FLAG_TABARDDESIGNER, LANG_NPCINFO_TABARDDESIGNER }, + { UNIT_NPC_FLAG_TRAINER, LANG_NPCINFO_TRAINER }, + { UNIT_NPC_FLAG_TRAINER_CLASS, LANG_NPCINFO_TRAINER_CLASS }, + { UNIT_NPC_FLAG_TRAINER_PROFESSION, LANG_NPCINFO_TRAINER_PROFESSION }, + { UNIT_NPC_FLAG_VENDOR, LANG_NPCINFO_VENDOR }, + { UNIT_NPC_FLAG_VENDOR_AMMO, LANG_NPCINFO_VENDOR_AMMO }, + { UNIT_NPC_FLAG_VENDOR_FOOD, LANG_NPCINFO_VENDOR_FOOD }, + { UNIT_NPC_FLAG_VENDOR_POISON, LANG_NPCINFO_VENDOR_POISON }, + { UNIT_NPC_FLAG_VENDOR_REAGENT, LANG_NPCINFO_VENDOR_REAGENT } +}; + class npc_commandscript : public CommandScript { public: @@ -619,11 +655,9 @@ public: handler->PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); handler->PSendSysMessage(LANG_NPCINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str()); - if (npcflags & UNIT_NPC_FLAG_VENDOR) - handler->SendSysMessage(LANG_NPCINFO_VENDOR); - - if (npcflags & UNIT_NPC_FLAG_TRAINER) - handler->SendSysMessage(LANG_NPCINFO_TRAINER); + for (uint8 i = 0; i < NPCFLAG_COUNT; i++) + if (npcflags & npcFlagTexts[i].flag) + handler->PSendSysMessage(npcFlagTexts[i].text, npcFlagTexts[i].flag); return true; } -- cgit v1.2.3 From c38d95ac33e44ea30908b5d8e8707848094dd5f0 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sun, 20 Jan 2013 04:30:17 +0100 Subject: Core/Spells: convert some spells to SpellScripts --- .../2013_01_20_03_world_spell_script_names.sql | 81 ++++++ src/server/game/Spells/Auras/SpellAuraEffects.cpp | 284 +-------------------- src/server/game/Spells/Spell.cpp | 5 - src/server/game/Spells/SpellEffects.cpp | 191 +------------- src/server/scripts/Spells/spell_dk.cpp | 107 ++++++++ src/server/scripts/Spells/spell_druid.cpp | 205 +++++++++++++++ src/server/scripts/Spells/spell_generic.cpp | 155 +++++++++++ src/server/scripts/Spells/spell_holiday.cpp | 87 +++++-- src/server/scripts/Spells/spell_item.cpp | 225 ++++++++++++++++ src/server/scripts/Spells/spell_mage.cpp | 178 ++++++++----- src/server/scripts/Spells/spell_paladin.cpp | 111 ++++++++ src/server/scripts/Spells/spell_priest.cpp | 148 ++++++++--- src/server/scripts/Spells/spell_rogue.cpp | 53 ++++ src/server/scripts/Spells/spell_shaman.cpp | 31 +++ src/server/scripts/Spells/spell_warlock.cpp | 38 +++ src/server/scripts/Spells/spell_warrior.cpp | 141 ++++++++++ 16 files changed, 1447 insertions(+), 593 deletions(-) create mode 100644 sql/updates/world/2013_01_20_03_world_spell_script_names.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_20_03_world_spell_script_names.sql b/sql/updates/world/2013_01_20_03_world_spell_script_names.sql new file mode 100644 index 00000000000..0cd28de0472 --- /dev/null +++ b/sql/updates/world/2013_01_20_03_world_spell_script_names.sql @@ -0,0 +1,81 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN ( +48792, -- spell_dk_icebound_fortitude +59754, -- spell_dk_rune_tap_party +55233, -- spell_dk_vampiric_blood +-1850, -- spell_dru_dash +48391, -- spell_dru_owlkin_frenzy +29166, -- spell_dru_innervate +34246, -- spell_dru_idol_lifebloom +60779, -- spell_dru_idol_lifebloom +-1079, -- spell_dru_rip +-61391,-- spell_dru_typhoon +63845, -- spell_gen_create_lance +28702, -- spell_gen_netherbloom +28720, -- spell_gen_nightmare_vine +26400, -- spell_item_arcane_shroud +8342, -- spell_item_goblin_jumper_cables +22999, -- spell_item_goblin_jumper_cables_xl +54732, -- spell_item_gnomish_army_knife +17512, -- spell_item_piccolo_of_the_flaming_fire +48129, -- spell_item_scroll_of_recall +60320, -- spell_item_scroll_of_recall +60321, -- spell_item_scroll_of_recall +28862, -- spell_item_the_eye_of_diminution +-543, -- spell_mage_fire_frost_ward +-6143, -- spell_mage_fire_frost_ward +-11426,-- spell_mage_ice_barrier +-1463, -- spell_mage_mana_shield +1038, -- spell_pal_hand_of_salvation +58597, -- spell_pal_sacred_shield +-7001, -- spell_pri_lightwell_renew +-17, -- spell_pri_power_word_shield +-1943, -- spell_rog_rupture +-51490,-- spell_sha_thunderstorm +-7235, -- spell_warl_shadow_ward +5246, -- spell_warr_intimidating_shout +-772, -- spell_warr_rend +64380, -- spell_warr_shattering_throw +65941, -- spell_warr_shattering_throw +50725, -- spell_warr_vigilance_trigger +26275 -- spell_winter_veil_px_238_winter_wondervolt +); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(48792, 'spell_dk_icebound_fortitude'), +(59754, 'spell_dk_rune_tap_party'), +(55233, 'spell_dk_vampiric_blood'), +(-1850, 'spell_dru_dash'), +(48391, 'spell_dru_owlkin_frenzy'), +(29166, 'spell_dru_innervate'), +(34246, 'spell_dru_idol_lifebloom'), +(60779, 'spell_dru_idol_lifebloom'), +(-1079, 'spell_dru_rip'), +(-61391,'spell_dru_typhoon'), +(63845, 'spell_gen_create_lance'), +(28702, 'spell_gen_netherbloom'), +(28720, 'spell_gen_nightmare_vine'), +(26400, 'spell_item_arcane_shroud'), +(8342, 'spell_item_goblin_jumper_cables'), +(22999, 'spell_item_goblin_jumper_cables_xl'), +(54732, 'spell_item_gnomish_army_knife'), +(17512, 'spell_item_piccolo_of_the_flaming_fire'), +(48129, 'spell_item_scroll_of_recall'), +(60320, 'spell_item_scroll_of_recall'), +(60321, 'spell_item_scroll_of_recall'), +(28862, 'spell_item_the_eye_of_diminution'), +(-543, 'spell_mage_fire_frost_ward'), +(-6143, 'spell_mage_fire_frost_ward'), +(-11426,'spell_mage_ice_barrier'), +(-1463, 'spell_mage_mana_shield'), +(1038, 'spell_pal_hand_of_salvation'), +(58597, 'spell_pal_sacred_shield'), +(-7001, 'spell_pri_lightwell_renew'), +(-17, 'spell_pri_power_word_shield'), +(-1943, 'spell_rog_rupture'), +(-51490,'spell_sha_thunderstorm'), +(-7235, 'spell_warl_shadow_ward'), +(5246, 'spell_warr_intimidating_shout'), +(-772, 'spell_warr_rend'), +(64380, 'spell_warr_shattering_throw'), +(65941, 'spell_warr_shattering_throw'), +(50725, 'spell_warr_vigilance_trigger'), +(26275, 'spell_winter_veil_px_238_winter_wondervolt'); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 3b5c6131c5a..05da36d2ccc 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -483,112 +483,8 @@ int32 AuraEffect::CalculateAmount(Unit* caster) } break; case SPELL_AURA_SCHOOL_ABSORB: - m_canBeRecalculated = false; - if (!caster) - break; - switch (GetSpellInfo()->SpellFamilyName) - { - case SPELLFAMILY_MAGE: - // Ice Barrier - if (GetSpellInfo()->SpellFamilyFlags[1] & 0x1 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) - { - // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; - // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) - // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage - DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); - } - // Fire Ward - else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x8 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) - { - // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; - } - // Frost Ward - else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x100 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) - { - // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; - } - break; - case SPELLFAMILY_WARLOCK: - // Shadow Ward - if (m_spellInfo->SpellFamilyFlags[2] & 0x40) - { - // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; - } - break; - case SPELLFAMILY_PRIEST: - // Power Word: Shield - if (GetSpellInfo()->SpellFamilyFlags[0] & 0x1 && GetSpellInfo()->SpellFamilyFlags[2] & 0x400) - { - // +80.68% from sp bonus - float bonus = 0.8068f; - - // Borrowed Time - if (AuraEffect const* pAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2899, 1)) - bonus += CalculatePct(1.0f, pAurEff->GetAmount()); - - DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus; - // Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) - // Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage - DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); - DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellInfo()); - - amount += int32(DoneActualBenefit); - - // Twin Disciplines - if (AuraEffect const* pAurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PRIEST, 0x400000, 0, 0, caster->GetGUID())) - AddPct(amount, pAurEff->GetAmount()); - - // Focused Power - // Reuse variable, not sure if this code below can be moved before Twin Disciplines - DoneActualBenefit = float(amount); - DoneActualBenefit *= caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT); - amount = int32(DoneActualBenefit); - - return amount; - } - break; - case SPELLFAMILY_PALADIN: - // Sacred Shield - if (m_spellInfo->SpellFamilyFlags[1] & 0x80000) - { - //+75.00% from sp bonus - float bonus = 0.75f; - - DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus; - // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage - DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); - DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellInfo()); - - amount += (int32)DoneActualBenefit; - - // Arena - Dampening - AuraEffect const* pAurEff = caster->GetAuraEffect(74410, 0); - if (!pAurEff) - pAurEff = caster->GetAuraEffect(74411, 0); // Battleground - Dampening - if (pAurEff) - AddPct(amount, pAurEff->GetAmount()); - - return amount; - } - break; - default: - break; - } - break; case SPELL_AURA_MANA_SHIELD: m_canBeRecalculated = false; - if (!caster) - break; - // Mana Shield - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellInfo()->SpellFamilyFlags[0] & 0x8000 && m_spellInfo->SpellFamilyFlags[2] & 0x8) - { - // +80.53% from +spd bonus - DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8053f; - } break; case SPELL_AURA_DUMMY: if (!caster) @@ -600,161 +496,9 @@ int32 AuraEffect::CalculateAmount(Unit* caster) amount = GetBase()->GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); } break; - case SPELL_AURA_PERIODIC_DAMAGE: - if (!caster) - break; - // Rupture - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellInfo->SpellFamilyFlags[0] & 0x100000) - { - m_canBeRecalculated = false; - if (caster->GetTypeId() != TYPEID_PLAYER) - break; - //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs - //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs - //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs - //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs - //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs - float AP_per_combo[6] = {0.0f, 0.015f, 0.024f, 0.03f, 0.03428571f, 0.0375f}; - uint8 cp = caster->ToPlayer()->GetComboPoints(); - if (cp > 5) cp = 5; - amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]); - } - // Rip - else if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[0] & 0x00800000 && GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE) - { - m_canBeRecalculated = false; - // 0.01*$AP*cp - if (caster->GetTypeId() != TYPEID_PLAYER) - break; - - uint8 cp = caster->ToPlayer()->GetComboPoints(); - - // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs - if (AuraEffect const* aurEff = caster->GetAuraEffect(34241, EFFECT_0)) - amount += cp * aurEff->GetAmount(); - // Idol of Worship. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs - else if (AuraEffect const* aurEff = caster->GetAuraEffect(60774, EFFECT_0)) - amount += cp * aurEff->GetAmount(); - - amount += uint32(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK), cp)); - } - // Rend - else if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARRIOR && GetSpellInfo()->SpellFamilyFlags[0] & 0x20) - { - m_canBeRecalculated = false; - // $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick - float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 mws = caster->GetAttackTime(BASE_ATTACK); - float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); - float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); - float mwb = ((mwb_min + mwb_max) / 2 + ap * mws / 14000) * 0.2f; - amount += int32(caster->ApplyEffectModifiers(m_spellInfo, m_effIndex, mwb)); - // "If used while your target is above 75% health, Rend does 35% more damage." - // as for 3.1.3 only ranks above 9 (wrong tooltip?) - if (m_spellInfo->GetRank() >= 9) - { - if (GetBase()->GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, m_spellInfo, caster)) - AddPct(amount, m_spellInfo->Effects[EFFECT_2].CalcValue(caster)); - } - } - break; - case SPELL_AURA_PERIODIC_ENERGIZE: - switch (m_spellInfo->Id) - { - case 29166: // Innervate - ApplyPct(amount, float(GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA)) / GetTotalTicks()); - break; - case 48391: // Owlkin Frenzy - ApplyPct(amount, GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA)); - break; - default: - break; - } - break; - case SPELL_AURA_PERIODIC_HEAL: - if (!caster) - break; - // Lightwell Renew - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags[2] & 0x4000) - { - if (caster->GetTypeId() == TYPEID_PLAYER) - // Bonus from Glyph of Lightwell - if (AuraEffect* modHealing = caster->GetAuraEffect(55673, 0)) - AddPct(amount, modHealing->GetAmount()); - } - break; - case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: - if (!caster) - break; - // Icebound Fortitude - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00100000) - { - if (caster->GetTypeId() == TYPEID_PLAYER) - { - int32 value = (-1 * amount) - 10; - uint32 defva = uint32(caster->ToPlayer()->GetSkillValue(SKILL_DEFENSE) + caster->ToPlayer()->GetRatingBonusValue(CR_DEFENSE_SKILL)); - - if (defva > 400) - value += int32((defva - 400) * 0.15); - - // Glyph of Icebound Fortitude - if (AuraEffect const* aurEff = caster->GetAuraEffect(58625, 0)) - { - int32 valMax = aurEff->GetAmount(); - if (value < valMax) - value = valMax; - } - amount = -value; - } - } - // Hand of Salvation - else if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PALADIN && GetSpellInfo()->SpellFamilyFlags[0] & 0x00000100) - { - //Glyph of Salvation - if (caster->GetGUID() == GetBase()->GetUnitOwner()->GetGUID()) - if (AuraEffect const* aurEff = caster->GetAuraEffect(63225, 0)) - amount = -aurEff->GetAmount(); - } - break; - case SPELL_AURA_MOD_THREAT: - { - uint8 level_diff = 0; - float multiplier = 0.0f; - switch (GetId()) - { - // Arcane Shroud - case 26400: - level_diff = GetBase()->GetUnitOwner()->getLevel() - 60; - multiplier = 2; - break; - // The Eye of Diminution - case 28862: - level_diff = GetBase()->GetUnitOwner()->getLevel() - 60; - multiplier = 1; - break; - } - if (level_diff > 0) - amount += int32(multiplier * level_diff); - break; - } - case SPELL_AURA_MOD_INCREASE_HEALTH: - // Vampiric Blood - if (GetId() == 55233) - amount = GetBase()->GetUnitOwner()->CountPctFromMaxHealth(amount); - break; - case SPELL_AURA_MOD_INCREASE_SPEED: - // Dash - do not set speed if not in cat form - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellFamilyFlags[2] & 0x00000008) - amount = GetBase()->GetUnitOwner()->GetShapeshiftForm() == FORM_CAT ? amount : 0; - break; default: break; } - if (DoneActualBenefit != 0.0f) - { - DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellInfo()); - amount += (int32)DoneActualBenefit; - } GetBase()->CallScriptEffectCalcAmountHandlers(const_cast(this), amount, m_canBeRecalculated); amount *= GetBase()->GetStackAmount(); @@ -848,32 +592,6 @@ void AuraEffect::CalculateSpellMod() { switch (GetAuraType()) { - case SPELL_AURA_DUMMY: - switch (GetSpellInfo()->SpellFamilyName) - { - case SPELLFAMILY_DRUID: - switch (GetId()) - { - case 34246: // Idol of the Emerald Queen - case 60779: // Idol of Lush Moss - { - if (!m_spellmod) - { - m_spellmod = new SpellModifier(GetBase()); - m_spellmod->op = SPELLMOD_DOT; - m_spellmod->type = SPELLMOD_FLAT; - m_spellmod->spellId = GetId(); - m_spellmod->mask[1] = 0x0010; - } - m_spellmod->value = GetAmount()/7; - } - break; - } - break; - default: - break; - } - break; case SPELL_AURA_ADD_FLAT_MODIFIER: case SPELL_AURA_ADD_PCT_MODIFIER: if (!m_spellmod) @@ -882,7 +600,7 @@ void AuraEffect::CalculateSpellMod() m_spellmod->op = SpellModOp(GetMiscValue()); ASSERT(m_spellmod->op < MAX_SPELLMOD); - m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types + m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types m_spellmod->spellId = GetId(); m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask; m_spellmod->charges = GetBase()->GetCharges(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 9bb3eaa31f1..054f6a109db 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1345,11 +1345,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge } } - // todo: move to scripts, but we must call it before resize list by MaxAffectedTargets - // Intimidating Shout - if (m_spellInfo->Id == 5246 && effIndex != EFFECT_0) - unitTargets.remove(m_targets.GetUnitTarget()); - // Other special target selection goes here if (uint32 maxTargets = m_spellValue->MaxAffectedTargets) { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1dddb08be0b..4fdf6654cba 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -883,12 +883,6 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex) m_caster->CastSpell(unitTarget, spell->Id, true); return; } - // Righteous Defense - case 31980: - { - m_caster->CastSpell(unitTarget, 31790, true); - return; - } // Cloak of Shadows case 35729: { @@ -1139,32 +1133,8 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) return; // Pre effects - uint8 uiMaxSafeLevel = 0; switch (m_spellInfo->Id) { - case 48129: // Scroll of Recall - uiMaxSafeLevel = 40; - case 60320: // Scroll of Recall II - if (!uiMaxSafeLevel) - uiMaxSafeLevel = 70; - case 60321: // Scroll of Recal III - if (!uiMaxSafeLevel) - uiMaxSafeLevel = 80; - - if (unitTarget->getLevel() > uiMaxSafeLevel) - { - unitTarget->AddAura(60444, unitTarget); //Apply Lost! Aura - - // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 - uint32 spellId = 60323; - if (m_caster->ToPlayer()->GetTeam() == HORDE) - spellId += 5; - - spellId += urand(0, 7); - m_caster->CastSpell(m_caster, spellId, true); - return; - } - break; case 66550: // teleports outside (Isle of Conquest) if (Player* target = unitTarget->ToPlayer()) { @@ -1188,7 +1158,7 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) // If not exist data for dest location - return if (!m_targets.HasDst()) { - sLog->outError(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTeleportUnits - does not have destination for spell ID %u\n", m_spellInfo->Id); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTeleportUnits - does not have destination for spellId %u.", m_spellInfo->Id); return; } @@ -1585,10 +1555,6 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/) if (!m_originalCaster) return; - // Rune Tap - Party - if (m_spellInfo->Id == 59754 && unitTarget == m_caster) - return; - uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL); heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); @@ -3732,23 +3698,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) return; unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].CalcValue()); break; - // PX-238 Winter Wondervolt TRAP - case 26275: - { - uint32 spells[4] = { 26272, 26157, 26273, 26274 }; - - // check presence - for (uint8 j = 0; j < 4; ++j) - if (unitTarget->HasAuraEffect(spells[j], 0)) - return; - - // select spell - uint32 iTmpSpellId = spells[urand(0, 3)]; - - // cast - unitTarget->CastSpell(unitTarget, iTmpSpellId, true); - return; - } // Bending Shinbone case 8856: { @@ -3794,14 +3743,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) m_caster->CastSpell(unitTarget, 22682, true); return; } - // Piccolo of the Flaming Fire - case 17512: - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); - return; - } // Decimate case 28374: case 54426: @@ -3944,17 +3885,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) m_caster->MonsterTextEmote(buf, 0); break; } - // Vigilance - case 50725: - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Remove Taunt cooldown - unitTarget->ToPlayer()->RemoveSpellCooldown(355, true); - - return; - } // Death Knight Initiate Visual case 51519: { @@ -4113,17 +4043,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } return; } - case 63845: // Create Lance - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - if (m_caster->ToPlayer()->GetTeam() == ALLIANCE) - m_caster->CastSpell(m_caster, 63914, true); - else - m_caster->CastSpell(m_caster, 63919, true); - return; - } case 59317: // Teleporting { @@ -4317,46 +4236,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) return; } } - case SPELLFAMILY_POTION: - { - switch (m_spellInfo->Id) - { - // Netherbloom - case 28702: - { - if (!unitTarget) - return; - // 25% chance of casting a random buff - if (roll_chance_i(75)) - return; - - // triggered spells are 28703 to 28707 - // Note: some sources say, that there was the possibility of - // receiving a debuff. However, this seems to be removed by a patch. - const uint32 spellid = 28703; - - // don't overwrite an existing aura - for (uint8 i = 0; i < 5; ++i) - if (unitTarget->HasAura(spellid + i)) - return; - unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); - break; - } - - // Nightmare Vine - case 28720: - { - if (!unitTarget) - return; - // 25% chance of casting Nightmare Pollen - if (roll_chance_i(75)) - return; - unitTarget->CastSpell(unitTarget, 28721, true); - break; - } - } - break; - } case SPELLFAMILY_DEATHKNIGHT: { // Pestilence @@ -4377,19 +4256,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } break; } - case SPELLFAMILY_WARRIOR: - { - // Shattering Throw - if (m_spellInfo->SpellFamilyFlags[1] & 0x00400000) - { - if (!unitTarget) - return; - // remove shields, will still display immune to damage part - unitTarget->RemoveAurasWithMechanic(1<GetTypeId() != TYPEID_PLAYER) + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - if (unitTarget->isAlive()) + if (unitTarget->isAlive() || !unitTarget->IsInWorld()) return; - if (!unitTarget->IsInWorld()) - return; - - switch (m_spellInfo->Id) - { - // Defibrillate (Goblin Jumper Cables) have 33% chance on success - case 8342: - if (roll_chance_i(67)) - { - m_caster->CastSpell(m_caster, 8338, true, m_CastItem); - return; - } - break; - // Defibrillate (Goblin Jumper Cables XL) have 50% chance on success - case 22999: - if (roll_chance_i(50)) - { - m_caster->CastSpell(m_caster, 23055, true, m_CastItem); - return; - } - break; - // Defibrillate (Gnomish Army Knife) have 67% chance on success_list - case 54732: - if (roll_chance_i(33)) - { - return; - } - break; - default: - break; - } Player* target = unitTarget->ToPlayer(); @@ -5151,26 +4984,10 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss()) return; - // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT/STUN + // Spells with SPELL_EFFECT_KNOCK_BACK (like Thunderstorm) can't knockback target if target has ROOT/STUN if (unitTarget->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) return; - // Typhoon - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x01000000) - { - // Glyph of Typhoon - if (m_caster->HasAura(62135)) - return; - } - - // Thunderstorm - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[1] & 0x00002000) - { - // Glyph of Thunderstorm - if (m_caster->HasAura(62132)) - return; - } - // Instantly interrupt non melee spells being casted if (unitTarget->IsNonMeleeSpellCasted(true)) unitTarget->InterruptNonMeleeSpells(true); diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 060db02d53c..62a0599dab1 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -37,6 +37,7 @@ enum DeathKnightSpells SPELL_DK_DEATH_COIL_HEAL = 47633, SPELL_DK_DEATH_STRIKE_HEAL = 45470, SPELL_DK_GHOUL_EXPLODE = 47496, + SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE = 58625, SPELL_DK_RUNIC_POWER_ENERGIZE = 49088, SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890, SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, @@ -584,6 +585,55 @@ class spell_dk_ghoul_explode : public SpellScriptLoader } }; +// 48792 - Icebound Fortitude +class spell_dk_icebound_fortitude : public SpellScriptLoader +{ + public: + spell_dk_icebound_fortitude() : SpellScriptLoader("spell_dk_icebound_fortitude") { } + + class spell_dk_icebound_fortitude_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_icebound_fortitude_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + int32 value = amount; + uint32 defValue = uint32(caster->ToPlayer()->GetSkillValue(SKILL_DEFENSE) + caster->ToPlayer()->GetRatingBonusValue(CR_DEFENSE_SKILL)); + + if (defValue > 400) + value -= int32((defValue - 400) * 0.15); + + // Glyph of Icebound Fortitude + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE, EFFECT_0)) + { + int32 valMax = -aurEff->GetAmount(); + if (value > valMax) + value = valMax; + } + amount = value; + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_icebound_fortitude_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_icebound_fortitude_AuraScript(); + } +}; + // 50365, 50371 - Improved Blood Presence class spell_dk_improved_blood_presence : public SpellScriptLoader { @@ -677,6 +727,33 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader } }; +// 59754 Rune Tap - Party +class spell_dk_rune_tap_party : public SpellScriptLoader +{ + public: + spell_dk_rune_tap_party() : SpellScriptLoader("spell_dk_rune_tap_party") { } + + class spell_dk_rune_tap_party_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dk_rune_tap_party_SpellScript); + + void CheckTargets(std::list& targets) + { + targets.remove(GetCaster()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_rune_tap_party_SpellScript::CheckTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dk_rune_tap_party_SpellScript(); + } +}; + // 55090 - Scourge Strike (55265, 55270, 55271) class spell_dk_scourge_strike : public SpellScriptLoader { @@ -784,6 +861,33 @@ class spell_dk_spell_deflection : public SpellScriptLoader } }; +// 55233 - Vampiric Blood +class spell_dk_vampiric_blood : public SpellScriptLoader +{ + public: + spell_dk_vampiric_blood() : SpellScriptLoader("spell_dk_vampiric_blood") { } + + class spell_dk_vampiric_blood_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_vampiric_blood_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + amount = GetUnitOwner()->CountPctFromMaxHealth(amount); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_vampiric_blood_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_HEALTH); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_vampiric_blood_AuraScript(); + } +}; + // 52284 - Will of the Necropolis class spell_dk_will_of_the_necropolis : public SpellScriptLoader { @@ -861,9 +965,12 @@ void AddSC_deathknight_spell_scripts() new spell_dk_death_pact(); new spell_dk_death_strike(); new spell_dk_ghoul_explode(); + new spell_dk_icebound_fortitude(); new spell_dk_improved_blood_presence(); new spell_dk_improved_unholy_presence(); + new spell_dk_rune_tap_party(); new spell_dk_scourge_strike(); new spell_dk_spell_deflection(); + new spell_dk_vampiric_blood(); new spell_dk_will_of_the_necropolis(); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 6dd453597de..e2b918e1c7f 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -30,6 +30,9 @@ enum DruidSpells { SPELL_DRUID_ENRAGE_MOD_DAMAGE = 51185, + SPELL_DRUID_GLYPH_OF_TYPHOON = 62135, + SPELL_DRUID_IDOL_OF_FERAL_SHADOWS = 34241, + SPELL_DRUID_IDOL_OF_WORSHIP = 60774, SPELL_DRUID_INCREASED_MOONFIRE_DURATION = 38414, SPELL_DRUID_KING_OF_THE_JUNGLE = 48492, SPELL_DRUID_LIFEBLOOM_ENERGIZE = 64372, @@ -41,6 +44,35 @@ enum DruidSpells SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, }; +// -1850 - Dash +class spell_dru_dash : public SpellScriptLoader +{ + public: + spell_dru_dash() : SpellScriptLoader("spell_dru_dash") { } + + class spell_dru_dash_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_dash_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // do not set speed if not in cat form + if (GetUnitOwner()->GetShapeshiftForm() != FORM_CAT) + amount = 0; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_dash_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_INCREASE_SPEED); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_dash_AuraScript(); + } +}; + // -5229 - Enrage class spell_dru_enrage : public SpellScriptLoader { @@ -121,6 +153,69 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader } }; +// 34246 - Idol of the Emerald Queen +// 60779 - Idol of Lush Moss +class spell_dru_idol_lifebloom : public SpellScriptLoader +{ + public: + spell_dru_idol_lifebloom() : SpellScriptLoader("spell_dru_idol_lifebloom") { } + + class spell_dru_idol_lifebloom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_idol_lifebloom_AuraScript); + + void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) + { + if (!spellMod) + { + spellMod = new SpellModifier(GetAura()); + spellMod->op = SPELLMOD_DOT; + spellMod->type = SPELLMOD_FLAT; + spellMod->spellId = GetId(); + spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask; + } + spellMod->value = aurEff->GetAmount() / 7; + } + + void Register() + { + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_dru_idol_lifebloom_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_idol_lifebloom_AuraScript(); + } +}; + +// 29166 - Innervate +class spell_dru_innervate : public SpellScriptLoader +{ + public: + spell_dru_innervate() : SpellScriptLoader("spell_dru_innervate") { } + + class spell_dru_innervate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_innervate_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + amount = CalculatePct(int32(GetUnitOwner()->GetCreatePowers(POWER_MANA) / aurEff->GetTotalTicks()), amount); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_innervate_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_innervate_AuraScript(); + } +}; + // -5570 - Insect Swarm class spell_dru_insect_swarm : public SpellScriptLoader { @@ -276,6 +371,33 @@ class spell_dru_moonkin_form_passive : public SpellScriptLoader } }; +// 48391 - Owlkin Frenzy +class spell_dru_owlkin_frenzy : public SpellScriptLoader +{ + public: + spell_dru_owlkin_frenzy() : SpellScriptLoader("spell_dru_owlkin_frenzy") { } + + class spell_dru_owlkin_frenzy_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_owlkin_frenzy_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + amount = CalculatePct(GetUnitOwner()->GetCreatePowers(POWER_MANA), amount); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_owlkin_frenzy_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_PERIODIC_ENERGIZE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_owlkin_frenzy_AuraScript(); + } +}; + // -16972 - Predatory Strikes class spell_dru_predatory_strikes : public SpellScriptLoader { @@ -349,6 +471,54 @@ class spell_dru_primal_tenacity : public SpellScriptLoader } }; +// -1079 - Rip +class spell_dru_rip : public SpellScriptLoader +{ + public: + spell_dru_rip() : SpellScriptLoader("spell_dru_rip") { } + + class spell_dru_rip_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_rip_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + + if (Unit* caster = GetCaster()) + { + // 0.01 * $AP * cp + uint8 cp = caster->ToPlayer()->GetComboPoints(); + + // Idol of Feral Shadows. Can't be handled as SpellMod due its dependency from CPs + if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_FERAL_SHADOWS, EFFECT_0)) + amount += cp * idol->GetAmount(); + // Idol of Worship. Can't be handled as SpellMod due its dependency from CPs + else if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_WORSHIP, EFFECT_0)) + amount += cp * idol->GetAmount(); + + amount += int32(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK), cp)); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_rip_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_rip_AuraScript(); + } +}; + // 62606 - Savage Defense class spell_dru_savage_defense : public SpellScriptLoader { @@ -658,6 +828,35 @@ class spell_dru_tiger_s_fury : public SpellScriptLoader } }; +// -61391 - Typhoon +class spell_dru_typhoon : public SpellScriptLoader +{ + public: + spell_dru_typhoon() : SpellScriptLoader("spell_dru_typhoon") { } + + class spell_dru_typhoon_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_typhoon_SpellScript); + + void HandleKnockBack(SpellEffIndex effIndex) + { + // Glyph of Typhoon + if (GetCaster()->HasAura(SPELL_DRUID_GLYPH_OF_TYPHOON)) + PreventHitDefaultEffect(effIndex); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_dru_typhoon_SpellScript::HandleKnockBack, EFFECT_0, SPELL_EFFECT_KNOCK_BACK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dru_typhoon_SpellScript(); + } +}; + // 70691 - Item T10 Restoration 4P Bonus class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader { @@ -715,13 +914,18 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader void AddSC_druid_spell_scripts() { + new spell_dru_dash(); new spell_dru_enrage(); new spell_dru_glyph_of_starfire(); + new spell_dru_idol_lifebloom(); + new spell_dru_innervate(); new spell_dru_insect_swarm(); new spell_dru_lifebloom(); new spell_dru_moonkin_form_passive(); + new spell_dru_owlkin_frenzy(); new spell_dru_predatory_strikes(); new spell_dru_primal_tenacity(); + new spell_dru_rip(); new spell_dru_savage_defense(); new spell_dru_savage_roar(); new spell_dru_starfall_aoe(); @@ -729,5 +933,6 @@ void AddSC_druid_spell_scripts() new spell_dru_survival_instincts(); new spell_dru_swift_flight_passive(); new spell_dru_tiger_s_fury(); + new spell_dru_typhoon(); new spell_dru_t10_restoration_4p_bonus(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index b5f4312bae5..6004ec6cf89 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -226,6 +226,158 @@ class spell_gen_cannibalize : public SpellScriptLoader } }; +// 63845 - Create Lance +enum CreateLanceSpells +{ + SPELL_CREATE_LANCE_ALLIANCE = 63914, + SPELL_CREATE_LANCE_HORDE = 63919 +}; + +class spell_gen_create_lance : public SpellScriptLoader +{ + public: + spell_gen_create_lance() : SpellScriptLoader("spell_gen_create_lance") { } + + class spell_gen_create_lance_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_create_lance_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_ALLIANCE) || !sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_HORDE)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Player* target = GetHitPlayer()) + { + if (target->GetTeam() == ALLIANCE) + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true); + else + GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_create_lance_SpellScript(); + } +}; + +// 28702 - Netherbloom +enum Netherbloom +{ + SPELL_NETHERBLOOM_POLLEN_1 = 28703 +}; + +class spell_gen_netherbloom : public SpellScriptLoader +{ + public: + spell_gen_netherbloom() : SpellScriptLoader("spell_gen_netherbloom") { } + + class spell_gen_netherbloom_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_netherbloom_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + for (uint8 i = 0; i < 5; ++i) + if (!sSpellMgr->GetSpellInfo(SPELL_NETHERBLOOM_POLLEN_1 + i)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Unit* target = GetHitUnit()) + { + // 25% chance of casting a random buff + if (roll_chance_i(75)) + return; + + // triggered spells are 28703 to 28707 + // Note: some sources say, that there was the possibility of + // receiving a debuff. However, this seems to be removed by a patch. + + // don't overwrite an existing aura + for (uint8 i = 0; i < 5; ++i) + if (target->HasAura(SPELL_NETHERBLOOM_POLLEN_1 + i)) + return; + + target->CastSpell(target, SPELL_NETHERBLOOM_POLLEN_1 + urand(0, 4), true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_netherbloom_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_netherbloom_SpellScript(); + } +}; + +// 28720 - Nightmare Vine +enum NightmareVine +{ + SPELL_NIGHTMARE_POLLEN = 28721 +}; + +class spell_gen_nightmare_vine : public SpellScriptLoader +{ + public: + spell_gen_nightmare_vine() : SpellScriptLoader("spell_gen_nightmare_vine") { } + + class spell_gen_nightmare_vine_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_nightmare_vine_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_NIGHTMARE_POLLEN)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Unit* target = GetHitUnit()) + { + // 25% chance of casting Nightmare Pollen + if (roll_chance_i(25)) + target->CastSpell(target, SPELL_NIGHTMARE_POLLEN, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_nightmare_vine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_nightmare_vine_SpellScript(); + } +}; + // 45472 Parachute enum ParachuteSpells { @@ -3195,6 +3347,9 @@ void AddSC_generic_spell_scripts() new spell_gen_av_drekthar_presence(); new spell_gen_burn_brutallus(); new spell_gen_cannibalize(); + new spell_gen_create_lance(); + new spell_gen_netherbloom(); + new spell_gen_nightmare_vine(); new spell_gen_parachute(); new spell_gen_pet_summoned(); new spell_gen_remove_flight_auras(); diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp index d883b4d7da7..dbfc2b44501 100644 --- a/src/server/scripts/Spells/spell_holiday.cpp +++ b/src/server/scripts/Spells/spell_holiday.cpp @@ -303,27 +303,10 @@ class spell_winter_veil_mistletoe : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); - if (Player* target = GetHitPlayer()) { - uint32 spellId = 0; - switch (urand(0, 2)) - { - case 0: - spellId = SPELL_CREATE_MISTLETOE; - break; - case 1: - spellId = SPELL_CREATE_HOLLY; - break; - case 2: - spellId = SPELL_CREATE_SNOWFLAKES; - break; - default: - return; - } - - caster->CastSpell(target, spellId, true); + uint32 spellId = RAND(SPELL_CREATE_HOLLY, SPELL_CREATE_MISTLETOE, SPELL_CREATE_SNOWFLAKES); + GetCaster()->CastSpell(target, spellId, true); } } @@ -339,6 +322,71 @@ class spell_winter_veil_mistletoe : public SpellScriptLoader } }; +// 26275 - PX-238 Winter Wondervolt TRAP +enum PX238WinterWondervolt +{ + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1 = 26157, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2 = 26272, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3 = 26273, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4 = 26274 +}; + +class spell_winter_veil_px_238_winter_wondervolt : public SpellScriptLoader +{ + public: + spell_winter_veil_px_238_winter_wondervolt() : SpellScriptLoader("spell_winter_veil_px_238_winter_wondervolt") { } + + class spell_winter_veil_px_238_winter_wondervolt_SpellScript : public SpellScript + { + PrepareSpellScript(spell_winter_veil_px_238_winter_wondervolt_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3) || + !sSpellMgr->GetSpellInfo(SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + uint32 const spells[4] = + { + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_1, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_2, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_3, + SPELL_PX_238_WINTER_WONDERVOLT_TRANSFORM_4 + }; + + if (Unit* target = GetHitUnit()) + { + for (uint8 i = 0; i < 4; ++i) + if (target->HasAura(spells[i])) + return; + + GetCaster()->CastSpell(target, spells[urand(0, 3)], true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_winter_veil_px_238_winter_wondervolt_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + + private: + + }; + + SpellScript* GetSpellScript() const + { + return new spell_winter_veil_px_238_winter_wondervolt_SpellScript(); + } +}; + void AddSC_holiday_spell_scripts() { // Love is in the Air @@ -349,4 +397,5 @@ void AddSC_holiday_spell_scripts() new spell_hallow_end_tricky_treat(); // Winter Veil new spell_winter_veil_mistletoe(); + new spell_winter_veil_px_238_winter_wondervolt(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index b4e06cb6b48..c38d05bc02a 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -73,6 +73,93 @@ class spell_item_trigger_spell : public SpellScriptLoader } }; +// 26400 - Arcane Shroud +class spell_item_arcane_shroud : public SpellScriptLoader +{ + public: + spell_item_arcane_shroud() : SpellScriptLoader("spell_item_arcane_shroud") { } + + class spell_item_arcane_shroud_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_arcane_shroud_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += 2 * diff; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_arcane_shroud_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_arcane_shroud_AuraScript(); + } +}; + +// 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success +// 22999 - Defibrillate (Goblin Jumper Cables XL) have 50% chance on success +// 54732 - Defibrillate (Gnomish Army Knife) have 67% chance on success +enum Defibrillate +{ + SPELL_GOBLIN_JUMPER_CABLES_FAIL = 8338, + SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL = 23055 +}; + +class spell_item_defibrillate : public SpellScriptLoader +{ + public: + spell_item_defibrillate(char const* name, uint8 chance, uint32 failSpell = 0) : SpellScriptLoader(name), _chance(chance), _failSpell(failSpell) { } + + class spell_item_defibrillate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_defibrillate_SpellScript); + + public: + spell_item_defibrillate_SpellScript(uint8 chance, uint32 failSpell) : SpellScript(), _chance(chance), _failSpell(failSpell) { } + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (_failSpell && !sSpellMgr->GetSpellInfo(_failSpell)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + if (roll_chance_i(_chance)) + { + PreventHitDefaultEffect(effIndex); + if (_failSpell) + GetCaster()->CastSpell(GetCaster(), _failSpell, true, GetCastItem()); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_defibrillate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_RESURRECT); + } + + private: + uint8 _chance; + uint32 _failSpell; + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_defibrillate_SpellScript(_chance, _failSpell); + } + + private: + uint8 _chance; + uint32 _failSpell; +}; + // http://www.wowhead.com/item=6522 Deviate Fish // 8063 Deviate Fish enum DeviateFishSpells @@ -464,6 +551,35 @@ class spell_item_noggenfogger_elixir : public SpellScriptLoader } }; +// 17512 - Piccolo of the Flaming Fire +class spell_item_piccolo_of_the_flaming_fire : public SpellScriptLoader +{ + public: + spell_item_piccolo_of_the_flaming_fire() : SpellScriptLoader("spell_item_piccolo_of_the_flaming_fire") { } + + class spell_item_piccolo_of_the_flaming_fire_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_piccolo_of_the_flaming_fire_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) + target->HandleEmoteCommand(EMOTE_STATE_DANCE); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_piccolo_of_the_flaming_fire_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_piccolo_of_the_flaming_fire_SpellScript(); + } +}; + // http://www.wowhead.com/item=6657 Savory Deviate Delight // 8213 Savory Deviate Delight enum SavoryDeviateDelight @@ -522,6 +638,79 @@ class spell_item_savory_deviate_delight : public SpellScriptLoader } }; +// 48129 - Scroll of Recall +// 60320 - Scroll of Recall II +// 60321 - Scroll of Recall III +enum ScrollOfRecall +{ + SPELL_SCROLL_OF_RECALL_I = 48129, + SPELL_SCROLL_OF_RECALL_II = 60320, + SPELL_SCROLL_OF_RECALL_III = 60321, + SPELL_LOST = 60444, + SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1 = 60323, + SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1 = 60328, +}; + +class spell_item_scroll_of_recall : public SpellScriptLoader +{ + public: + spell_item_scroll_of_recall() : SpellScriptLoader("spell_item_scroll_of_recall") { } + + class spell_item_scroll_of_recall_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_scroll_of_recall_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + uint8 maxSafeLevel = 0; + switch (GetSpellInfo()->Id) + { + case SPELL_SCROLL_OF_RECALL_I: // Scroll of Recall + maxSafeLevel = 40; + break; + case SPELL_SCROLL_OF_RECALL_II: // Scroll of Recall II + maxSafeLevel = 70; + break; + case SPELL_SCROLL_OF_RECALL_III: // Scroll of Recal III + maxSafeLevel = 80; + break; + default: + break; + } + + if (caster->getLevel() > maxSafeLevel) + { + caster->CastSpell(caster, SPELL_LOST, true); + + // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 + uint32 spellId = SPELL_SCROLL_OF_RECALL_FAIL_ALLIANCE_1; + if (GetCaster()->ToPlayer()->GetTeam() == HORDE) + spellId = SPELL_SCROLL_OF_RECALL_FAIL_HORDE_1; + + GetCaster()->CastSpell(GetCaster(), spellId + urand(0, 7), true); + + PreventHitDefaultEffect(effIndex); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_scroll_of_recall_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_scroll_of_recall_SpellScript(); + } +}; + // http://www.wowhead.com/item=7734 Six Demon Bag // 14537 Six Demon Bag enum SixDemonBagSpells @@ -593,6 +782,35 @@ class spell_item_six_demon_bag : public SpellScriptLoader } }; +// 28862 - The Eye of Diminution +class spell_item_the_eye_of_diminution : public SpellScriptLoader +{ + public: + spell_item_the_eye_of_diminution() : SpellScriptLoader("spell_item_the_eye_of_diminution") { } + + class spell_item_the_eye_of_diminution_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_the_eye_of_diminution_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + int32 diff = GetUnitOwner()->getLevel() - 60; + if (diff > 0) + amount += diff; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_the_eye_of_diminution_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_THREAT); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_the_eye_of_diminution_AuraScript(); + } +}; + // http://www.wowhead.com/item=44012 Underbelly Elixir // 59640 Underbelly Elixir enum UnderbellyElixirSpells @@ -2030,6 +2248,10 @@ void AddSC_item_spell_scripts() // 23075 Mithril Mechanical Dragonling new spell_item_trigger_spell("spell_item_mithril_mechanical_dragonling", SPELL_MITHRIL_MECHANICAL_DRAGONLING); + new spell_item_arcane_shroud(); + new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); + new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); + new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); new spell_item_deviate_fish(); new spell_item_flask_of_the_north(); new spell_item_gnomish_death_ray(); @@ -2037,8 +2259,11 @@ void AddSC_item_spell_scripts() new spell_item_mingos_fortune_generator(); new spell_item_net_o_matic(); new spell_item_noggenfogger_elixir(); + new spell_item_piccolo_of_the_flaming_fire(); new spell_item_savory_deviate_delight(); + new spell_item_scroll_of_recall(); new spell_item_six_demon_bag(); + new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); new spell_item_shadowmourne(); new spell_item_red_rider_air_rifle(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 61f0579190f..a673759a49e 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -29,7 +29,7 @@ enum MageSpells { SPELL_MAGE_COLD_SNAP = 11958, - SPELL_MAGE_FROST_WARDING_R1 = 28332, + SPELL_MAGE_FROST_WARDING_R1 = 11189, SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, SPELL_MAGE_INCANTERS_ABSORBTION_R1 = 44394, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED = 44413, @@ -45,6 +45,31 @@ enum MageSpells SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126, }; +// Incanter's Absorbtion +class spell_mage_incanters_absorbtion_base_AuraScript : public AuraScript +{ + public: + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_R1)) + return false; + return true; + } + + void Trigger(AuraEffect* aurEff, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) + { + Unit* target = GetTarget(); + + if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_INCANTERS_ABSORBTION_R1, EFFECT_0)) + { + int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); + target->CastCustomSpell(target, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + } + } +}; + // -11113 - Blast Wave class spell_mage_blast_wave : public SpellScriptLoader { @@ -127,29 +152,47 @@ class spell_mage_cold_snap : public SpellScriptLoader } }; -// -543, -6143 - Frost Warding -class spell_mage_frost_warding_trigger : public SpellScriptLoader +// -543 - Fire Ward +// -6143 - Frost Ward +class spell_mage_fire_frost_ward : public SpellScriptLoader { public: - spell_mage_frost_warding_trigger() : SpellScriptLoader("spell_mage_frost_warding_trigger") { } + spell_mage_fire_frost_ward() : SpellScriptLoader("spell_mage_fire_frost_ward") { } - class spell_mage_frost_warding_trigger_AuraScript : public AuraScript + class spell_mage_fire_frost_ward_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript { - PrepareAuraScript(spell_mage_frost_warding_trigger_AuraScript); + PrepareAuraScript(spell_mage_fire_frost_ward_AuraScript); bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1)) return false; return true; } - void Absorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + } + } + + void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) { Unit* target = GetTarget(); if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_FROST_WARDING_R1, EFFECT_0)) { - int32 chance = talentAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + int32 chance = talentAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // SPELL_EFFECT_DUMMY with NO_TARGET if (roll_chance_i(chance)) { @@ -164,79 +207,58 @@ class spell_mage_frost_warding_trigger : public SpellScriptLoader void Register() { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_mage_frost_warding_trigger_AuraScript::Absorb, EFFECT_0); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_fire_frost_ward_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_mage_fire_frost_ward_AuraScript::Absorb, EFFECT_0); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_fire_frost_ward_AuraScript::Trigger, EFFECT_0); } }; AuraScript* GetAuraScript() const { - return new spell_mage_frost_warding_trigger_AuraScript(); + return new spell_mage_fire_frost_ward_AuraScript(); } }; -class spell_mage_incanters_absorbtion_base_AuraScript : public AuraScript +// -11426 - Ice Barrier +class spell_mage_ice_barrier : public SpellScriptLoader { public: + spell_mage_ice_barrier() : SpellScriptLoader("spell_mage_ice_barrier") { } - bool Validate(SpellInfo const* /*spellInfo*/) - { - return sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED) - && sSpellMgr->GetSpellInfo(SPELL_MAGE_INCANTERS_ABSORBTION_R1); - } - - void Trigger(AuraEffect* aurEff, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount) + class spell_mage_ice_barrier_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript { - Unit* target = GetTarget(); + PrepareAuraScript(spell_mage_ice_barrier_AuraScript); - if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_INCANTERS_ABSORBTION_R1, EFFECT_0)) + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) { - int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); - target->CastCustomSpell(target, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); - } - } -}; - -// -543, -6143, -11426 - Incanter's Absorption -class spell_mage_incanters_absorbtion_absorb : public SpellScriptLoader -{ - public: - spell_mage_incanters_absorbtion_absorb() : SpellScriptLoader("spell_mage_incanters_absorbtion_absorb") { } + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; - class spell_mage_incanters_absorbtion_absorb_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript - { - PrepareAuraScript(spell_mage_incanters_absorbtion_absorb_AuraScript); + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); - void Register() - { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_incanters_absorbtion_absorb_AuraScript::Trigger, EFFECT_0); - } - }; + // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) + // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage + bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); - AuraScript* GetAuraScript() const - { - return new spell_mage_incanters_absorbtion_absorb_AuraScript(); - } -}; + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); -// -1463 - Incanter's Absorption -class spell_mage_incanters_absorbtion_manashield : public SpellScriptLoader -{ - public: - spell_mage_incanters_absorbtion_manashield() : SpellScriptLoader("spell_mage_incanters_absorbtion_manashield") { } - - class spell_mage_incanters_absorbtion_manashield_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript - { - PrepareAuraScript(spell_mage_incanters_absorbtion_manashield_AuraScript); + amount += int32(bonus); + } + } void Register() { - AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_incanters_absorbtion_manashield_AuraScript::Trigger, EFFECT_0); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_ice_barrier_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_ice_barrier_AuraScript::Trigger, EFFECT_0); } }; AuraScript* GetAuraScript() const { - return new spell_mage_incanters_absorbtion_manashield_AuraScript(); + return new spell_mage_ice_barrier_AuraScript(); } }; @@ -279,6 +301,44 @@ class spell_mage_living_bomb : public SpellScriptLoader } }; +// -1463 - Mana Shield +class spell_mage_mana_shield : public SpellScriptLoader +{ + public: + spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { } + + class spell_mage_mana_shield_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript + { + PrepareAuraScript(spell_mage_mana_shield_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.53% from sp bonus + float bonus = 0.8053f; + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_mana_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MANA_SHIELD); + AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_mana_shield_AuraScript::Trigger, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_mana_shield_AuraScript(); + } +}; + enum SilvermoonPolymorph { NPC_AUROSALIA = 18744, @@ -378,10 +438,10 @@ void AddSC_mage_spell_scripts() { new spell_mage_blast_wave(); new spell_mage_cold_snap(); - new spell_mage_frost_warding_trigger(); - new spell_mage_incanters_absorbtion_absorb(); - new spell_mage_incanters_absorbtion_manashield(); + new spell_mage_fire_frost_ward(); + new spell_mage_ice_barrier(); new spell_mage_living_bomb(); + new spell_mage_mana_shield(); new spell_mage_polymorph_cast_visual(); new spell_mage_summon_water_elemental(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index d3fc86302e1..2f22de97d77 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -51,6 +51,13 @@ enum PaladinSpells SPELL_PALADIN_HAND_OF_SACRIFICE = 6940, SPELL_PALADIN_DIVINE_SACRIFICE = 64205, + + SPELL_PALADIN_GLYPH_OF_SALVATION = 63225, + + SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, + + SPELL_GENERIC_ARENA_DAMPENING = 74410, + SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411 }; // 31850 - Ardent Defender @@ -490,6 +497,39 @@ class spell_pal_hand_of_sacrifice : public SpellScriptLoader } }; +// 1038 - Hand of Salvation +class spell_pal_hand_of_salvation : public SpellScriptLoader +{ + public: + spell_pal_hand_of_salvation() : SpellScriptLoader("spell_pal_hand_of_salvation") { } + + class spell_pal_hand_of_salvation_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_hand_of_salvation_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + // Glyph of Salvation + if (caster->GetGUID() == GetUnitOwner()->GetGUID()) + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_PALADIN_GLYPH_OF_SALVATION, EFFECT_0)) + amount -= aurEff->GetAmount(); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_hand_of_salvation_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_hand_of_salvation_AuraScript(); + } +}; + // -20473 - Holy Shock class spell_pal_holy_shock : public SpellScriptLoader { @@ -656,6 +696,13 @@ class spell_pal_righteous_defense : public SpellScriptLoader { PrepareSpellScript(spell_pal_righteous_defense_SpellScript); + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT)) + return false; + return true; + } + SpellCastResult CheckCast() { Unit* caster = GetCaster(); @@ -673,9 +720,27 @@ class spell_pal_righteous_defense : public SpellScriptLoader return SPELL_CAST_OK; } + void HandleTriggerSpellLaunch(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + } + + void HandleTriggerSpellHit(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Unit* target = GetHitUnit()) + GetCaster()->CastSpell(target, SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT, true); + } + void Register() { OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast); + //! WORKAROUND + //! target select will be executed in hitphase of effect 0 + //! so we must handle trigger spell also in hit phase (default execution in launch phase) + //! see issue #3718 + OnEffectLaunchTarget += SpellEffectFn(spell_pal_righteous_defense_SpellScript::HandleTriggerSpellLaunch, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); + OnEffectHitTarget += SpellEffectFn(spell_pal_righteous_defense_SpellScript::HandleTriggerSpellHit, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL); } }; @@ -685,6 +750,50 @@ class spell_pal_righteous_defense : public SpellScriptLoader } }; +// 58597 - Sacred Shield +class spell_pal_sacred_shield : public SpellScriptLoader +{ + public: + spell_pal_sacred_shield() : SpellScriptLoader("spell_pal_sacred_shield") { } + + class spell_pal_sacred_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_sacred_shield_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + // +75.00% from sp bonus + float bonus = CalculatePct(caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()), 75.0f); + + // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage + bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + + // Arena - Dampening + if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) + AddPct(amount, dampening->GetAmount()); + // Battleground - Dampening + else if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) + AddPct(amount, dampening->GetAmount()); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_sacred_shield_AuraScript(); + } +}; + void AddSC_paladin_spell_scripts() { new spell_pal_ardent_defender(); @@ -696,8 +805,10 @@ void AddSC_paladin_spell_scripts() new spell_pal_exorcism_and_holy_wrath_damage(); new spell_pal_guarded_by_the_light(); new spell_pal_hand_of_sacrifice(); + new spell_pal_hand_of_salvation(); new spell_pal_holy_shock(); new spell_pal_judgement_of_command(); new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); + new spell_pal_sacred_shield(); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 1c416a0d28a..23a39819aa2 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -30,6 +30,7 @@ enum PriestSpells { SPELL_PRIEST_EMPOWERED_RENEW = 63544, + SPELL_PRIEST_GLYPHE_OF_LIGHTWELL = 55673, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, SPELL_PRIEST_PENANCE_R1 = 47540, SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, @@ -43,6 +44,7 @@ enum PriestSpells enum PriestSpellIcons { + PRIEST_ICON_ID_BORROWED_TIME = 2899, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, }; @@ -104,6 +106,38 @@ class spell_pri_guardian_spirit : public SpellScriptLoader } }; +// -7001 - Lightwell Renew +class spell_pri_lightwell_renew : public SpellScriptLoader +{ + public: + spell_pri_lightwell_renew() : SpellScriptLoader("spell_pri_lightwell_renew") { } + + class spell_pri_lightwell_renew_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_lightwell_renew_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + // Bonus from Glyph of Lightwell + if (AuraEffect* modHealing = caster->GetAuraEffect(SPELL_PRIEST_GLYPHE_OF_LIGHTWELL, EFFECT_0)) + AddPct(amount, modHealing->GetAmount()); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_lightwell_renew_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_lightwell_renew_AuraScript(); + } +}; + // -8129 - Mana Burn class spell_pri_mana_burn : public SpellScriptLoader { @@ -260,81 +294,114 @@ class spell_pri_penance : public SpellScriptLoader } }; -// 33110 - Prayer of Mending Heal -class spell_pri_prayer_of_mending_heal : public SpellScriptLoader +// -17 - Power Word: Shield +class spell_pri_power_word_shield : public SpellScriptLoader { public: - spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } + spell_pri_power_word_shield() : SpellScriptLoader("spell_pri_power_word_shield") { } - class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript + class spell_pri_power_word_shield_AuraScript : public AuraScript { - PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); + PrepareAuraScript(spell_pri_power_word_shield_AuraScript); - void HandleHeal(SpellEffIndex /*effIndex*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (Unit* caster = GetOriginalCaster()) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_R1)) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) { - if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_PRIEST_T9_HEALING_2P, EFFECT_0)) + // +80.68% from sp bonus + float bonus = 0.8068f; + + // Borrowed Time + if (AuraEffect const* borrowedTime = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_BORROWED_TIME, EFFECT_1)) + bonus += CalculatePct(1.0f, borrowedTime->GetAmount()); + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + + // Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) + // Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage + bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + + // Twin Disciplines + if (AuraEffect const* twinDisciplines = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PRIEST, 0x400000, 0, 0, GetCasterGUID())) + AddPct(amount, twinDisciplines->GetAmount()); + + // Focused Power + amount *= caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT); + } + } + + void ReflectDamage(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + { + Unit* target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + + if (Unit* caster = GetCaster()) + if (AuraEffect* talentAurEff = caster->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0)) { - int32 heal = GetHitHeal(); - AddPct(heal, aurEff->GetAmount()); - SetHitHeal(heal); + int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); } - } } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_power_word_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_power_word_shield_AuraScript::ReflectDamage, EFFECT_0); } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_pri_prayer_of_mending_heal_SpellScript(); + return new spell_pri_power_word_shield_AuraScript(); } }; -// -17 - Reflective Shield -class spell_pri_reflective_shield_trigger : public SpellScriptLoader +// 33110 - Prayer of Mending Heal +class spell_pri_prayer_of_mending_heal : public SpellScriptLoader { public: - spell_pri_reflective_shield_trigger() : SpellScriptLoader("spell_pri_reflective_shield_trigger") { } + spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } - class spell_pri_reflective_shield_trigger_AuraScript : public AuraScript + class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript { - PrepareAuraScript(spell_pri_reflective_shield_trigger_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_R1)) - return false; - return true; - } + PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); - void Trigger(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + void HandleHeal(SpellEffIndex /*effIndex*/) { - Unit* target = GetTarget(); - if (dmgInfo.GetAttacker() == target) - return; - - if (GetCaster()) - if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0)) + if (Unit* caster = GetOriginalCaster()) + { + if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_PRIEST_T9_HEALING_2P, EFFECT_0)) { - int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); - target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + int32 heal = GetHitHeal(); + AddPct(heal, aurEff->GetAmount()); + SetHitHeal(heal); } + } } void Register() { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_reflective_shield_trigger_AuraScript::Trigger, EFFECT_0); + OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); } }; - AuraScript* GetAuraScript() const + SpellScript* GetSpellScript() const { - return new spell_pri_reflective_shield_trigger_AuraScript(); + return new spell_pri_prayer_of_mending_heal_SpellScript(); } }; @@ -458,12 +525,13 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void AddSC_priest_spell_scripts() { new spell_pri_guardian_spirit(); + new spell_pri_lightwell_renew(); new spell_pri_mana_burn(); new spell_pri_mind_sear(); new spell_pri_pain_and_suffering_proc(); new spell_pri_penance(); + new spell_pri_power_word_shield(); new spell_pri_prayer_of_mending_heal(); - new spell_pri_reflective_shield_trigger(); new spell_pri_renew(); new spell_pri_shadow_word_death(); new spell_pri_vampiric_touch(); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 70b677f5aaa..156158b4e36 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -347,6 +347,58 @@ class spell_rog_prey_on_the_weak : public SpellScriptLoader } }; +// -1943 - Rupture +class spell_rog_rupture : public SpellScriptLoader +{ + public: + spell_rog_rupture() : SpellScriptLoader("spell_rog_rupture") { } + + class spell_rog_rupture_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_rupture_AuraScript); + + bool Load() + { + Unit* caster = GetCaster(); + return caster && caster->GetTypeId() == TYPEID_PLAYER; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + if (Unit* caster = GetCaster()) + { + canBeRecalculated = false; + + float const attackpowerPerCombo[6] = + { + 0.0f, + 0.015f, // 1 point: ${($m1 + $b1*1 + 0.015 * $AP) * 4} damage over 8 secs + 0.024f, // 2 points: ${($m1 + $b1*2 + 0.024 * $AP) * 5} damage over 10 secs + 0.03f, // 3 points: ${($m1 + $b1*3 + 0.03 * $AP) * 6} damage over 12 secs + 0.03428571f, // 4 points: ${($m1 + $b1*4 + 0.03428571 * $AP) * 7} damage over 14 secs + 0.0375f // 5 points: ${($m1 + $b1*5 + 0.0375 * $AP) * 8} damage over 16 secs + }; + + uint8 cp = caster->ToPlayer()->GetComboPoints(); + if (cp > 5) + cp = 5; + + amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * attackpowerPerCombo[cp]); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_rupture_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_rupture_AuraScript(); + } +}; + // 5938 - Shiv class spell_rog_shiv : public SpellScriptLoader { @@ -395,5 +447,6 @@ void AddSC_rogue_spell_scripts() new spell_rog_nerves_of_steel(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); + new spell_rog_rupture(); new spell_rog_shiv(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 0d249953421..2994761be6f 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -38,6 +38,7 @@ enum ShamanSpells SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456, SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441, + SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132, SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032, @@ -743,6 +744,35 @@ class spell_sha_sentry_totem : public SpellScriptLoader } }; +// -51490 - Thunderstorm +class spell_sha_thunderstorm : public SpellScriptLoader +{ + public: + spell_sha_thunderstorm() : SpellScriptLoader("spell_sha_thunderstorm") { } + + class spell_sha_thunderstorm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_thunderstorm_SpellScript); + + void HandleKnockBack(SpellEffIndex effIndex) + { + // Glyph of Thunderstorm + if (GetCaster()->HasAura(SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM)) + PreventHitDefaultEffect(effIndex); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_sha_thunderstorm_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_thunderstorm_SpellScript(); + } +}; + void AddSC_shaman_spell_scripts() { new spell_sha_ancestral_awakening_proc(); @@ -760,4 +790,5 @@ void AddSC_shaman_spell_scripts() new spell_sha_mana_spring_totem(); new spell_sha_mana_tide_totem(); new spell_sha_sentry_totem(); + new spell_sha_thunderstorm(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 89c69733daf..68ad1315dce 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -649,6 +649,43 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader } }; +// -7235 - Shadow Ward +class spell_warl_shadow_ward : public SpellScriptLoader +{ + public: + spell_warl_shadow_ward() : SpellScriptLoader("spell_warl_shadow_ward") { } + + class spell_warl_shadow_ward_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_shadow_ward_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = false; + if (Unit* caster = GetCaster()) + { + // +80.68% from sp bonus + float bonus = 0.8068f; + + bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()); + bonus *= caster->CalculateLevelPenalty(GetSpellInfo()); + + amount += int32(bonus); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_shadow_ward_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_shadow_ward_AuraScript(); + } +}; + // 29858 - Soulshatter class spell_warl_soulshatter : public SpellScriptLoader { @@ -742,6 +779,7 @@ void AddSC_warlock_spell_scripts() new spell_warl_life_tap(); new spell_warl_ritual_of_doom_effect(); new spell_warl_seed_of_corruption(); + new spell_warl_shadow_ward(); new spell_warl_soulshatter(); new spell_warl_unstable_affliction(); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index f84265b89de..822d4b17992 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -41,6 +41,7 @@ enum WarriorSpells SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, SPELL_WARRIOR_SLAM = 50783, + SPELL_WARRIOR_TAUNT = 355, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2 = 46860, SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1 = 64849, @@ -333,6 +334,34 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader } }; +// 5246 - Intimidating Shout +class spell_warr_intimidating_shout : public SpellScriptLoader +{ + public: + spell_warr_intimidating_shout() : SpellScriptLoader("spell_warr_intimidating_shout") { } + + class spell_warr_intimidating_shout_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_intimidating_shout_SpellScript); + + void FilterTargets(std::list& unitList) + { + unitList.remove(GetExplTargetWorldObject()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_intimidating_shout_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_intimidating_shout_SpellScript::FilterTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_intimidating_shout_SpellScript(); + } +}; + // 12975 - Last Stand class spell_warr_last_stand : public SpellScriptLoader { @@ -409,6 +438,83 @@ class spell_warr_overpower : public SpellScriptLoader } }; +// -772 - Rend +class spell_warr_rend : public SpellScriptLoader +{ + public: + spell_warr_rend() : SpellScriptLoader("spell_warr_rend") { } + + class spell_warr_rend_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_rend_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated) + { + if (Unit* caster = GetCaster()) + { + canBeRecalculated = false; + + // $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick + float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); + int32 mws = caster->GetAttackTime(BASE_ATTACK); + float mwbMin = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); + float mwbMax = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); + float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.2f; + amount += int32(caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), mwb)); + + // "If used while your target is above 75% health, Rend does 35% more damage." + // as for 3.1.3 only ranks above 9 (wrong tooltip?) + if (GetSpellInfo()->GetRank() >= 9) + { + if (GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetSpellInfo(), caster)) + AddPct(amount, GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster)); + } + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warr_rend_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_rend_AuraScript(); + } +}; + +// 64380, 65941 - Shattering Throw +class spell_warr_shattering_throw : public SpellScriptLoader +{ + public: + spell_warr_shattering_throw() : SpellScriptLoader("spell_warr_shattering_throw") { } + + class spell_warr_shattering_throw_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_shattering_throw_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + // remove shields, will still display immune to damage part + if (Unit* target = GetHitUnit()) + target->RemoveAurasWithMechanic(1 << MECHANIC_IMMUNE_SHIELD, AURA_REMOVE_BY_ENEMY_SPELL); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_shattering_throw_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_shattering_throw_SpellScript(); + } +}; + // -1464 - Slam class spell_warr_slam : public SpellScriptLoader { @@ -493,6 +599,37 @@ class spell_warr_vigilance : public SpellScriptLoader } }; +// 50725 Vigilance +class spell_warr_vigilance_trigger : public SpellScriptLoader +{ + public: + spell_warr_vigilance_trigger() : SpellScriptLoader("spell_warr_vigilance_trigger") { } + + class spell_warr_vigilance_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_vigilance_trigger_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + // Remove Taunt cooldown + if (Player* target = GetHitPlayer()) + target->RemoveSpellCooldown(SPELL_WARRIOR_TAUNT, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_vigilance_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_vigilance_trigger_SpellScript(); + } +}; + void AddSC_warrior_spell_scripts() { new spell_warr_bloodthirst(); @@ -502,8 +639,12 @@ void AddSC_warrior_spell_scripts() new spell_warr_deep_wounds(); new spell_warr_execute(); new spell_warr_improved_spell_reflection(); + new spell_warr_intimidating_shout(); new spell_warr_last_stand(); new spell_warr_overpower(); + new spell_warr_rend(); + new spell_warr_shattering_throw(); new spell_warr_slam(); new spell_warr_vigilance(); + new spell_warr_vigilance_trigger(); } -- cgit v1.2.3 From bbcc78e2c187b99396f1311401a26b3e24d33332 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 20 Jan 2013 17:55:48 +0100 Subject: Core: Fix warnings --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e440b2a0fbd..d029d2884c9 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -449,8 +449,6 @@ int32 AuraEffect::CalculateAmount(Unit* caster) } } - float DoneActualBenefit = 0.0f; - // custom amount calculations go here switch (GetAuraType()) { -- cgit v1.2.3 From 1eab850cab9c71c0e8086af538aded557c526914 Mon Sep 17 00:00:00 2001 From: kaelima Date: Sun, 20 Jan 2013 19:44:38 +0100 Subject: Core/BG: Set bgteam in PLAYER_BYTES_3 >> 24. Creds to vlad852 closes #8969 --- src/server/game/Battlegrounds/Battleground.cpp | 13 +++---------- src/server/game/Entities/Player/Player.h | 6 +++++- src/server/game/Handlers/BattleGroundHandler.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index e717a10fcd7..264c2c333aa 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -523,7 +523,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) WorldPacket status; BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), GetPlayerTeam(itr->first)); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam()); player->GetSession()->SendPacket(&status); player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); @@ -919,7 +919,7 @@ void Battleground::EndBattleground(uint32 winner) player->GetSession()->SendPacket(&pvpLogData); WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), GetPlayerTeam(player->GetGUID())); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam()); player->GetSession()->SendPacket(&data); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } @@ -1147,13 +1147,6 @@ void Battleground::AddPlayer(Player* player) sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player); SendPacketToTeam(team, &data, player, false); - // BG Status packet - WorldPacket status; - BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); - uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), team); - player->GetSession()->SendPacket(&status); - player->RemoveAurasByType(SPELL_AURA_MOUNTED); // add arena specific auras @@ -1846,7 +1839,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) sBattlegroundMgr->BuildPvpLogDataPacket(&data, this); player->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), GetPlayerTeam(player->GetGUID())); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam()); player->GetSession()->SendPacket(&data); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 52e81d6d0cd..6d9d63b8fda 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2219,7 +2219,11 @@ class Player : public Unit, public GridObject WorldLocation const& GetBattlegroundEntryPoint() const { return m_bgData.joinPos; } void SetBattlegroundEntryPoint(); - void SetBGTeam(uint32 team) { m_bgData.bgTeam = team; } + void SetBGTeam(uint32 team) + { + m_bgData.bgTeam = team; + SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)); + } uint32 GetBGTeam() const { return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); } void LeaveBattleground(bool teleportToEntryPoint = true); diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 99056960893..e70f127d600 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -453,8 +453,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->CleanupAfterTaxiFlight(); } - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), bg->GetPlayerTeam(_player->GetGUID())); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team); _player->GetSession()->SendPacket(&data); + // remove battleground queue status from BGmgr bgQueue.RemovePlayer(_player->GetGUID(), false); // this is still needed here if battleground "jumping" shouldn't add deserter debuff @@ -466,6 +467,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->SetBattlegroundId(bg->GetInstanceID(), bgTypeId); // set the destination team _player->SetBGTeam(ginfo.Team); + // bg->HandleBeforeTeleportToBattleground(_player); sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId); // add only in HandleMoveWorldPortAck() @@ -541,7 +543,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // this line is checked, i only don't know if GetStartTime is changing itself after bg end! // send status in Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, bg->GetPlayerTeam(_player->GetGUID())); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); SendPacket(&data); continue; } -- cgit v1.2.3 From 4372d24a7cc9dab325a9352bedf053a7580ac7b4 Mon Sep 17 00:00:00 2001 From: kaelima Date: Sun, 20 Jan 2013 20:06:30 +0100 Subject: Core/Movement: Prevent calling _updateSpeed for pets during a maptransfer Closes #8998 --- .../Movement/MovementGenerators/TargetedMovementGenerator.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 1958774380e..20c9c6cb608 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -273,15 +273,16 @@ void FollowMovementGenerator::_updateSpeed(Player &/*u*/) } template<> -void FollowMovementGenerator::_updateSpeed(Creature &u) +void FollowMovementGenerator::_updateSpeed(Creature& owner) { // pet only sync speed with owner - if (!((Creature&)u).isPet() || !i_target.isValid() || i_target->GetGUID() != u.GetOwnerGUID()) + /// Make sure we are not in the process of a map change + if (!owner.isPet() || !owner.IsInWorld() || !i_target.isValid() || i_target->GetGUID() != owner.GetOwnerGUID()) return; - u.UpdateSpeed(MOVE_RUN, true); - u.UpdateSpeed(MOVE_WALK, true); - u.UpdateSpeed(MOVE_SWIM, true); + owner.UpdateSpeed(MOVE_RUN, true); + owner.UpdateSpeed(MOVE_WALK, true); + owner.UpdateSpeed(MOVE_SWIM, true); } template<> -- cgit v1.2.3 From b153e68cfdd79adaeaff99cda1c0bfdbf22f2cd6 Mon Sep 17 00:00:00 2001 From: Mislav Blažević Date: Sun, 20 Jan 2013 16:36:55 +0100 Subject: Too small buffer fail --- src/server/game/DataStores/DBCStores.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 3fdff8e11d6..ad1c2d8e0b1 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -237,9 +237,10 @@ inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCSt // sort problematic dbc to (1) non compatible and (2) non-existed if (FILE* f = fopen(dbcFilename.c_str(), "rb")) { - char buf[100]; - snprintf(buf, 100, " exists, and has %u field(s) (expected " SIZEFMTD "). Extracted file might be from wrong client version or a database-update has been forgotten.", storage.GetFieldCount(), strlen(storage.GetFormat())); - errors.push_back(dbcFilename + buf); + std::ostringstream stream; + stream << dbcFilename << " exists, and has " << storage.GetFieldCount() << " field(s) (expected " << strlen(storage.GetFormat()) << "). Extracted file might be from wrong client version or a database-update has been forgotten."; + std::string buf = stream.str(); + errors.push_back(buf); fclose(f); } else -- cgit v1.2.3 From 4d7b2c4929c7efc5ce5c82f7a884d383094cc087 Mon Sep 17 00:00:00 2001 From: kaelima Date: Sun, 20 Jan 2013 21:30:11 +0100 Subject: Corrections to 1eab850cab9c71c0e8086af538aded557c526914 --- src/server/game/Entities/Player/Player.h | 2 +- .../game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 6d9d63b8fda..a1e6591413f 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2222,7 +2222,7 @@ class Player : public Unit, public GridObject void SetBGTeam(uint32 team) { m_bgData.bgTeam = team; - SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE)); + SetByteValue(PLAYER_BYTES_3, 3, uint8(team == ALLIANCE ? 1 : 0)); } uint32 GetBGTeam() const { return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); } diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 20c9c6cb608..7a1cf552731 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -276,7 +276,7 @@ template<> void FollowMovementGenerator::_updateSpeed(Creature& owner) { // pet only sync speed with owner - /// Make sure we are not in the process of a map change + /// Make sure we are not in the process of a map change (IsInWorld) if (!owner.isPet() || !owner.IsInWorld() || !i_target.isValid() || i_target->GetGUID() != owner.GetOwnerGUID()) return; -- cgit v1.2.3 From b7dbc8d746ed583ff5b4b529ce4441aa3c1149ba Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sun, 20 Jan 2013 18:04:06 -0330 Subject: Scripting/Zulgrub: Updated Boss Arlokk Script. --- .../world/2013_01_20_09_world_spell_dbc.sql | 18 + .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 396 ++++++++++++++++----- .../EasternKingdoms/ZulGurub/instance_zulgurub.cpp | 77 ++-- .../scripts/EasternKingdoms/ZulGurub/zulgurub.h | 22 +- 4 files changed, 396 insertions(+), 117 deletions(-) create mode 100644 sql/updates/world/2013_01_20_09_world_spell_dbc.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_20_09_world_spell_dbc.sql b/sql/updates/world/2013_01_20_09_world_spell_dbc.sql new file mode 100644 index 00000000000..bdd57e940b5 --- /dev/null +++ b/sql/updates/world/2013_01_20_09_world_spell_dbc.sql @@ -0,0 +1,18 @@ +-- Add missing spells to spell_dbc +DELETE FROM `spell_dbc` WHERE `Id` IN (24211,24246,24235,7939); +INSERT INTO `spell_dbc` (`Id`,`SchoolMask`,`Dispel`,`Mechanic`,`Attributes`,`AttributesEx`,`AttributesEx2`,`AttributesEx3`,`AttributesEx4`,`Stances`,`StancesNot`,`Targets`,`CastingTimeIndex`,`AuraInterruptFlags`,`ProcFlags`,`ProcChance`,`ProcCharges`,`MaxLevel`,`BaseLevel`,`SpellLevel`,`DurationIndex`,`RangeIndex`,`StackAmount`,`EquippedItemClass`,`EquippedItemSubClassMask`,`EquippedItemInventoryTypeMask`,`Effect1`,`Effect2`,`Effect3`,`EffectDieSides1`,`EffectDieSides2`,`EffectDieSides3`,`EffectRealPointsPerLevel1`,`EffectRealPointsPerLevel2`,`EffectRealPointsPerLevel3`,`EffectBasePoints1`,`EffectBasePoints2`,`EffectBasePoints3`,`EffectMechanic1`,`EffectMechanic2`,`EffectMechanic3`,`EffectImplicitTargetA1`,`EffectImplicitTargetA2`,`EffectImplicitTargetA3`,`EffectImplicitTargetB1`,`EffectImplicitTargetB2`,`EffectImplicitTargetB3`,`EffectRadiusIndex1`,`EffectRadiusIndex2`,`EffectRadiusIndex3`,`EffectApplyAuraName1`,`EffectApplyAuraName2`,`EffectApplyAuraName3`,`EffectAmplitude1`,`EffectAmplitude2`,`EffectAmplitude3`,`EffectMultipleValue1`,`EffectMultipleValue2`,`EffectMultipleValue3`,`EffectMiscValue1`,`EffectMiscValue2`,`EffectMiscValue3`,`EffectTriggerSpell1`,`EffectTriggerSpell2`,`EffectTriggerSpell3`,`Comment`,`MaxTargetLevel`,`SpellFamilyName`,`SpellFamilyFlags1`,`SpellFamilyFlags2`,`MaxAffectedTargets`,`DmgClass`,`PreventionType`,`DmgMultiplier1`,`DmgMultiplier2`,`DmgMultiplier3`,`EffectMiscValueB1`) VALUES +(24211,0,0,0,256,0,4,0,0,0,0,0,1,0,0,101,0,0,0,0,0,0,0,-1,0,0,63,0,0,1,0,0,0,0,0,4999,0,0,0,0,0,22,0,0,0,0,0,7,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'Mark of Arlokk',0,0,0,0,0,0,0,1,0,0,0), +(24246,0,0,0,256,0,0,0,0,0,0,0,1,0,0,101,0,0,0,0,6,0,0,-1,0,0,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,15101,0,0,0,0,0,'Summon Zulian Prowler',0,0,0,0,0,0,0,1,0,0,64), +(24235,0,0,0,272,268435456,0,0,0,0,0,0,1,0,0,101,0,0,0,0,1,0,0,-1,0,0,6,0,0,0,0,0,0,0,0,9999,0,0,0,0,0,1,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'Super Invis',0,0,0,0,0,0,0,1,1,1,0), +(7939,0,5,0,402915728,268435456,0,0,0,0,0,0,1,6147,0,101,0,0,1,1,21,1,0,-1,-1,0,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 'Sneak Rank 1',0,0,0,0,0,0,0,-1,1,1,0); + +-- Add script name to Zulian Prowler +UPDATE `creature_template` SET `AIName` = '', `ScriptName`='npc_zulian_prowler' WHERE `entry`=15101; + +-- Remove SmartAI +DELETE FROM smart_scripts WHERE entryorguid = 15101; + +-- Add condition for Mark of Arlokk +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=24211; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,24211,0,0,0,31,3,15101,0,0,0,0, '', 'Mark of Arlokk - Targets Zulian Prowler'); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 51aab7c20d0..9d6aaf71665 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * 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 @@ -17,10 +16,12 @@ */ /* ScriptData -SDName: Boss_Arlokk -SD%Complete: 95 -SDComment: Wrong cleave and red aura is missing. -SDCategory: Zul'Gurub +TCName: Boss_Arlokk +TC%Complete: 95 +TCComment: Wrong cleave and red aura is missing not yet added. +TCComment: Prowlers moving through wall hopefully mmaps will fix. +TCComment: Can't test LOS until mmaps. +TCCategory: Zul'Gurub EndScriptData */ #include "ScriptMgr.h" @@ -30,47 +31,58 @@ EndScriptData */ enum Says { SAY_AGGRO = 0, - SAY_FEAST_PANTHER = 1, + SAY_FEAST_PROWLER = 1, SAY_DEATH = 2 }; enum Spells { - SPELL_SHADOW_WORD_PAIN = 23952, - SPELL_GOUGE = 24698, - SPELL_MARK = 24210, - SPELL_CLEAVE = 26350, // Perhaps not right. Not a red aura... - SPELL_PANTHER_TRANSFORM = 24190 + SPELL_SHADOW_WORD_PAIN = 24212, // corrected + SPELL_GOUGE = 12540, // corrected + SPELL_MARK_OF_ARLOKK = 24210, // This is correct triggers 24211 Added to Spell_dbc + SPELL_RAVAGE = 24213, // corrected + SPELL_CLEAVE = 25174, // Searching for right spell + SPELL_PANTHER_TRANSFORM = 24190, // Transform to panther now used + SPELL_SUMMON_PROWLER = 24246, // Added to Spell_dbc + SPELL_VANISH_VISUAL = 24222, // Added + SPELL_VANISH = 24223, // Added + SPELL_SUPER_INVIS = 24235 // Added }; enum Events { - EVENT_SHADOW_WORD_PAIN = 0, - EVENT_GOUGE = 1, - EVENT_MARK = 2, - EVENT_CLEAVE = 3, - EVENT_VANISH = 4, - EVENT_VISIBLE = 5, - EVENT_SUMMON = 6 + EVENT_SHADOW_WORD_PAIN = 1, + EVENT_GOUGE = 2, + EVENT_MARK_OF_ARLOKK = 3, + EVENT_RAVAGE = 4, + EVENT_TRANSFORM = 5, + EVENT_VANISH = 6, + EVENT_VANISH_2 = 7, + EVENT_TRANSFORM_BACK = 8, + EVENT_VISIBLE = 9, + EVENT_SUMMON_PROWLERS = 10 }; enum Phases { - PHASE_ONE = 1, - PHASE_TWO = 2 + PHASE_ALL = 0, + PHASE_ONE = 1, + PHASE_TWO = 2 }; -enum ModelIds +enum Weapon { - MODEL_ID_NORMAL = 15218, - MODEL_ID_PANTHER = 15215, - MODEL_ID_BLANK = 11686 + WEAPON_DAGGER = 10616 }; -Position const PosSummonProwlers[2] = +enum Misc { - { -11532.7998f, -1649.6734f, 41.4800f, 0.0f }, - { -11532.9970f, -1606.4840f, 41.2979f, 0.0f } + MAX_PROWLERS_PER_SIDE = 15 +}; + +Position const PosMoveOnSpawn[1] = +{ + { -11561.9f, -1627.868f, 41.29941f } }; class boss_arlokk : public CreatureScript @@ -83,52 +95,88 @@ class boss_arlokk : public CreatureScript void Reset() { - summonCount = 0; - markedTargetGUID = 0; - me->SetDisplayId(MODEL_ID_NORMAL); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + summonCountA = 0; + summonCountB = 0; + me->RemoveAllAuras(); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); + if (instance) + { + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + gate->SetGoState(GO_STATE_READY); + me->SetWalk(false); + me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0].m_positionX,PosMoveOnSpawn[0].m_positionY,PosMoveOnSpawn[0].m_positionZ); + } } void JustDied(Unit* /*killer*/) { - _JustDied(); Talk(SAY_DEATH); - me->SetDisplayId(MODEL_ID_NORMAL); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAllAuras(); + if (instance) + { + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + gate->SetGoState(GO_STATE_ACTIVE); + instance->SetBossState(DATA_ARLOKK, DONE); + } } void EnterCombat(Unit* /*who*/) { _EnterCombat(); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_MARK, 35000, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_SUMMON, 5000); - events.ScheduleEvent(EVENT_VANISH, 60000); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + if (instance) + events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); + events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); + events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); Talk(SAY_AGGRO); - } - void JustReachedHome() - { - instance->SetBossState(DATA_ARLOKK, NOT_STARTED); - me->DespawnOrUnsummon(); + // Sets up list of Panther spawners to cast on + std::list triggerList; + GetCreatureListWithEntryInGrid(triggerList, me, NPC_PANTHER_TRIGGER, 100.0f); + if (!triggerList.empty()) + { + uint8 sideA = 0; + uint8 sideB = 0; + for (std::list::const_iterator itr = triggerList.begin(); itr != triggerList.end(); ++itr) + { + if (Creature* trigger = *itr) + { + if (trigger->GetPositionY() < -1625.0f) + { + triggersSideAGUID[sideA] = trigger->GetGUID(); + ++sideA; + } + else + { + triggersSideBGUID[sideB] = trigger->GetGUID(); + ++sideB; + } + } + } + } } - void DoSummonPhanters() + void EnterEvadeMode() { - if (summonCount > 30) - return; - - if (markedTargetGUID) - Talk(SAY_FEAST_PANTHER, markedTargetGUID); - me->SummonCreature(NPC_ZULIAN_PROWLER, PosSummonProwlers[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - me->SummonCreature(NPC_ZULIAN_PROWLER, PosSummonProwlers[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + if (instance) + { + if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + object->SetGoState(GO_STATE_ACTIVE); + if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_GONG_OF_BETHEKK))) + object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + instance->SetBossState(DATA_ARLOKK, NOT_STARTED); + } + me->DespawnOrUnsummon(4000); } - void JustSummoned(Creature* summoned) + void SetData(uint32 uiId, uint32 uiValue) { - if (Unit* markedTarget = Unit::GetUnit(*me, markedTargetGUID)) - summoned->AI()->AttackStart(markedTarget); - ++summonCount; + if (uiId == 1) + --summonCountA; + if (uiId == 2) + --summonCountB; } void UpdateAI(uint32 const diff) @@ -147,47 +195,99 @@ class boss_arlokk : public CreatureScript { case EVENT_SHADOW_WORD_PAIN: DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 15000, 0, PHASE_ONE); - break; - case EVENT_MARK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_MARK); - events.ScheduleEvent(EVENT_MARK, 15000, 0, PHASE_ONE); - break; - case EVENT_CLEAVE: - DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - events.ScheduleEvent(EVENT_CLEAVE, 16000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); break; case EVENT_GOUGE: - DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - events.ScheduleEvent(EVENT_GOUGE, urand(17000, 27000), 0, PHASE_TWO); + DoCastVictim(SPELL_GOUGE, true); break; - case EVENT_SUMMON: - DoSummonPhanters(); - events.ScheduleEvent(EVENT_SUMMON, 5000); + case EVENT_SUMMON_PROWLERS: + if (summonCountA < MAX_PROWLERS_PER_SIDE) + if (Unit* trigger = me->GetUnit(*me, triggersSideAGUID[urand(0, 4)])) + { + trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); + ++summonCountA; + } + if (summonCountB < MAX_PROWLERS_PER_SIDE) + if (Unit* trigger = me->GetUnit(*me, triggersSideBGUID[urand(0, 4)])) + { + trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); + ++summonCountB; + } + events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); break; - case EVENT_VANISH: - me->SetDisplayId(MODEL_ID_BLANK); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->AttackStop(); - DoResetThreat(); - events.ScheduleEvent(EVENT_VISIBLE, 6000); + case EVENT_MARK_OF_ARLOKK: + { + Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, urand(1,3), 0.0f, false, -SPELL_MARK_OF_ARLOKK); + if (!target) + target = me->getVictim(); + if (target) + { + DoCast(target, SPELL_MARK_OF_ARLOKK, true); + Talk(SAY_FEAST_PROWLER, target->GetGUID()); + } break; - case EVENT_VISIBLE: + events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); + } + case EVENT_TRANSFORM: { - me->SetDisplayId(MODEL_ID_PANTHER); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_PANTHER_TRANSFORM); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP)); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(EQUIP_UNEQUIP)); const CreatureTemplate* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); me->UpdateDamagePhysical(BASE_ATTACK); + me->AttackStop(); + DoResetThreat(); + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_VANISH_VISUAL); + DoCast(me, SPELL_VANISH); + events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); + break; + } + case EVENT_VANISH: + DoCast(me, SPELL_SUPER_INVIS); + me->SetWalk(false); + if (instance) + me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ()); + events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); + break; + case EVENT_VANISH_2: + DoCast(me, SPELL_VANISH); + DoCast(me, SPELL_SUPER_INVIS); + events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); + break; + case EVENT_VISIBLE: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) AttackStart(target); - events.ScheduleEvent(EVENT_VANISH, 39000); - events.ScheduleEvent(EVENT_CLEAVE, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_GOUGE, 14000, 0, PHASE_TWO); + me->RemoveAura(SPELL_SUPER_INVIS); + me->RemoveAura(SPELL_VANISH); + events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); events.SetPhase(PHASE_TWO); break; + case EVENT_RAVAGE: + DoCastVictim(SPELL_RAVAGE, true); + events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + break; + case EVENT_TRANSFORM_BACK: + { + me->RemoveAura(SPELL_PANTHER_TRANSFORM); + DoCast(me, SPELL_VANISH_VISUAL); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); + const CreatureTemplate* cinfo = me->GetCreatureTemplate(); + me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg)); + me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg)); + me->UpdateDamagePhysical(BASE_ATTACK); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); + events.SetPhase(PHASE_ONE); + break; } default: break; @@ -198,8 +298,10 @@ class boss_arlokk : public CreatureScript } private: - uint32 summonCount; - uint64 markedTargetGUID; + uint8 summonCountA; + uint8 summonCountB; + uint64 triggersSideAGUID[5]; + uint64 triggersSideBGUID[5]; }; CreatureAI* GetAI(Creature* creature) const @@ -208,6 +310,123 @@ class boss_arlokk : public CreatureScript } }; +/*###### +## npc_zulian_prowler +######*/ + +enum ZulianProwlerSpells +{ + SPELL_SNEAK_RANK_1_1 = 22766, + SPELL_SNEAK_RANK_1_2 = 7939, + SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 +}; + +enum ZulianProwlerEvents +{ + EVENT_ATTACK = 1 +}; + +Position const PosProwlerCenter[1] = +{ + { -11556.7f, -1631.344f, 41.2994f } +}; + +class npc_zulian_prowler : public CreatureScript +{ + public: npc_zulian_prowler() : CreatureScript("npc_zulian_prowler") {} + + struct npc_zulian_prowlerAI : public ScriptedAI + { + npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } + + void Reset() + { + if (me->GetPositionY() < -1625.0f) + sideData = 1; + else + sideData = 2; + + DoCast(me, SPELL_SNEAK_RANK_1_1); + DoCast(me, SPELL_SNEAK_RANK_1_2); + // me->SetReactState(REACT_PASSIVE); + + if (instance) + if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) + me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ()); + events.ScheduleEvent(EVENT_ATTACK, 6000); + } + + void EnterCombat(Unit* /*who*/) + { + me->GetMotionMaster()->Clear(false); + me->RemoveAura(SPELL_SNEAK_RANK_1_1); + me->RemoveAura(SPELL_SNEAK_RANK_1_2); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + if (spell->Id == SPELL_MARK_OF_ARLOKK_TRIGGER) // Should only hit if line of sight + { + me->Attack(caster, true); + } + } + + void JustDied(Unit* /*killer*/) + { + + if (instance) + if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) + if (arlokk->isAlive()) + arlokk->GetAI()->SetData(sideData, 0); + me->DespawnOrUnsummon(4000); + } + + void UpdateAI(const uint32 diff) + { + + if (UpdateVictim()) + { + DoMeleeAttackIfReady(); + return; + } + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ATTACK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0.0f, 100, false)) + me->Attack(target, true); + break; + default: + break; + } + } + } + + private: + int32 sideData; + EventMap events; + InstanceScript* instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetZulGurubAI(creature); + } +}; + +/*###### +## go_gong_of_bethekk +######*/ + +Position const PosSummonArlokk[1] = +{ + { -11507.22f, -1628.062f, 41.38264f, 3.159046f } +}; + class go_gong_of_bethekk : public GameObjectScript { public: go_gong_of_bethekk() : GameObjectScript("go_gong_of_bethekk") {} @@ -216,12 +435,11 @@ class go_gong_of_bethekk : public GameObjectScript { if (InstanceScript* instance = go->GetInstanceScript()) { - if (instance->GetBossState(DATA_ARLOKK) == DONE || instance->GetBossState(DATA_ARLOKK) == IN_PROGRESS) - return true; + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SendCustomAnim(0); + go->SummonCreature(NPC_ARLOKK, PosSummonArlokk[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 600000); instance->SetBossState(DATA_ARLOKK, IN_PROGRESS); - return true; } - return true; } }; @@ -229,6 +447,6 @@ class go_gong_of_bethekk : public GameObjectScript void AddSC_boss_arlokk() { new boss_arlokk(); + new npc_zulian_prowler(); new go_gong_of_bethekk(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index 19a2ba39578..d922e2db3f3 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -40,11 +40,14 @@ class instance_zulgurub : public InstanceMapScript void Initialize() { - ZealotLorkhanGUID = 0; - ZealotZathGUID = 0; - HighPriestTekalGUID = 0; - JindoTheHexxerGUID = 0; - VilebranchSpeakerGUID = 0; + zealotLorkhanGUID = 0; + zealotZathGUID = 0; + highPriestTekalGUID = 0; + jindoTheHexxerGUID = 0; + vilebranchSpeakerGUID = 0; + arlokkGUID = 0; + go_ForcefieldGUID = 0; + go_GongOfBethekkGUID = 0; } bool IsEncounterInProgress() const @@ -58,23 +61,41 @@ class instance_zulgurub : public InstanceMapScript switch (creature->GetEntry()) { case NPC_ZEALOT_LORKHAN: - ZealotLorkhanGUID = creature->GetGUID(); + zealotLorkhanGUID = creature->GetGUID(); break; case NPC_ZEALOT_ZATH: - ZealotZathGUID = creature->GetGUID(); + zealotZathGUID = creature->GetGUID(); break; case NPC_HIGH_PRIEST_THEKAL: - HighPriestTekalGUID = creature->GetGUID(); + highPriestTekalGUID = creature->GetGUID(); break; case NPC_JINDO_THE_HEXXER: - JindoTheHexxerGUID = creature->GetGUID(); + jindoTheHexxerGUID = creature->GetGUID(); break; case NPC_VILEBRANCH_SPEAKER: - VilebranchSpeakerGUID = creature->GetGUID(); + vilebranchSpeakerGUID = creature->GetGUID(); break; - case NPC_MANDOKIR: - if (GetBossState(DATA_MANDOKIR) == DONE) - creature->DespawnOrUnsummon(); + case NPC_ARLOKK: + arlokkGUID = creature->GetGUID(); + break; + } + } + + void OnGameObjectCreate(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_FORCEFIELD: + go_ForcefieldGUID = go->GetGUID(); + break; + case GO_GONG_OF_BETHEKK: + go_GongOfBethekkGUID = go->GetGUID(); + if (GetBossState(DATA_ARLOKK) == DONE) + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + else + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + default: break; } } @@ -84,16 +105,25 @@ class instance_zulgurub : public InstanceMapScript switch (uiData) { case DATA_LORKHAN: - return ZealotLorkhanGUID; + return zealotLorkhanGUID; break; case DATA_ZATH: - return ZealotZathGUID; + return zealotZathGUID; break; case DATA_THEKAL: - return HighPriestTekalGUID; + return highPriestTekalGUID; break; case DATA_JINDO: - return JindoTheHexxerGUID; + return jindoTheHexxerGUID; + break; + case NPC_ARLOKK: + return arlokkGUID; + break; + case GO_FORCEFIELD: + return go_ForcefieldGUID; + break; + case GO_GONG_OF_BETHEKK: + return go_GongOfBethekkGUID; break; } return 0; @@ -145,11 +175,14 @@ class instance_zulgurub : public InstanceMapScript //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too. //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too. - uint64 ZealotLorkhanGUID; - uint64 ZealotZathGUID; - uint64 HighPriestTekalGUID; - uint64 JindoTheHexxerGUID; - uint64 VilebranchSpeakerGUID; + uint64 zealotLorkhanGUID; + uint64 zealotZathGUID; + uint64 highPriestTekalGUID; + uint64 jindoTheHexxerGUID; + uint64 vilebranchSpeakerGUID; + uint64 arlokkGUID; + uint64 go_ForcefieldGUID; + uint64 go_GongOfBethekkGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 34680447cd7..77767153a96 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -36,23 +36,33 @@ enum DataTypes DATA_EDGE_OF_MADNESS = 9, // Optional Event Edge of Madness - one of: Gri'lek, Renataki, Hazza'rah, or Wushoolay DATA_LORKHAN = 10, // Zealot Lor'Khan add to High priest Thekal! DATA_ZATH = 11, // Zealot Zath add to High priest Thekal! - DATA_OHGAN = 12 // Bloodlord Mandokir's raptor mount + DATA_OHGAN = 12, // Bloodlord Mandokir's raptor mount + TYPE_EDGE_OF_MADNESS = 13 // Boss storage }; enum CreatureIds { + NPC_ARLOKK = 14515, // Arlokk Event + NPC_PANTHER_TRIGGER = 15091, // Arlokk Event + NPC_ZULIAN_PROWLER = 15101, // Arlokk Event NPC_ZEALOT_LORKHAN = 11347, NPC_ZEALOT_ZATH = 11348, NPC_HIGH_PRIEST_THEKAL = 14509, NPC_JINDO_THE_HEXXER = 11380, NPC_NIGHTMARE_ILLUSION = 15163, - NPC_ZULIAN_PROWLER = 15101, - NPC_VILEBRANCH_SPEAKER = 11391, NPC_SHADE_OF_JINDO = 14986, NPC_SACRIFICED_TROLL = 14826, - NPC_OHGAN = 14988, - NPC_CHAINED_SPIRT = 15117, - NPC_MANDOKIR = 11382 + NPC_MANDOKIR = 11382, // Mandokir Event + NPC_OHGAN = 14988, // Mandokir Event + NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event + NPC_CHAINED_SPIRT = 15117 // Mandokir Event + +}; + +enum GameobjectIds +{ + GO_FORCEFIELD = 180497, // Arlokk Event + GO_GONG_OF_BETHEKK = 180526 // Arlokk Event }; template -- cgit v1.2.3 From 33b768569635fc4a2477ed63e6a1673f5ada6660 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sun, 20 Jan 2013 18:20:46 -0330 Subject: Scripting/ZulGrub: Fix last commit --- .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 9d6aaf71665..3682b265cbc 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellInfo.h" #include "zulgurub.h" enum Says @@ -37,16 +38,16 @@ enum Says enum Spells { - SPELL_SHADOW_WORD_PAIN = 24212, // corrected - SPELL_GOUGE = 12540, // corrected - SPELL_MARK_OF_ARLOKK = 24210, // This is correct triggers 24211 Added to Spell_dbc - SPELL_RAVAGE = 24213, // corrected + SPELL_SHADOW_WORD_PAIN = 24212, // Corrected + SPELL_GOUGE = 12540, // Corrected + SPELL_MARK_OF_ARLOKK = 24210, // triggered spell 24211 Added to spell_dbc + SPELL_RAVAGE = 24213, // Corrected SPELL_CLEAVE = 25174, // Searching for right spell SPELL_PANTHER_TRANSFORM = 24190, // Transform to panther now used SPELL_SUMMON_PROWLER = 24246, // Added to Spell_dbc SPELL_VANISH_VISUAL = 24222, // Added SPELL_VANISH = 24223, // Added - SPELL_SUPER_INVIS = 24235 // Added + SPELL_SUPER_INVIS = 24235 // Added to Spell_dbc }; enum Events @@ -105,7 +106,7 @@ class boss_arlokk : public CreatureScript if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) gate->SetGoState(GO_STATE_READY); me->SetWalk(false); - me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0].m_positionX,PosMoveOnSpawn[0].m_positionY,PosMoveOnSpawn[0].m_positionZ); + me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]); } } @@ -171,7 +172,7 @@ class boss_arlokk : public CreatureScript me->DespawnOrUnsummon(4000); } - void SetData(uint32 uiId, uint32 uiValue) + void SetData(uint32 uiId, uint32 /*uiValue*/) { if (uiId == 1) --summonCountA; @@ -317,8 +318,8 @@ class boss_arlokk : public CreatureScript enum ZulianProwlerSpells { SPELL_SNEAK_RANK_1_1 = 22766, - SPELL_SNEAK_RANK_1_2 = 7939, - SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 + SPELL_SNEAK_RANK_1_2 = 7939, // Added to Spell_dbc + SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 // Added to Spell_dbc }; enum ZulianProwlerEvents @@ -348,7 +349,6 @@ class npc_zulian_prowler : public CreatureScript DoCast(me, SPELL_SNEAK_RANK_1_1); DoCast(me, SPELL_SNEAK_RANK_1_2); - // me->SetReactState(REACT_PASSIVE); if (instance) if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) @@ -438,7 +438,6 @@ class go_gong_of_bethekk : public GameObjectScript go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SendCustomAnim(0); go->SummonCreature(NPC_ARLOKK, PosSummonArlokk[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 600000); - instance->SetBossState(DATA_ARLOKK, IN_PROGRESS); } return true; } -- cgit v1.2.3 From dd7391660b9c897fdb4584ab03227bde2478ecee Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 21 Jan 2013 01:55:56 +0000 Subject: Core/Collision: Fix BIH::intersectRay crash Assure that BIHWrap::remove(const T& obj) actually removes every reference of obj from BIHWrap. Also add sanity checks to MDLCallback () functions to avoid array overruns. Closes #5218 Signed-off-by: Nay --- .../collision/BoundingIntervalHierarchyWrapper.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/collision/BoundingIntervalHierarchyWrapper.h b/src/server/collision/BoundingIntervalHierarchyWrapper.h index 8a99078caab..315f3004306 100644 --- a/src/server/collision/BoundingIntervalHierarchyWrapper.h +++ b/src/server/collision/BoundingIntervalHierarchyWrapper.h @@ -33,11 +33,14 @@ class BIHWrap { const T* const* objects; RayCallback& _callback; + uint32 objects_size; - MDLCallback(RayCallback& callback, const T* const* objects_array ) : objects(objects_array), _callback(callback) {} + MDLCallback(RayCallback& callback, const T* const* objects_array, uint32 objects_size ) : objects(objects_array), _callback(callback), objects_size(objects_size) {} bool operator() (const Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/) { + if (Idx >= objects_size) + return false; if (const T* obj = objects[Idx]) return _callback(ray, *obj, MaxDist/*, stopAtFirst*/); return false; @@ -45,6 +48,8 @@ class BIHWrap void operator() (const Vector3& p, uint32 Idx) { + if (Idx >= objects_size) + return false; if (const T* obj = objects[Idx]) _callback(p, *obj); } @@ -87,21 +92,24 @@ public: m_objects.fastClear(); m_obj2Idx.getKeys(m_objects); m_objects_to_push.getMembers(m_objects); + //assert that m_obj2Idx has all the keys m_tree.build(m_objects, BoundsFunc::getBounds2); } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& maxDist) const + void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& maxDist) { - MDLCallback temp_cb(intersectCallback, m_objects.getCArray()); + balance(); + MDLCallback temp_cb(intersectCallback, m_objects.getCArray(), m_objects.size()); m_tree.intersectRay(ray, temp_cb, maxDist, true); } template - void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) const + void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) { - MDLCallback callback(intersectCallback, m_objects.getCArray()); + balance(); + MDLCallback callback(intersectCallback, m_objects.getCArray(), m_objects.size()); m_tree.intersectPoint(point, callback); } }; -- cgit v1.2.3 From c6c23d67b8692936fe9e7d5920bfb997df516323 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 21 Jan 2013 02:10:01 +0000 Subject: Scripts/ZG: Fix some code style issues and logic errors --- .../world/2013_01_20_09_world_spell_dbc.sql | 2 +- src/server/game/Miscellaneous/Language.h | 4 +- .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 146 +++++++++++---------- .../EasternKingdoms/ZulGurub/boss_gahzranka.cpp | 1 - .../EasternKingdoms/ZulGurub/boss_hazzarah.cpp | 1 - .../EasternKingdoms/ZulGurub/instance_zulgurub.cpp | 64 ++++----- 6 files changed, 110 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/sql/updates/world/2013_01_20_09_world_spell_dbc.sql b/sql/updates/world/2013_01_20_09_world_spell_dbc.sql index bdd57e940b5..d8f466173f3 100644 --- a/sql/updates/world/2013_01_20_09_world_spell_dbc.sql +++ b/sql/updates/world/2013_01_20_09_world_spell_dbc.sql @@ -10,7 +10,7 @@ INSERT INTO `spell_dbc` (`Id`,`SchoolMask`,`Dispel`,`Mechanic`,`Attributes`,`Att UPDATE `creature_template` SET `AIName` = '', `ScriptName`='npc_zulian_prowler' WHERE `entry`=15101; -- Remove SmartAI -DELETE FROM smart_scripts WHERE entryorguid = 15101; +DELETE FROM `smart_scripts` WHERE `entryorguid`=15101; -- Add condition for Mark of Arlokk DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=24211; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 35b0a6f8569..039e8b816b3 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -742,7 +742,7 @@ enum TrinityStrings LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818, LANG_CHANNEL_CITY = 819, - + LANG_NPCINFO_GOSSIP = 820, LANG_NPCINFO_QUESTGIVER = 821, LANG_NPCINFO_TRAINER_CLASS = 822, @@ -766,7 +766,7 @@ enum TrinityStrings LANG_NPCINFO_SPELLCLICK = 840, LANG_NPCINFO_MAILBOX = 841, LANG_NPCINFO_PLAYER_VEHICLE = 842, - + // Room for in-game strings 843-999 not used // Level 4 (CLI only commands) diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 3682b265cbc..4b4186c7684 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -96,14 +96,14 @@ class boss_arlokk : public CreatureScript void Reset() { - summonCountA = 0; - summonCountB = 0; + _summonCountA = 0; + _summonCountB = 0; me->RemoveAllAuras(); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); - if (instance) + if (_instance) { - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + if (GameObject* gate = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) gate->SetGoState(GO_STATE_READY); me->SetWalk(false); me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]); @@ -114,23 +114,23 @@ class boss_arlokk : public CreatureScript { Talk(SAY_DEATH); me->RemoveAllAuras(); - if (instance) + if (_instance) { - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + if (GameObject* gate = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) gate->SetGoState(GO_STATE_ACTIVE); - instance->SetBossState(DATA_ARLOKK, DONE); + _instance->SetBossState(DATA_ARLOKK, DONE); } } void EnterCombat(Unit* /*who*/) { _EnterCombat(); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - if (instance) - events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); - events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); - events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + if (_instance) + _events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); + _events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); + _events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); Talk(SAY_AGGRO); // Sets up list of Panther spawners to cast on @@ -146,12 +146,12 @@ class boss_arlokk : public CreatureScript { if (trigger->GetPositionY() < -1625.0f) { - triggersSideAGUID[sideA] = trigger->GetGUID(); + _triggersSideAGUID[sideA] = trigger->GetGUID(); ++sideA; } else { - triggersSideBGUID[sideB] = trigger->GetGUID(); + _triggersSideBGUID[sideB] = trigger->GetGUID(); ++sideB; } } @@ -161,23 +161,23 @@ class boss_arlokk : public CreatureScript void EnterEvadeMode() { - if (instance) + if (_instance) { - if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) + if (GameObject* object = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) object->SetGoState(GO_STATE_ACTIVE); - if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_GONG_OF_BETHEKK))) + if (GameObject* object = me->GetMap()->GetGameObject(_instance->GetData64(GO_GONG_OF_BETHEKK))) object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - instance->SetBossState(DATA_ARLOKK, NOT_STARTED); + _instance->SetBossState(DATA_ARLOKK, NOT_STARTED); } me->DespawnOrUnsummon(4000); } - void SetData(uint32 uiId, uint32 /*uiValue*/) + void SetData(uint32 id, uint32 /*value*/) { - if (uiId == 1) - --summonCountA; - if (uiId == 2) - --summonCountB; + if (id == 1) + --_summonCountA; + else if (id == 2) + --_summonCountB; } void UpdateAI(uint32 const diff) @@ -185,36 +185,40 @@ class boss_arlokk : public CreatureScript if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_SHADOW_WORD_PAIN: DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); break; case EVENT_GOUGE: DoCastVictim(SPELL_GOUGE, true); break; case EVENT_SUMMON_PROWLERS: - if (summonCountA < MAX_PROWLERS_PER_SIDE) - if (Unit* trigger = me->GetUnit(*me, triggersSideAGUID[urand(0, 4)])) + if (_summonCountA < MAX_PROWLERS_PER_SIDE) + { + if (Unit* trigger = me->GetUnit(*me, _triggersSideAGUID[urand(0, 4)])) { trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); - ++summonCountA; + ++_summonCountA; } - if (summonCountB < MAX_PROWLERS_PER_SIDE) - if (Unit* trigger = me->GetUnit(*me, triggersSideBGUID[urand(0, 4)])) + } + if (_summonCountB < MAX_PROWLERS_PER_SIDE) + { + if (Unit* trigger = me->GetUnit(*me, _triggersSideBGUID[urand(0, 4)])) { trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); - ++summonCountB; + ++_summonCountB; } - events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); + } + _events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); break; case EVENT_MARK_OF_ARLOKK: { @@ -226,8 +230,8 @@ class boss_arlokk : public CreatureScript DoCast(target, SPELL_MARK_OF_ARLOKK, true); Talk(SAY_FEAST_PROWLER, target->GetGUID()); } + _events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); break; - events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); } case EVENT_TRANSFORM: { @@ -244,20 +248,20 @@ class boss_arlokk : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_VANISH_VISUAL); DoCast(me, SPELL_VANISH); - events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); break; } case EVENT_VANISH: DoCast(me, SPELL_SUPER_INVIS); me->SetWalk(false); - if (instance) + if (_instance) me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ()); - events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); break; case EVENT_VANISH_2: DoCast(me, SPELL_VANISH); DoCast(me, SPELL_SUPER_INVIS); - events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); break; case EVENT_VISIBLE: me->SetReactState(REACT_AGGRESSIVE); @@ -266,13 +270,13 @@ class boss_arlokk : public CreatureScript AttackStart(target); me->RemoveAura(SPELL_SUPER_INVIS); me->RemoveAura(SPELL_VANISH); - events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); + _events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + _events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); + _events.SetPhase(PHASE_TWO); break; case EVENT_RAVAGE: DoCastVictim(SPELL_RAVAGE, true); - events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + _events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); break; case EVENT_TRANSFORM_BACK: { @@ -284,10 +288,10 @@ class boss_arlokk : public CreatureScript me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg)); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg)); me->UpdateDamagePhysical(BASE_ATTACK); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); - events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); + _events.SetPhase(PHASE_ONE); break; } default: @@ -299,10 +303,10 @@ class boss_arlokk : public CreatureScript } private: - uint8 summonCountA; - uint8 summonCountB; - uint64 triggersSideAGUID[5]; - uint64 triggersSideBGUID[5]; + uint8 _summonCountA; + uint8 _summonCountB; + uint64 _triggersSideAGUID[5]; + uint64 _triggersSideBGUID[5]; }; CreatureAI* GetAI(Creature* creature) const @@ -338,22 +342,22 @@ class npc_zulian_prowler : public CreatureScript struct npc_zulian_prowlerAI : public ScriptedAI { - npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } + npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } void Reset() { if (me->GetPositionY() < -1625.0f) - sideData = 1; + _sideData = 1; else - sideData = 2; + _sideData = 2; DoCast(me, SPELL_SNEAK_RANK_1_1); DoCast(me, SPELL_SNEAK_RANK_1_2); - if (instance) - if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) + if (_instance) + if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ()); - events.ScheduleEvent(EVENT_ATTACK, 6000); + _events.ScheduleEvent(EVENT_ATTACK, 6000); } void EnterCombat(Unit* /*who*/) @@ -366,33 +370,33 @@ class npc_zulian_prowler : public CreatureScript void SpellHit(Unit* caster, SpellInfo const* spell) { if (spell->Id == SPELL_MARK_OF_ARLOKK_TRIGGER) // Should only hit if line of sight - { me->Attack(caster, true); - } } void JustDied(Unit* /*killer*/) { - - if (instance) - if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) - if (arlokk->isAlive()) - arlokk->GetAI()->SetData(sideData, 0); + if (_instance) + { + if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) + { + if (arlokk->isAlive()) + arlokk->GetAI()->SetData(_sideData, 0); + } + } me->DespawnOrUnsummon(4000); } void UpdateAI(const uint32 diff) { - if (UpdateVictim()) { DoMeleeAttackIfReady(); return; } - events.Update(diff); + _events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { @@ -407,9 +411,9 @@ class npc_zulian_prowler : public CreatureScript } private: - int32 sideData; - EventMap events; - InstanceScript* instance; + int32 _sideData; + EventMap _events; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const @@ -433,7 +437,7 @@ class go_gong_of_bethekk : public GameObjectScript bool OnGossipHello(Player* /*player*/, GameObject* go) { - if (InstanceScript* instance = go->GetInstanceScript()) + if (go->GetInstanceScript()) { go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SendCustomAnim(0); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp index 70399b6934c..f3f12bc35c5 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp @@ -112,4 +112,3 @@ void AddSC_boss_gahzranka() { new boss_gahzranka(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp index 15228815d69..809403bb325 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp @@ -121,4 +121,3 @@ void AddSC_boss_hazzarah() { new boss_hazzarah(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index d922e2db3f3..01c5ef998f5 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -40,14 +40,14 @@ class instance_zulgurub : public InstanceMapScript void Initialize() { - zealotLorkhanGUID = 0; - zealotZathGUID = 0; - highPriestTekalGUID = 0; - jindoTheHexxerGUID = 0; - vilebranchSpeakerGUID = 0; - arlokkGUID = 0; - go_ForcefieldGUID = 0; - go_GongOfBethekkGUID = 0; + _zealotLorkhanGUID = 0; + _zealotZathGUID = 0; + _highPriestTekalGUID = 0; + _jindoTheHexxerGUID = 0; + _vilebranchSpeakerGUID = 0; + _arlokkGUID = 0; + _goForcefieldGUID = 0; + _goGongOfBethekkGUID = 0; } bool IsEncounterInProgress() const @@ -61,22 +61,22 @@ class instance_zulgurub : public InstanceMapScript switch (creature->GetEntry()) { case NPC_ZEALOT_LORKHAN: - zealotLorkhanGUID = creature->GetGUID(); + _zealotLorkhanGUID = creature->GetGUID(); break; case NPC_ZEALOT_ZATH: - zealotZathGUID = creature->GetGUID(); + _zealotZathGUID = creature->GetGUID(); break; case NPC_HIGH_PRIEST_THEKAL: - highPriestTekalGUID = creature->GetGUID(); + _highPriestTekalGUID = creature->GetGUID(); break; case NPC_JINDO_THE_HEXXER: - jindoTheHexxerGUID = creature->GetGUID(); + _jindoTheHexxerGUID = creature->GetGUID(); break; case NPC_VILEBRANCH_SPEAKER: - vilebranchSpeakerGUID = creature->GetGUID(); + _vilebranchSpeakerGUID = creature->GetGUID(); break; case NPC_ARLOKK: - arlokkGUID = creature->GetGUID(); + _arlokkGUID = creature->GetGUID(); break; } } @@ -86,13 +86,13 @@ class instance_zulgurub : public InstanceMapScript switch (go->GetEntry()) { case GO_FORCEFIELD: - go_ForcefieldGUID = go->GetGUID(); + _goForcefieldGUID = go->GetGUID(); break; case GO_GONG_OF_BETHEKK: - go_GongOfBethekkGUID = go->GetGUID(); + _goGongOfBethekkGUID = go->GetGUID(); if (GetBossState(DATA_ARLOKK) == DONE) go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - else + else go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); break; default: @@ -105,25 +105,25 @@ class instance_zulgurub : public InstanceMapScript switch (uiData) { case DATA_LORKHAN: - return zealotLorkhanGUID; + return _zealotLorkhanGUID; break; case DATA_ZATH: - return zealotZathGUID; + return _zealotZathGUID; break; case DATA_THEKAL: - return highPriestTekalGUID; + return _highPriestTekalGUID; break; case DATA_JINDO: - return jindoTheHexxerGUID; + return _jindoTheHexxerGUID; break; case NPC_ARLOKK: - return arlokkGUID; + return _arlokkGUID; break; case GO_FORCEFIELD: - return go_ForcefieldGUID; + return _goForcefieldGUID; break; case GO_GONG_OF_BETHEKK: - return go_GongOfBethekkGUID; + return _goGongOfBethekkGUID; break; } return 0; @@ -175,14 +175,14 @@ class instance_zulgurub : public InstanceMapScript //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too. //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too. - uint64 zealotLorkhanGUID; - uint64 zealotZathGUID; - uint64 highPriestTekalGUID; - uint64 jindoTheHexxerGUID; - uint64 vilebranchSpeakerGUID; - uint64 arlokkGUID; - uint64 go_ForcefieldGUID; - uint64 go_GongOfBethekkGUID; + uint64 _zealotLorkhanGUID; + uint64 _zealotZathGUID; + uint64 _highPriestTekalGUID; + uint64 _jindoTheHexxerGUID; + uint64 _vilebranchSpeakerGUID; + uint64 _arlokkGUID; + uint64 _goForcefieldGUID; + uint64 _goGongOfBethekkGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const -- cgit v1.2.3 From 236355265598955861cc9ecd46315737270ac893 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 21 Jan 2013 02:24:25 +0000 Subject: Scripts/ZG: Fix a warning and a compile error introduced in previous commit Personal opinion: BossAI should not have a public field named "instance" --- .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 4b4186c7684..3c549150a78 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -83,7 +83,7 @@ enum Misc Position const PosMoveOnSpawn[1] = { - { -11561.9f, -1627.868f, 41.29941f } + { -11561.9f, -1627.868f, 41.29941f, 0.0f } }; class boss_arlokk : public CreatureScript @@ -101,9 +101,9 @@ class boss_arlokk : public CreatureScript me->RemoveAllAuras(); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); - if (_instance) + if (instance) { - if (GameObject* gate = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) gate->SetGoState(GO_STATE_READY); me->SetWalk(false); me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]); @@ -114,11 +114,11 @@ class boss_arlokk : public CreatureScript { Talk(SAY_DEATH); me->RemoveAllAuras(); - if (_instance) + if (instance) { - if (GameObject* gate = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) gate->SetGoState(GO_STATE_ACTIVE); - _instance->SetBossState(DATA_ARLOKK, DONE); + instance->SetBossState(DATA_ARLOKK, DONE); } } @@ -127,7 +127,7 @@ class boss_arlokk : public CreatureScript _EnterCombat(); _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); _events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - if (_instance) + if (instance) _events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); _events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); _events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); @@ -161,13 +161,13 @@ class boss_arlokk : public CreatureScript void EnterEvadeMode() { - if (_instance) + if (instance) { - if (GameObject* object = me->GetMap()->GetGameObject(_instance->GetData64(GO_FORCEFIELD))) + if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) object->SetGoState(GO_STATE_ACTIVE); - if (GameObject* object = me->GetMap()->GetGameObject(_instance->GetData64(GO_GONG_OF_BETHEKK))) + if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_GONG_OF_BETHEKK))) object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - _instance->SetBossState(DATA_ARLOKK, NOT_STARTED); + instance->SetBossState(DATA_ARLOKK, NOT_STARTED); } me->DespawnOrUnsummon(4000); } @@ -254,7 +254,7 @@ class boss_arlokk : public CreatureScript case EVENT_VANISH: DoCast(me, SPELL_SUPER_INVIS); me->SetWalk(false); - if (_instance) + if (instance) me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ()); _events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); break; -- cgit v1.2.3 From 3523d84a9146b2aecd6895adb2a84f60a76c5f21 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 21 Jan 2013 02:34:43 +0000 Subject: Shooting myself in 3... 2... --- .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 3c549150a78..2a8c663a5ed 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -125,12 +125,12 @@ class boss_arlokk : public CreatureScript void EnterCombat(Unit* /*who*/) { _EnterCombat(); - _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); - _events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); if (instance) - _events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); - _events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); - _events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); + events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL); + events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE); Talk(SAY_AGGRO); // Sets up list of Panther spawners to cast on @@ -185,18 +185,18 @@ class boss_arlokk : public CreatureScript if (!UpdateVictim()) return; - _events.Update(diff); + events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = _events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SHADOW_WORD_PAIN: DoCastVictim(SPELL_SHADOW_WORD_PAIN, true); - _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE); break; case EVENT_GOUGE: DoCastVictim(SPELL_GOUGE, true); @@ -218,7 +218,7 @@ class boss_arlokk : public CreatureScript ++_summonCountB; } } - _events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); + events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL); break; case EVENT_MARK_OF_ARLOKK: { @@ -230,7 +230,7 @@ class boss_arlokk : public CreatureScript DoCast(target, SPELL_MARK_OF_ARLOKK, true); Talk(SAY_FEAST_PROWLER, target->GetGUID()); } - _events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); + events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000)); break; } case EVENT_TRANSFORM: @@ -248,7 +248,7 @@ class boss_arlokk : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_VANISH_VISUAL); DoCast(me, SPELL_VANISH); - _events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE); break; } case EVENT_VANISH: @@ -256,12 +256,12 @@ class boss_arlokk : public CreatureScript me->SetWalk(false); if (instance) me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ()); - _events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE); break; case EVENT_VANISH_2: DoCast(me, SPELL_VANISH); DoCast(me, SPELL_SUPER_INVIS); - _events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE); break; case EVENT_VISIBLE: me->SetReactState(REACT_AGGRESSIVE); @@ -270,13 +270,13 @@ class boss_arlokk : public CreatureScript AttackStart(target); me->RemoveAura(SPELL_SUPER_INVIS); me->RemoveAura(SPELL_VANISH); - _events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); - _events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); - _events.SetPhase(PHASE_TWO); + events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); + events.SetPhase(PHASE_TWO); break; case EVENT_RAVAGE: DoCastVictim(SPELL_RAVAGE, true); - _events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); + events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); break; case EVENT_TRANSFORM_BACK: { @@ -288,10 +288,10 @@ class boss_arlokk : public CreatureScript me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg)); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg)); me->UpdateDamagePhysical(BASE_ATTACK); - _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); - _events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); - _events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); - _events.SetPhase(PHASE_ONE); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); + events.SetPhase(PHASE_ONE); break; } default: -- cgit v1.2.3 From 321b425f366330768f4bb84f8f4f785c53f3d1ff Mon Sep 17 00:00:00 2001 From: Aokromes Date: Mon, 21 Jan 2013 02:47:51 +0000 Subject: Update COPYING Signed-off-by: Nay --- COPYING | 40 +++++++++++----------- .../EasternKingdoms/ZulGurub/boss_arlokk.cpp | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/COPYING b/COPYING index cdfdede6e8c..d159169d105 100644 --- a/COPYING +++ b/COPYING @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. 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 + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 2a8c663a5ed..e4e8235a172 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -377,7 +377,7 @@ class npc_zulian_prowler : public CreatureScript { if (_instance) { - if (Unit* arlokk = me->GetUnit(*me, instance->GetData64(NPC_ARLOKK))) + if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) { if (arlokk->isAlive()) arlokk->GetAI()->SetData(_sideData, 0); -- cgit v1.2.3 From 367e1f7b2b2b2754ea9225af0e8f90cb5b315871 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Mon, 21 Jan 2013 10:11:46 +0100 Subject: Core: Fix warnings --- src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index e4e8235a172..c2806c395f4 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -333,7 +333,7 @@ enum ZulianProwlerEvents Position const PosProwlerCenter[1] = { - { -11556.7f, -1631.344f, 41.2994f } + { -11556.7f, -1631.344f, 41.2994f, 0.0f } }; class npc_zulian_prowler : public CreatureScript -- cgit v1.2.3 From 3cb80f206eb75ab7d1b09662885fd13f8cf46071 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 21 Jan 2013 20:45:09 +0000 Subject: Core/Config: Set mmaps disabled by default --- src/server/game/World/World.cpp | 2 +- src/server/worldserver/worldserver.conf.dist | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index da00034108c..8f42be71f44 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1132,7 +1132,7 @@ void World::LoadConfigSettings(bool reload) sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Using DataDir %s", m_dataPath.c_str()); } - m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", true); + m_bool_configs[CONFIG_ENABLE_MMAPS] = ConfigMgr::GetBoolDefault("mmap.enablePathFinding", false); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "WORLD: MMap data directory is: %smmaps", m_dataPath.c_str()); m_bool_configs[CONFIG_VMAP_INDOOR_CHECK] = ConfigMgr::GetBoolDefault("vmap.enableIndoorCheck", 0); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index b3e6b636b32..51c083a3dbe 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -270,11 +270,11 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1 # # mmap.enablePathFinding -# Description: Enable/Disable pathfinding using mmaps -# Default: 1 - (Enabled) -# 0 - (Disabled) +# Description: Enable/Disable pathfinding using mmaps - experimental +# Default: 0 - (Disabled) +# 1 - (Enabled) -mmap.enablePathFinding = 1 +mmap.enablePathFinding = 0 # # vmap.enableLOS -- cgit v1.2.3 From 0cdadcdd781b768d9869f6b06e6abb572fbfdefc Mon Sep 17 00:00:00 2001 From: Mislav Blažević Date: Tue, 22 Jan 2013 09:36:54 +0100 Subject: Expand ~ to home directory on unix --- src/server/game/World/World.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d232920418d..264119ee99c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1118,6 +1118,15 @@ void World::LoadConfigSettings(bool reload) if (dataPath.at(dataPath.length()-1) != '/' && dataPath.at(dataPath.length()-1) != '\\') dataPath.push_back('/'); +#if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE + if (dataPath[0] == '~') + { + const char* home = getenv("HOME"); + if (home) + dataPath.replace(0, 1, home); + } +#endif + if (reload) { if (dataPath != m_dataPath) -- cgit v1.2.3 From a65caa6da2d6090ca23018706029f3a96a035b55 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 13:13:41 +0100 Subject: Core/Movement: Fixed one (probably many remain) merge error --- .../game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 3a8841848d1..abb4ac9964b 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -107,10 +107,6 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool upd Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->GetPath()); - if (forceDest && updateDestination) - init.SetFacing(i_target.getTarget()->GetOrientation()); - else - init.SetFacing(i_target.getTarget()); init.SetWalk(((D*)this)->EnableWalking()); // Using the same condition for facing target as the one that is used for SetInFront on movement end // - applies to ChaseMovementGenerator mostly -- cgit v1.2.3 From fcd258a8a97098c4392c216f9bd6f99424b5b4b9 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 15:40:12 +0100 Subject: Tools/MeshExtractor: Removed shared and MySQL dependencies. --- src/tools/mesh_extractor/CMakeLists.txt | 65 ++++++++------------------ src/tools/mesh_extractor/Cache.h | 5 +- src/tools/mesh_extractor/Chunk.h | 2 +- src/tools/mesh_extractor/Constants.h | 2 - src/tools/mesh_extractor/ContinentBuilder.h | 4 +- src/tools/mesh_extractor/DBC.cpp | 2 +- src/tools/mesh_extractor/DBC.h | 3 +- src/tools/mesh_extractor/LiquidHandler.h | 2 +- src/tools/mesh_extractor/MPQ.h | 14 +++--- src/tools/mesh_extractor/MPQManager.cpp | 3 +- src/tools/mesh_extractor/MPQManager.h | 4 +- src/tools/mesh_extractor/MeshExtractor.cpp | 28 ++++++----- src/tools/mesh_extractor/TileBuilder.cpp | 30 ++++++------ src/tools/mesh_extractor/Utils.h | 6 ++- src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 16 files changed, 74 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index b8bd9f54331..1b5d1564b71 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -11,69 +11,42 @@ file(GLOB_RECURSE sources *.cpp *.h) -if( UNIX ) - include_directories ( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ) -elseif( WIN32 ) - include_directories ( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast - ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour - ${CMAKE_SOURCE_DIR}/dep/libmpq +add_definitions(-DNO_CORE_FUNCS) + +set(include_Base + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/libmpq + ${CMAKE_SOURCE_DIR}/dep/g3dlite/include + ${ACE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +if( WIN32 ) + set(include_Base + ${include_Base} ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ) + ) endif() +include_directories(${include_Base}) + add_executable(MeshExtractor ${sources} ) target_link_libraries(MeshExtractor - shared g3dlib mpq Recast Detour - ${MYSQL_LIBRARY} - ${OPENSSL_LIBRARIES} - ${OPENSSL_EXTRA_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} ${ACE_LIBRARY} ) -add_dependencies(MeshExtractor mpq Recast Detour) - if( UNIX ) install(TARGETS MeshExtractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 34293b14b54..60e3d8434cf 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -2,8 +2,9 @@ #define CACHE_H #include #include -#include "Common.h" -#include "ace/Synch.h" +#include "Define.h" +#include +#include class WorldModelRoot; class Model; diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h index 2eea36f69b6..f3681a9f576 100644 --- a/src/tools/mesh_extractor/Chunk.h +++ b/src/tools/mesh_extractor/Chunk.h @@ -1,6 +1,6 @@ #ifndef CHUNK_H #define CHUNK_H -#include "Common.h" +#include "Define.h" #include class ChunkedData; diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 54fa073fbef..02e2d25559f 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -1,8 +1,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include "Common.h" - class Constants { public: diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index 3d7b879879e..b36ca125b9e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -2,7 +2,7 @@ #define CONT_BUILDER_H #include #include "WDT.h" -#include "Common.h" +#include "Define.h" class ContinentBuilder { @@ -22,7 +22,7 @@ private: WDT* TileMap; uint32 MapId; uint32 NumberOfThreads; - int tileXMin; + int tileXMin; int tileYMin; int tileXMax; int tileYMax; diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index 3c846363d06..9a55ff6d7ed 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -1,6 +1,6 @@ #include #include "DBC.h" -#include "Common.h" +#include "Define.h" DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true) { diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 0c857bd40ed..5ed57754e73 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -1,7 +1,8 @@ #ifndef DBC_H #define DBC_H #include -#include "Common.h" +#include +#include "Define.h" class Record; diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h index 6e8d0081adb..41e128ba20b 100644 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ b/src/tools/mesh_extractor/LiquidHandler.h @@ -2,7 +2,7 @@ #define LIQUID_H #include "ADT.h" #include "Utils.h" -#include "Common.h" +#include "Define.h" #include diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index 15fce452726..2f8b082f526 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -2,27 +2,25 @@ #define MPQ_H #include "libmpq/mpq.h" -#include "Common.h" -#include +#include "Define.h" +#include #include #include #include #include -using namespace std; - class MPQArchive { public: mpq_archive_s *mpq_a; - - vector Files; + + std::vector Files; MPQArchive(const char* filename); void close(); - void GetFileListTo(vector& filelist) { + void GetFileListTo(std::vector& filelist) { uint32_t filenum; if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; libmpq__off_t size, transferred; @@ -40,7 +38,7 @@ public: while ((token != NULL) && (counter < size)) { //cout << token << endl; token[strlen(token) - 1] = 0; - string s = token; + std::string s = token; filelist.push_back(s); counter += strlen(token) + 2; token = strtok(NULL, seps); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 90491dfb945..0fe07cd8b85 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -2,8 +2,7 @@ #include "MPQ.h" #include "DBC.h" #include "Utils.h" - -#include "ace/Synch.h" +#include char* MPQManager::Files[] = { "common.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index c23d7177825..788be7f5974 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -2,7 +2,9 @@ #define MPQ_MANAGER_H #include "MPQ.h" -#include "ace/Synch.h" +#include +#include +#include class DBC; class MPQManager diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index b164ff5861d..e06f44c7125 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -12,11 +12,6 @@ #include -#include "Common.h" -#include "LoginDatabase.h" -#include "Util.h" -LoginDatabaseWorkerPool LoginDatabase; - MPQManager* MPQHandler; CacheClass* Cache; @@ -64,7 +59,7 @@ void ExtractDBCs() path += std::string(MPQManager::Languages[*itr]) + "/"; Utils::CreateDir(path); } - + std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; // Extract the component file Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); @@ -104,7 +99,7 @@ void ExtractGameobjectModels() { fileName = Utils::FixModelPath(fileName); Model model(path); - + if (model.IsBad) continue; @@ -151,7 +146,7 @@ void ExtractGameobjectModels() fwrite(indices, sizeof(uint16), numTris, output); } - + fwrite("VERT", 4, 1, output); wsize = sizeof(int) + sizeof(float) * 3 * numVerts; fwrite(&wsize, sizeof(int), 1, output); @@ -170,7 +165,7 @@ void ExtractGameobjectModels() fwrite(vertices, sizeof(float), numVerts * 3, output); } - + fclose(output); delete[] indices; delete[] vertices; @@ -254,11 +249,14 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis param = argv[++i]; if (!param) return false; - std::string maps = std::string(param); - Tokenizer tokens(maps, ','); - for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) - mapList.insert(atoi(*itr)); + char* copy = strdup(param); + char* token = strtok(copy, ","); + while (token) + { + mapList.insert(atoi(token)); + token = strtok(NULL, ","); + } printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); } @@ -337,7 +335,7 @@ int main(int argc, char* argv[]) uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; - + if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags)) { PrintUsage(); @@ -425,6 +423,6 @@ int main(int argc, char* argv[]) printf("Found!"); } - + return 0; } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 4a14cbbd51d..9bb9b11619f 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -10,7 +10,7 @@ #include "RecastAlloc.h" #include "DetourNavMeshBuilder.h" -#include "ace/Synch.h" +#include TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) @@ -118,7 +118,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); fclose(debug); } - + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -128,13 +128,13 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - + rcVcopy(Config.bmin, cBuilder->bmin); rcVcopy(Config.bmax, cBuilder->bmax); - + // this sets the dimensions of the heightfield - should maybe happen before border padding rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height); - + // Initialize per tile config. rcConfig tileCfg = Config; tileCfg.width = Config.tileSize + Config.borderSize * 2; @@ -154,8 +154,8 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs; tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs; tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs; - - + + rcHeightfield* hf = rcAllocHeightfield(); rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch); rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); @@ -198,7 +198,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Free memory rcFreeCompactHeightfield(chf); rcFreeContourSet(cset); - + pmmerge[nmerge] = pmesh; dmmerge[nmerge] = dmesh; ++nmerge; @@ -207,15 +207,15 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) rcPolyMesh* pmesh = rcAllocPolyMesh(); rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); - + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); - + delete[] pmmerge; delete[] dmmerge; - + printf("[%02i,%02i] Meshes merged!\n", X, Y); - + // Remove padding from the polymesh data. (Remove this odditity) for (int i = 0; i < pmesh->nverts; ++i) { @@ -262,10 +262,10 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) rcVcopy(params.bmin, cBuilder->bmin); rcVcopy(params.bmax, cBuilder->bmax); - + // Offmesh-connection settings params.offMeshConCount = 0; // none for now - + params.tileSize = Constants::VertexPerMap; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) @@ -281,7 +281,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) delete vertices; return NULL; } - + int navDataSize; uint8* navData; printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index e7380ed8142..41ea33e6157 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -7,12 +7,16 @@ #include "G3D/Matrix4.h" #include "DetourNavMesh.h" -#include "Common.h" +#include "Define.h" #include "Constants.h" +#include + struct WorldModelDefinition; class DoodadInstance; +#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } + struct Vector3 { Vector3() {} diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 6ce41807492..ecfff4e97d4 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -3,7 +3,7 @@ #include "Chunk.h" #include "Cache.h" #include "Model.h" -#include "Common.h" +#include "Define.h" #include "G3D/Matrix4.h" #include diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index cccedfa60fb..29715ded696 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -1,6 +1,6 @@ #ifndef WMODEL_HNDL_H #define WMODEL_HNDL_H -#include "Common.h" +#include "Define.h" #include "Utils.h" #include "WorldModelRoot.h" #include "ObjectDataHandler.h" -- cgit v1.2.3 From 259a29c0935e566dd63d8c03360c5cd19b4ffe52 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 18:40:32 +0100 Subject: Tools/Extractors: Mmap extractors no longer depend on shared and MySQL libraries --- cmake/showoptions.cmake | 1 + src/server/collision/Management/VMapManager2.cpp | 12 ++-- src/server/collision/Maps/MapTree.cpp | 21 ++---- src/server/collision/Models/GameObjectModel.cpp | 13 ++-- src/server/collision/VMapDefinitions.h | 12 ++++ src/server/shared/Debugging/Errors.h | 2 +- src/tools/map_extractor/CMakeLists.txt | 19 +++-- src/tools/map_extractor/mpq_libmpq.cpp | 2 +- src/tools/map_extractor/mpq_libmpq04.h | 3 - src/tools/mesh_extractor/CMakeLists.txt | 8 +-- src/tools/mesh_extractor/MPQ.cpp | 2 +- src/tools/mmaps_generator/CMakeLists.txt | 45 +++++------- src/tools/mmaps_generator/IntermediateValues.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 55 +++++++------- src/tools/mmaps_generator/MapBuilder.h | 10 +-- src/tools/mmaps_generator/PathCommon.h | 43 +++++++++-- src/tools/mmaps_generator/PathGenerator.cpp | 3 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 92 +++++++++++++++++++----- src/tools/mmaps_generator/TerrainBuilder.h | 11 +-- src/tools/mmaps_generator/VMapExtensions.cpp | 6 +- src/tools/vmap4_assembler/CMakeLists.txt | 2 - src/tools/vmap4_extractor/CMakeLists.txt | 25 +++---- src/tools/vmap4_extractor/mpq_libmpq.cpp | 2 +- src/tools/vmap4_extractor/mpq_libmpq04.h | 3 - src/tools/vmap4_extractor/wdtfile.cpp | 2 +- 25 files changed, 220 insertions(+), 176 deletions(-) (limited to 'src') diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake index 47ad7b0889b..d3415e4e204 100644 --- a/cmake/showoptions.cmake +++ b/cmake/showoptions.cmake @@ -34,6 +34,7 @@ endif() if( TOOLS ) message("* Build map/vmap tools : Yes") + add_definitions(-DNO_CORE_FUNCS) else() message("* Build map/vmap tools : No (default)") endif() diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 5e3741ca753..8a1bd346957 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -24,13 +24,13 @@ #include "MapTree.h" #include "ModelInstance.h" #include "WorldModel.h" -#include "VMapDefinitions.h" -#include "Log.h" #include #include #include #include "DisableMgr.h" #include "DBCStores.h" +#include "Log.h" +#include "VMapDefinitions.h" using G3D::Vector3; @@ -257,11 +257,11 @@ namespace VMAP WorldModel* worldmodel = new WorldModel(); if (!worldmodel->readFile(basepath + filename + ".vmo")) { - sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str()); delete worldmodel; return NULL; } - sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); model = iLoadedModelFiles.insert(std::pair(filename, ManagedModel())).first; model->second.setModel(worldmodel); } @@ -277,12 +277,12 @@ namespace VMAP ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { - sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str()); return; } if (model->second.decRefCount() == 0) { - sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str()); delete model->second.getModel(); iLoadedModelFiles.erase(model); } diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 5f4e2b6aa8b..e3cd158709c 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -27,12 +27,6 @@ #include #include -#ifndef NO_CORE_FUNCS - #include "Errors.h" -#else - #define ASSERT(x) -#endif - using G3D::Vector3; namespace VMAP @@ -277,7 +271,7 @@ namespace VMAP bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm) { - sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str()); bool success = true; std::string fullname = iBasePath + fname; FILE* rf = fopen(fullname.c_str(), "rb"); @@ -310,7 +304,7 @@ namespace VMAP if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); - sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); + VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); if (model) { // assume that global model always is the first and only tree value (could be improved...) @@ -320,7 +314,7 @@ namespace VMAP else { success = false; - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); } } @@ -356,7 +350,7 @@ namespace VMAP } if (!iTreeValues) { - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY); return false; } bool result = true; @@ -382,7 +376,7 @@ namespace VMAP // acquire model instance WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); if (!model) - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); // update tree uint32 referencedVal; @@ -432,7 +426,7 @@ namespace VMAP loadedTileMap::iterator tile = iLoadedTiles.find(tileID); if (tile == iLoadedTiles.end()) { - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY); return; } if (tile->second) // file associated with tile @@ -466,7 +460,7 @@ namespace VMAP else { if (!iLoadedSpawns.count(referencedNode)) - sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID); else if (--iLoadedSpawns[referencedNode] == 0) { iTreeValues[referencedNode].setUnloaded(); @@ -480,5 +474,4 @@ namespace VMAP } iLoadedTiles.erase(tile); } - } diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 0ecf02648f9..54283389387 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -34,8 +34,6 @@ using G3D::Vector3; using G3D::Ray; using G3D::AABox; -#ifndef NO_CORE_FUNCS - struct GameobjectModelData { GameobjectModelData(const std::string& name_, const AABox& box) : @@ -54,7 +52,7 @@ void LoadGameObjectModelList() FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { - sLog->outError(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); return; } @@ -73,7 +71,7 @@ void LoadGameObjectModelList() || fread(&v1, sizeof(Vector3), 1, model_list_file) != 1 || fread(&v2, sizeof(Vector3), 1, model_list_file) != 1) { - sLog->outError(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); break; } @@ -84,8 +82,7 @@ void LoadGameObjectModelList() } fclose(model_list_file); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime)); - + VMAP_INFO_LOG(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime)); } GameObjectModel::~GameObjectModel() @@ -104,7 +101,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn // ignore models with no bounds if (mdl_box == G3D::AABox::zero()) { - sLog->outError(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str()); + VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str()); return false; } @@ -184,5 +181,3 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto } return hit; } - -#endif diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index 609d00cd00f..56084389ad6 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -31,4 +31,16 @@ namespace VMAP // defined in TileAssembler.cpp currently... bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len); } + +// Set of helper macros for extractors (VMAP and MMAP) +#ifndef NO_CORE_FUNCS +#define VMAP_ERROR_LOG(FILTER, ...) sLog->outError(FILTER, __VA_ARGS__) +#define VMAP_DEBUG_LOG(FILTER, ...) sLog->outDebug(FILTER, __VA_ARGS__) +#define VMAP_INFO_LOG(FILTER, ...) sLog->outInfo(FILTER, __VA_ARGS__) +#else +#define VMAP_ERROR_LOG(FILTER, ...) printf(__VA_ARGS__) +#define VMAP_DEBUG_LOG(FILTER, ...) printf(__VA_ARGS__) +#define VMAP_INFO_LOG(FILTER, ...) printf(__VA_ARGS__) +#endif + #endif diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h index 3d10740f149..10e94634e9a 100644 --- a/src/server/shared/Debugging/Errors.h +++ b/src/server/shared/Debugging/Errors.h @@ -24,7 +24,7 @@ #include #include -#define WPAssert(assertion) { if (!(assertion)) { ACE_Stack_Trace st; sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } +#define WPAssert(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } #define WPError(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); *((volatile int*)NULL) = 0; } } #define WPWarning(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); } } #define WPFatal(assertion, errmsg) { if (!(assertion)) { sLog->outError(LOG_FILTER_GENERAL, "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); ACE_OS::sleep(10); *((volatile int*)NULL) = 0; } } diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index 9fb8d5713d7..ea073456680 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -11,23 +11,22 @@ file(GLOB_RECURSE sources *.cpp *.h) -if( UNIX ) - include_directories ( +set(include_Dirs ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/loadlib - ) -elseif( WIN32 ) - include_directories ( - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/dep/libmpq +) + +if( WIN32 ) + set(include_Dirs + ${include_Dirs} ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/loadlib ) endif() +include_directories(${include_Dirs}) + add_executable(mapextractor ${sources} ) @@ -38,8 +37,6 @@ target_link_libraries(mapextractor ${ZLIB_LIBRARIES} ) -add_dependencies(mapextractor mpq) - if( UNIX ) install(TARGETS mapextractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp index 81aa8cc2894..1c1a12e7b85 100644 --- a/src/tools/map_extractor/mpq_libmpq.cpp +++ b/src/tools/map_extractor/mpq_libmpq.cpp @@ -79,7 +79,7 @@ size_t MPQFile::read(void* dest, size_t bytes) if (eof) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index 89f715e9e87..9f0163067c4 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -1,6 +1,3 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - #ifndef MPQ_H #define MPQ_H diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt index 1b5d1564b71..9ed8472051d 100644 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ b/src/tools/mesh_extractor/CMakeLists.txt @@ -9,9 +9,7 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources *.cpp *.h) - -add_definitions(-DNO_CORE_FUNCS) +file(GLOB_RECURSE meshExtract_Sources *.cpp *.h) set(include_Base ${CMAKE_BINARY_DIR} @@ -33,9 +31,7 @@ endif() include_directories(${include_Base}) -add_executable(MeshExtractor - ${sources} -) +add_executable(MeshExtractor ${meshExtract_Sources}) target_link_libraries(MeshExtractor g3dlib diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index b7be181594d..18a9eb0f0e3 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -77,7 +77,7 @@ size_t MPQFile::Read(void* dest, size_t bytes) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 229a2cd808f..99492abf8ee 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -8,17 +8,11 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -file(GLOB_RECURSE sources *.cpp *.h) +file(GLOB_RECURSE mmap_gen_sources *.cpp *.h) -# definitions -add_definitions(-DNO_CORE_FUNCS) -add_definitions(-DDEBUG) -add_definitions(-DNO_vsnprintf) - -include_directories( +set(mmap_gen_Includes ${CMAKE_BINARY_DIR} ${ACE_INCLUDE_DIR} - ${MYSQL_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/dep/libmpq ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/dep/bzip2 @@ -26,20 +20,6 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/Database - ${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation - ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging - ${CMAKE_SOURCE_DIR}/src/server/shared/Threading - ${CMAKE_SOURCE_DIR}/src/server/shared/Logging - ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic - ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference - ${CMAKE_SOURCE_DIR}/src/server/game/Maps - ${CMAKE_SOURCE_DIR}/src/server/game/DataStores - ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints - ${CMAKE_SOURCE_DIR}/src/server/game/Grids - ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells - ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous ${CMAKE_SOURCE_DIR}/src/server/game/Conditions ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management @@ -47,18 +27,25 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/collision/Models ) -add_executable(mmaps_generator ${sources}) +if( WIN32 ) + set(mmap_gen_Includes + ${mmap_gen_Includes} + ${CMAKE_SOURCE_DIR}/dep/libmpq/win + ) +endif() + +include_directories(${mmap_gen_Includes}) + +add_executable(mmaps_generator ${mmap_gen_sources}) target_link_libraries(mmaps_generator - ${MYSQL_LIBRARY} + collision + g3dlib + Recast + Detour ${ACE_LIBRARY} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} - Recast - Detour - collision - g3dlib - shared ) if( UNIX ) diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index 6fad96887a2..a490273ad80 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -37,7 +37,7 @@ namespace MMAP printf("%sWriting debug output... \r", tileString); - string name("meshes/%03u%02i%02i."); + std::string name("meshes/%03u%02i%02i."); #define DEBUG_WRITE(fileExtension,data) \ do { \ diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 9e6acd71a72..a62011ddfff 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -21,29 +21,34 @@ #include "MapTree.h" #include "ModelInstance.h" -#include "LoginDatabase.h" #include "DetourNavMeshBuilder.h" #include "DetourNavMesh.h" #include "DetourCommon.h" -// These make the linker happy. -LoginDatabaseWorkerPool LoginDatabase; -uint32 GetLiquidFlags(uint32 /*liquidType*/) -{ - return 0; -} - #include "DisableMgr.h" +#include + +uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; } namespace DisableMgr { - bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/) - { - return 0; - } + bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; } } -using namespace VMAP; +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 3 + +struct MmapTileHeader +{ + uint32 mmapMagic; + uint32 dtVersion; + uint32 mmapVersion; + uint32 size; + bool usesLiquids : 1; + + MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), + mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} +}; namespace MMAP { @@ -83,7 +88,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::discoverTiles() { - vector files; + std::vector files; uint32 mapID, tileX, tileY, tileID, count = 0; char filter[12]; @@ -94,7 +99,7 @@ namespace MMAP mapID = uint32(atoi(files[i].substr(0,3).c_str())); if (m_tiles.find(mapID) == m_tiles.end()) { - m_tiles.insert(pair*>(mapID, new set)); + m_tiles.insert(std::pair*>(mapID, new std::set)); count++; } } @@ -104,7 +109,7 @@ namespace MMAP for (uint32 i = 0; i < files.size(); ++i) { mapID = uint32(atoi(files[i].substr(0,3).c_str())); - m_tiles.insert(pair*>(mapID, new set)); + m_tiles.insert(std::pair*>(mapID, new std::set)); count++; } printf("found %u.\n", count); @@ -113,7 +118,7 @@ namespace MMAP printf("Discovering tiles... "); for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) { - set* tiles = (*itr).second; + std::set* tiles = (*itr).second; mapID = (*itr).first; sprintf(filter, "%03u*.vmtile", mapID); @@ -146,14 +151,14 @@ namespace MMAP } /**************************************************************************/ - set* MapBuilder::getTileList(uint32 mapID) + std::set* MapBuilder::getTileList(uint32 mapID) { TileList::iterator itr = m_tiles.find(mapID); if (itr != m_tiles.end()) return (*itr).second; - set* tiles = new set(); - m_tiles.insert(pair*>(mapID, tiles)); + std::set* tiles = new std::set(); + m_tiles.insert(std::pair*>(mapID, tiles)); return tiles; } @@ -318,7 +323,7 @@ namespace MMAP { printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID); - set* tiles = getTileList(mapID); + std::set* tiles = getTileList(mapID); // make sure we process maps which don't have tiles if (!tiles->size()) @@ -346,7 +351,7 @@ namespace MMAP // now start building mmtiles for each tile printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + for (std::set::iterator it = tiles->begin(); it != tiles->end(); ++it) { uint32 tileX, tileY; @@ -407,7 +412,7 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { - set* tiles = getTileList(mapID); + std::set* tiles = getTileList(mapID); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -423,9 +428,9 @@ namespace MMAP /*** calculate bounds of map ***/ uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; - for (set::iterator it = tiles->begin(); it != tiles->end(); ++it) + for (std::set::iterator it = tiles->begin(); it != tiles->end(); ++it) { - StaticMapTree::unpackTileID((*it), tileX, tileY); + StaticMapTree::unpackTileID(*it, tileX, tileY); if (tileX > tileXMax) tileXMax = tileX; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index c083e0b680a..ea9636b3cc3 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -26,22 +26,18 @@ #include "TerrainBuilder.h" #include "IntermediateValues.h" -#include "IVMapManager.h" -#include "WorldModel.h" - #include "Recast.h" #include "DetourNavMesh.h" -#include "ace/Task.h" +#include -using namespace std; using namespace VMAP; // G3D namespace typedefs conflicts with ACE typedefs namespace MMAP { - typedef map*> TileList; + typedef std::map*> TileList; struct Tile { Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {} @@ -87,7 +83,7 @@ namespace MMAP private: // detect maps and tiles void discoverTiles(); - set* getTileList(uint32 mapID); + std::set* getTileList(uint32 mapID); void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 413f2b8735d..3e06ff58410 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -21,6 +21,7 @@ #include #include +#include #include "Define.h" @@ -33,7 +34,19 @@ #include #endif -using namespace std; +enum NavTerrain +{ + NAV_EMPTY = 0x00, + NAV_GROUND = 0x01, + NAV_MAGMA = 0x02, + NAV_SLIME = 0x04, + NAV_WATER = 0x08, + NAV_UNUSED1 = 0x10, + NAV_UNUSED2 = 0x20, + NAV_UNUSED3 = 0x40, + NAV_UNUSED4 = 0x80 + // we only have 8 bits +}; namespace MMAP { @@ -75,12 +88,12 @@ namespace MMAP LISTFILE_OK = 1 }; - inline ListFilesResult getDirContents(vector &fileList, string dirpath = ".", string filter = "*") + inline ListFilesResult getDirContents(std::vector &fileList, std::string dirpath = ".", std::string filter = "*") { #ifdef WIN32 HANDLE hFind; WIN32_FIND_DATA findFileInfo; - string directory; + std::string directory; directory = dirpath + "/" + filter; @@ -91,7 +104,7 @@ namespace MMAP do { if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - fileList.push_back(string(findFileInfo.cFileName)); + fileList.push_back(std::string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); @@ -109,7 +122,7 @@ namespace MMAP if ((dp = readdir(dirp)) != NULL) { if (matchWildcardFilter(filter.c_str(), dp->d_name)) - fileList.push_back(string(dp->d_name)); + fileList.push_back(std::string(dp->d_name)); } else break; @@ -123,6 +136,26 @@ namespace MMAP return LISTFILE_OK; } + + inline uint32 getMSTime() + { + static const ACE_Time_Value ApplicationStartTime = ACE_OS::gettimeofday(); + return (ACE_OS::gettimeofday() - ApplicationStartTime).msec(); + } + + inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime) + { + // getMSTime() have limited data range and this is case when it overflow in this tick + if (oldMSTime > newMSTime) + return (0xFFFFFFFF - oldMSTime) + newMSTime; + else + return newMSTime - oldMSTime; + } + + inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime) + { + return getMSTimeDiff(oldMSTime, getMSTime()); + } } #endif diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 9707cb4160a..01059099f98 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -18,13 +18,12 @@ #include "PathCommon.h" #include "MapBuilder.h" -#include "Timer.h" using namespace MMAP; bool checkDirectories(bool debugOutput) { - vector dirFiles; + std::vector dirFiles; if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index f7cf76e9718..c3d6541dfa3 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -24,6 +24,60 @@ #include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" +#include + +// ****************************************** +// 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; + uint32 holesOffset; + uint32 holesSize; +}; + +#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; +}; + +#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_LIQUID_TYPE_DARK_WATER 0x10 +#define MAP_LIQUID_TYPE_WMO_WATER 0x20 namespace MMAP { @@ -139,7 +193,7 @@ namespace MMAP count += fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile); if (count != expected) printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count); - + heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255; for (int i = 0; i < V9_SIZE_SQ; ++i) @@ -612,11 +666,11 @@ namespace MMAP // now we have a model to add to the meshdata retval = true; - vector groupModels; + std::vector groupModels; worldModel->getGroupModels(groupModels); // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != instance.name.npos || instance.name.find(".M2") != instance.name.npos; + bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos; // transform data float scale = instance.iScale; @@ -625,14 +679,14 @@ namespace MMAP position.x -= 32*GRID_SIZE; position.y -= 32*GRID_SIZE; - for (vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) + for (std::vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) { - vector tempVertices; - vector transformedVertices; - vector tempTriangles; + std::vector tempVertices; + std::vector transformedVertices; + std::vector tempTriangles; WmoLiquid* liquid = NULL; - (*it).getMeshData(tempVertices, tempTriangles, liquid); + it->getMeshData(tempVertices, tempTriangles, liquid); // first handle collision mesh transform(tempVertices, transformedVertices, scale, rotation, position); @@ -645,8 +699,8 @@ namespace MMAP // now handle liquid data if (liquid) { - vector liqVerts; - vector liqTris; + std::vector liqVerts; + std::vector liqTris; uint32 tilesX, tilesY, vertsX, vertsY; Vector3 corner; liquid->getPosInfo(tilesX, tilesY, corner); @@ -732,9 +786,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::transform(vector &source, vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { // apply tranform, then mirror along the horizontal axes Vector3 v((*it) * rotation * scale + position); @@ -745,9 +799,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyVertices(vector &source, G3D::Array &dest) + void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).y); dest.push_back((*it).z); @@ -756,11 +810,11 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyIndices(vector &source, G3D::Array &dest, int offset, bool flip) + void TerrainBuilder::copyIndices(std::vector &source, G3D::Array &dest, int offset, bool flip) { if (flip) { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).idx2+offset); dest.push_back((*it).idx1+offset); @@ -769,7 +823,7 @@ namespace MMAP } else { - for (vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).idx0+offset); dest.push_back((*it).idx1+offset); @@ -789,7 +843,7 @@ namespace MMAP /**************************************************************************/ void TerrainBuilder::cleanVertices(G3D::Array &verts, G3D::Array &tris) { - map vertMap; + std::map vertMap; int* t = tris.getCArray(); float* v = verts.getCArray(); @@ -819,7 +873,7 @@ namespace MMAP // update triangles to use new indices for (int i = 0; i < tris.size(); ++i) { - map::iterator it; + std::map::iterator it; if ((it = vertMap.find(t[i])) == vertMap.end()) continue; diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6ad4284f416..069a5a94c84 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -20,17 +20,12 @@ #define _MMAP_TERRAIN_BUILDER_H #include "PathCommon.h" -#include "Map.h" -#include "SharedDefines.h" - #include "WorldModel.h" #include "G3D/Array.h" #include "G3D/Vector3.h" #include "G3D/Matrix3.h" -using namespace Trinity; - namespace MMAP { enum Spot @@ -93,10 +88,10 @@ namespace MMAP bool usesLiquids() { return !m_skipLiquid; } // vert and triangle methods - static void transform(vector &original, vector &transformed, + static void transform(std::vector &original, std::vector &transformed, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position); - static void copyVertices(vector &source, G3D::Array &dest); - static void copyIndices(vector &source, G3D::Array &dest, int offest, bool flip); + static void copyVertices(std::vector &source, G3D::Array &dest); + static void copyIndices(std::vector &source, G3D::Array &dest, int offest, bool flip); static void copyIndices(G3D::Array &src, G3D::Array &dest, int offset); static void cleanVertices(G3D::Array &verts, G3D::Array &tris); private: diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 37b7d94af55..972f222bba6 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -22,8 +22,6 @@ #include "WorldModel.h" #include "ModelInstance.h" -using namespace std; - namespace VMAP { // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator @@ -43,13 +41,13 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void WorldModel::getGroupModels(vector &groupModels) + void WorldModel::getGroupModels(std::vector &groupModels) { groupModels = this->groupModels; } // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(vector &vertices, vector &triangles, WmoLiquid* &liquid) + void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) { vertices = this->vertices; triangles = this->triangles; diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt index 55b6514d091..8d455eae6ee 100644 --- a/src/tools/vmap4_assembler/CMakeLists.txt +++ b/src/tools/vmap4_assembler/CMakeLists.txt @@ -20,9 +20,7 @@ include_directories( ${ZLIB_INCLUDE_DIR} ) -add_definitions(-DNO_CORE_FUNCS) add_executable(vmap4assembler VMapAssembler.cpp) -add_dependencies(vmap4assembler mpq) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set_target_properties(vmap4assembler PROPERTIES LINK_FLAGS "-framework Carbon") diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt index 19798e46475..023f5447f85 100644 --- a/src/tools/vmap4_extractor/CMakeLists.txt +++ b/src/tools/vmap4_extractor/CMakeLists.txt @@ -11,26 +11,19 @@ file(GLOB_RECURSE sources *.cpp *.h) -# uncomment next line to disable debug mode -add_definitions("-DIOMAP_DEBUG") - -# build setup currently only supports libmpq 0.4.x -add_definitions("-DUSE_LIBMPQ04") -add_definitions("-Wall") -add_definitions("-ggdb") -add_definitions("-O3") - -if( UNIX ) - include_directories( - ${CMAKE_SOURCE_DIR}/dep/libmpq - ) -elseif( WIN32 ) - include_directories( +set(include_Dirs ${CMAKE_SOURCE_DIR}/dep/libmpq +) + +if( WIN32 ) + set(include_Dirs + ${include_Dirs} ${CMAKE_SOURCE_DIR}/dep/libmpq/win ) endif() +include_directories(${include_Dirs}) + add_executable(vmap4extractor ${sources}) target_link_libraries(vmap4extractor @@ -39,8 +32,6 @@ target_link_libraries(vmap4extractor ${ZLIB_LIBRARIES} ) -add_dependencies(vmap4extractor mpq) - if( UNIX ) install(TARGETS vmap4extractor DESTINATION bin) elseif( WIN32 ) diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp index 528b9679a58..ffa097d9a22 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq.cpp +++ b/src/tools/vmap4_extractor/mpq_libmpq.cpp @@ -79,7 +79,7 @@ size_t MPQFile::read(void* dest, size_t bytes) if (eof) return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size_t(size)) { bytes = size - pointer; eof = true; } diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index 89f715e9e87..9f0163067c4 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -1,6 +1,3 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - #ifndef MPQ_H #define MPQ_H diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 7420edfee2e..d9216fd77eb 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -35,7 +35,7 @@ WDTFile::WDTFile(char* file_name, char* file_name1) : WDT(file_name), gWmoInstan filename.append(file_name1,strlen(file_name1)); } -bool WDTFile::init(char */*map_id*/, unsigned int mapID) +bool WDTFile::init(char* /*map_id*/, unsigned int mapID) { if (WDT.isEof()) { -- cgit v1.2.3 From 10d4d2e5b74ef682f5db5364dd52547ec39f4510 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 18:45:09 +0100 Subject: Core/Objects: Changed how update fields marked for sending are stored serverside to use our UpdateMask class --- src/server/game/Entities/Object/Object.cpp | 49 ++++++++++++++---------------- src/server/game/Entities/Object/Object.h | 5 ++- 2 files changed, 24 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 6f4f3cf9d3d..f20d452dc96 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -75,7 +75,6 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1) m_objectType = TYPEMASK_OBJECT; m_uint32Values = NULL; - _changedFields = NULL; m_valuesCount = 0; _fieldNotifyFlags = UF_FLAG_DYNAMIC; @@ -119,8 +118,6 @@ Object::~Object() } delete [] m_uint32Values; - delete [] _changedFields; - } void Object::_InitValues() @@ -128,8 +125,7 @@ void Object::_InitValues() m_uint32Values = new uint32[m_valuesCount]; memset(m_uint32Values, 0, m_valuesCount*sizeof(uint32)); - _changedFields = new bool[m_valuesCount]; - memset(_changedFields, 0, m_valuesCount*sizeof(bool)); + _changesMask.SetCount(m_valuesCount); m_objectUpdated = false; } @@ -757,7 +753,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* void Object::ClearUpdateMask(bool remove) { - memset(_changedFields, 0, m_valuesCount*sizeof(bool)); + _changesMask.Clear(); if (m_objectUpdated) { @@ -854,13 +850,12 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin for (uint32 index = 0; index < count; ++index) { m_uint32Values[startOffset + index] = atol(tokens[index]); - _changedFields[startOffset + index] = true; + _changesMask.SetBit(startOffset + index); } } void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const { - bool* indexes = _changedFields; uint32* flags = NULL; bool isSelf = target == this; bool isOwner = false; @@ -870,8 +865,8 @@ void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); - for (uint16 index = 0; index < m_valuesCount; ++index, ++indexes) - if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*indexes && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) + for (uint16 index = 0; index < m_valuesCount; ++index) + if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (_changesMask.GetBit(index) && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) updateMask->SetBit(index); } @@ -899,7 +894,7 @@ void Object::SetInt32Value(uint16 index, int32 value) if (m_int32Values[index] != value) { m_int32Values[index] = value; - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -916,7 +911,7 @@ void Object::SetUInt32Value(uint16 index, uint32 value) if (m_uint32Values[index] != value) { m_uint32Values[index] = value; - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -931,7 +926,7 @@ void Object::UpdateUInt32Value(uint16 index, uint32 value) ASSERT(index < m_valuesCount || PrintIndexError(index, true)); m_uint32Values[index] = value; - _changedFields[index] = true; + _changesMask.SetBit(index); } void Object::SetUInt64Value(uint16 index, uint64 value) @@ -941,8 +936,8 @@ void Object::SetUInt64Value(uint16 index, uint64 value) { m_uint32Values[index] = PAIR64_LOPART(value); m_uint32Values[index + 1] = PAIR64_HIPART(value); - _changedFields[index] = true; - _changedFields[index + 1] = true; + _changesMask.SetBit(index); + _changesMask.SetBit(index + 1); if (m_inWorld && !m_objectUpdated) { @@ -959,8 +954,8 @@ bool Object::AddUInt64Value(uint16 index, uint64 value) { m_uint32Values[index] = PAIR64_LOPART(value); m_uint32Values[index + 1] = PAIR64_HIPART(value); - _changedFields[index] = true; - _changedFields[index + 1] = true; + _changesMask.SetBit(index); + _changesMask.SetBit(index + 1); if (m_inWorld && !m_objectUpdated) { @@ -981,8 +976,8 @@ bool Object::RemoveUInt64Value(uint16 index, uint64 value) { m_uint32Values[index] = 0; m_uint32Values[index + 1] = 0; - _changedFields[index] = true; - _changedFields[index + 1] = true; + _changesMask.SetBit(index); + _changesMask.SetBit(index + 1); if (m_inWorld && !m_objectUpdated) { @@ -1003,7 +998,7 @@ void Object::SetFloatValue(uint16 index, float value) if (m_floatValues[index] != value) { m_floatValues[index] = value; - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1027,7 +1022,7 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value) { m_uint32Values[index] &= ~uint32(uint32(0xFF) << (offset * 8)); m_uint32Values[index] |= uint32(uint32(value) << (offset * 8)); - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1051,7 +1046,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value) { m_uint32Values[index] &= ~uint32(uint32(0xFFFF) << (offset * 16)); m_uint32Values[index] |= uint32(uint32(value) << (offset * 16)); - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1118,7 +1113,7 @@ void Object::SetFlag(uint16 index, uint32 newFlag) if (oldval != newval) { m_uint32Values[index] = newval; - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1139,7 +1134,7 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag) if (oldval != newval) { m_uint32Values[index] = newval; - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1162,7 +1157,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) if (!(uint8(m_uint32Values[index] >> (offset * 8)) & newFlag)) { m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8)); - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1185,7 +1180,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) if (uint8(m_uint32Values[index] >> (offset * 8)) & oldFlag) { m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8)); - _changedFields[index] = true; + _changesMask.SetBit(index); if (m_inWorld && !m_objectUpdated) { @@ -1968,7 +1963,7 @@ void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf) void Object::ForceValuesUpdateAtIndex(uint32 i) { - _changedFields[i] = true; + _changesMask.SetBit(i); if (m_inWorld && !m_objectUpdated) { sObjectAccessor->AddUpdateObject(this); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index a9afd074c67..641f9afb154 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -20,7 +20,7 @@ #define _OBJECT_H #include "Common.h" -#include "UpdateFields.h" +#include "UpdateMask.h" #include "UpdateData.h" #include "GridReference.h" #include "ObjectDefines.h" @@ -107,7 +107,6 @@ class ByteBuffer; class WorldSession; class Creature; class Player; -class UpdateMask; class InstanceScript; class GameObject; class TempSummon; @@ -348,7 +347,7 @@ class Object float *m_floatValues; }; - bool* _changedFields; + UpdateMask _changesMask; uint16 m_valuesCount; -- cgit v1.2.3 From 5b9159e165ea4bca3ab32317b180d9d543f99dbf Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 19:07:40 +0100 Subject: Tools: Build fix --- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/Utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 0fe07cd8b85..5ae8558d749 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -14,7 +14,7 @@ char* MPQManager::Files[] = { "patch-3.MPQ" }; -char* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; +char const* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; void MPQManager::Initialize() { diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 41ea33e6157..64fb1bb35ba 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -15,7 +15,7 @@ struct WorldModelDefinition; class DoodadInstance; -#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } +#define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } struct Vector3 { -- cgit v1.2.3 From 7a74f68c0d974de5a1f885904fefa45db934da3d Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 18:14:32 +0000 Subject: Tools/MapExtractor: Fix displaying of a few counts in Windows %zu works fine on GCC/Linux, but fails in MSVC/Windows --- src/tools/map_extractor/System.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 2e117934679..bf88a92c32a 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -222,7 +222,7 @@ uint32 ReadMapDBC() map_ids[x].id = dbc.getRecord(x).getUInt(0); strcpy(map_ids[x].name, dbc.getRecord(x).getString(1)); } - printf("Done! (%zu maps loaded)\n", map_count); + printf("Done! (%u maps loaded)\n", (uint32)map_count); return map_count; } @@ -247,7 +247,7 @@ void ReadAreaTableDBC() maxAreaId = dbc.getMaxId(); - printf("Done! (%zu areas loaded)\n", area_count); + printf("Done! (%u areas loaded)\n", (uint32)area_count); } void ReadLiquidTypeTableDBC() @@ -268,7 +268,7 @@ void ReadLiquidTypeTableDBC() for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - printf("Done! (%zu LiqTypes loaded)\n", liqTypeCount); + printf("Done! (%u LiqTypes loaded)\n", (uint32)liqTypeCount); } // -- cgit v1.2.3 From 69baba23cc81bef23278549c93576afc3195ece5 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 22 Jan 2013 19:30:52 +0100 Subject: Tools: Build fix, for real this time --- src/server/collision/Maps/MapTree.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index e3cd158709c..eb4b4555cb4 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -21,6 +21,7 @@ #include "VMapManager2.h" #include "VMapDefinitions.h" #include "Log.h" +#include "Errors.h" #include #include -- cgit v1.2.3 From bd893b4516292de4d2b1244acbecb0f301977e3f Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 18:41:26 +0000 Subject: Tools/MeshExtractor: Fix warnings --- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/MPQManager.h | 4 ++-- src/tools/mesh_extractor/WorldModelGroup.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 5ae8558d749..91b9c121c89 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -4,7 +4,7 @@ #include "Utils.h" #include -char* MPQManager::Files[] = { +char const* MPQManager::Files[] = { "common.MPQ", "common-2.MPQ", "expansion.MPQ", diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 788be7f5974..2f49ad258a5 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -24,8 +24,8 @@ public: std::set AvailableLocales; std::map LocaleFiles; - static char* Files[]; - static char* Languages[]; + static char const* Files[]; + static char const* Languages[]; protected: void InitializeDBC(); private: diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 5eeef824b1a..21e1c1e63e1 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -137,7 +137,7 @@ void WorldModelGroup::ReadBatches() MOBALength = chunk->Length / 2; MOBA = new uint16[MOBALength]; - int count = fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); + uint32 count = (uint32)fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); if (count != MOBALength) - printf("WorldModelGroup::ReadBatches: Error reading data, expected %d, read %d\n", MOBALength, count); + printf("WorldModelGroup::ReadBatches: Error reading data, expected %u, read %u\n", MOBALength, count); } -- cgit v1.2.3 From 7a76de93f83984a05bc38e321ca2f710cfd221d4 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 22 Jan 2013 20:24:00 +0100 Subject: Update more copyright note for 2013. --- dep/recastnavigation/Detour/CMakeLists.txt | 2 +- dep/recastnavigation/Recast/CMakeLists.txt | 2 +- src/tools/mmaps_generator/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/dep/recastnavigation/Detour/CMakeLists.txt b/dep/recastnavigation/Detour/CMakeLists.txt index c09e0e35d42..303a003dee2 100644 --- a/dep/recastnavigation/Detour/CMakeLists.txt +++ b/dep/recastnavigation/Detour/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2010 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/dep/recastnavigation/Recast/CMakeLists.txt b/dep/recastnavigation/Recast/CMakeLists.txt index 7ced79c10b7..726aff72c0c 100644 --- a/dep/recastnavigation/Recast/CMakeLists.txt +++ b/dep/recastnavigation/Recast/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2010 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 99492abf8ee..b168691c994 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2011 Trinity +# Copyright (C) 2008-2013 TrinityCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without -- cgit v1.2.3 From 6fc17c6b1e0dadc3429ffa67b753ac492ddbd7a1 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 19:34:04 +0000 Subject: Core: Fix compile warnings --- src/server/game/Miscellaneous/SharedDefines.h | 2 +- .../game/Movement/MovementGenerators/PointMovementGenerator.h | 2 +- .../game/Movement/MovementGenerators/TargetedMovementGenerator.h | 6 +++--- src/server/game/Movement/PathGenerator.cpp | 2 +- src/server/scripts/Commands/cs_mmaps.cpp | 4 ++-- src/tools/mmaps_generator/TerrainBuilder.cpp | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e5c4377d085..3d8ad37c92d 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3534,7 +3534,7 @@ enum PartyResult ERR_PARTY_LFG_TELEPORT_IN_COMBAT = 30 }; -#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' #define MMAP_VERSION 3 struct MmapTileHeader diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 89f643283d6..421736ca4ec 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -27,7 +27,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG { public: PointMovementGenerator(uint32 _id, float _x, float _y, float _z, bool _generatePath, float _speed = 0.0f) : id(_id), - i_x(_x), i_y(_y), i_z(_z), m_generatePath(_generatePath), speed(_speed), i_recalculateSpeed(false) {} + i_x(_x), i_y(_y), i_z(_z), speed(_speed), m_generatePath(_generatePath), i_recalculateSpeed(false) {} void DoInitialize(T*); void DoFinalize(T*); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 4f8cf658fde..3edeb348d54 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -39,8 +39,8 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, { protected: TargetedMovementGeneratorMedium(Unit* target, float offset, float angle) : - TargetedMovementGeneratorBase(target), i_recheckDistance(0), i_path(NULL), - i_offset(offset), i_angle(angle), + TargetedMovementGeneratorBase(target), i_path(NULL), + i_recheckDistance(0), i_offset(offset), i_angle(angle), i_recalculateTravel(false), i_targetReached(false) { } @@ -55,12 +55,12 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, protected: void _setTargetLocation(T* owner, bool updateDestination); + PathGenerator* i_path; TimeTrackerSmall i_recheckDistance; float i_offset; float i_angle; bool i_recalculateTravel : 1; bool i_targetReached : 1; - PathGenerator* i_path; }; template diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 71617f6a6ab..dbda4aa2411 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -30,7 +30,7 @@ PathGenerator::PathGenerator(const Unit* owner) : _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false), _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), - _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL), _endPosition(Vector3::zero()) + _endPosition(Vector3::zero()), _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL) { sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 4649e13e1c4..c4605e30991 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -98,7 +98,7 @@ public: PointsArray pointPath = path.GetPath(); handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); - handler->PSendSysMessage("Result: %s - Length: %i - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); + handler->PSendSysMessage("Result: %s - Length: "SIZEFMTD" - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); Vector3 start = path.GetStartPosition(); Vector3 end = path.GetEndPosition(); @@ -264,7 +264,7 @@ public: if (!creatureList.empty()) { - handler->PSendSysMessage("Found %i Creatures.", creatureList.size()); + handler->PSendSysMessage("Found "SIZEFTMD" Creatures.", creatureList.size()); uint32 paths = 0; uint32 uStartTime = getMSTime(); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index c3d6541dfa3..6f26a43fa05 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -296,7 +296,7 @@ namespace MMAP } // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" - if (liquid_type && liquid_map) + if (liquid_map) { int count = meshData.liquidVerts.size() / 3; float xoffset = (float(tileX)-32)*GRID_SIZE; @@ -393,7 +393,7 @@ namespace MMAP // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid - if (!liquid_type || !meshData.liquidVerts.size() || !ltriangles.size()) + if (!meshData.liquidVerts.size() || !ltriangles.size()) useLiquid = false; else { -- cgit v1.2.3 From 98e01fdb3f8278502a461e481323e62ed4523148 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 22 Jan 2013 21:00:08 +0100 Subject: Core: Fix build --- src/server/scripts/Commands/cs_mmaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index c4605e30991..97861133983 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -264,7 +264,7 @@ public: if (!creatureList.empty()) { - handler->PSendSysMessage("Found "SIZEFTMD" Creatures.", creatureList.size()); + handler->PSendSysMessage("Found "SIZEFMTD" Creatures.", creatureList.size()); uint32 paths = 0; uint32 uStartTime = getMSTime(); -- cgit v1.2.3 From 4f3c6b139031116fe5074e9340bc53139a98ab57 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 22 Jan 2013 20:47:52 +0000 Subject: Core: Yet another warning fix @Kaelima: could you verify MoveCharge? --- src/server/game/Movement/MotionMaster.cpp | 2 +- src/tools/mmaps_generator/TerrainBuilder.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index f792aa959fb..c9ca7772186 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -428,7 +428,7 @@ void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) { Vector3 dest = path.GetActualEndPosition(); - MoveCharge(dest.x, dest.y, dest.z); + MoveCharge(dest.x, dest.y, dest.z, speed, id); Movement::MoveSplineInit init(_owner); init.MovebyPath(path.GetPath()); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 6f26a43fa05..a42cd2b9bc6 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -295,7 +295,6 @@ namespace MMAP printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n"); } - // FIXME: "the address of ‘liquid_type’ will always evaluate as ‘true’" if (liquid_map) { int count = meshData.liquidVerts.size() / 3; @@ -369,7 +368,7 @@ namespace MMAP float* tverts = meshData.solidVerts.getCArray(); int* ttris = ttriangles.getCArray(); - if (ltriangles.size() + ttriangles.size() == 0) + if ((ltriangles.size() + ttriangles.size()) == 0) return false; // make a copy of liquid vertices -- cgit v1.2.3 From e360f8747002e858c0a85945ff1b1c1e3cba1fc3 Mon Sep 17 00:00:00 2001 From: Xanvial Date: Wed, 23 Jan 2013 05:26:51 +0700 Subject: Scripts/Paladin: Templar's Verdict --- .../2013_01_22_01_world_spell_script_names_434.sql | 4 ++ src/server/scripts/Spells/spell_paladin.cpp | 73 +++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 sql/updates/world/2013_01_22_01_world_spell_script_names_434.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_22_01_world_spell_script_names_434.sql b/sql/updates/world/2013_01_22_01_world_spell_script_names_434.sql new file mode 100644 index 00000000000..cc74d504e94 --- /dev/null +++ b/sql/updates/world/2013_01_22_01_world_spell_script_names_434.sql @@ -0,0 +1,4 @@ +-- 85256 - Templar's Verdict +DELETE FROM `spell_script_names` WHERE `spell_id`=85256; +INSERT INTO `spell_script_names` VALUES +(85256,'spell_pal_templar_s_verdict'); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 47592630a11..7625ed548ac 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -50,7 +50,9 @@ enum PaladinSpells SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988, SPELL_PALADIN_HAND_OF_SACRIFICE = 6940, - SPELL_PALADIN_DIVINE_SACRIFICE = 64205 + SPELL_PALADIN_DIVINE_SACRIFICE = 64205, + + SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174 }; // 31850 - Ardent Defender @@ -719,6 +721,74 @@ class spell_pal_sacred_shield : public SpellScriptLoader } }; +// 85256 - Templar's Verdict +/// Updated 4.3.4 +class spell_pal_templar_s_verdict : public SpellScriptLoader +{ + public: + spell_pal_templar_s_verdict() : SpellScriptLoader("spell_pal_templar_s_verdict") { } + + class spell_pal_templar_s_verdict_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pal_templar_s_verdict_SpellScript); + + bool Validate (SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_DIVINE_PURPOSE_PROC)) + return false; + + return true; + } + + bool Load() + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER) + return false; + + if (GetCaster()->ToPlayer()->getClass() != CLASS_PALADIN) + return false; + + return true; + } + + void ChangeDamage(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + int32 damage = GetHitDamage(); + + if (caster->HasAura(SPELL_PALADIN_DIVINE_PURPOSE_PROC)) + damage *= 7.5; // 7.5*30% = 225% + else + { + switch (caster->GetPower(POWER_HOLY_POWER)) + { + case 0: // 1 Holy Power + damage = damage; + break; + case 1: // 2 Holy Power + damage *= 3; // 3*30 = 90% + break; + case 2: // 3 Holy Power + damage *= 7.5; // 7.5*30% = 225% + break; + } + } + + SetHitDamage(damage); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_pal_templar_s_verdict_SpellScript::ChangeDamage, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pal_templar_s_verdict_SpellScript(); + } +}; + void AddSC_paladin_spell_scripts() { //new spell_pal_ardent_defender(); @@ -733,4 +803,5 @@ void AddSC_paladin_spell_scripts() new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); new spell_pal_sacred_shield(); + new spell_pal_templar_s_verdict(); } -- cgit v1.2.3 From af50ce6223ded9aa91a087556f2332b9c1f13df8 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Tue, 22 Jan 2013 00:20:16 +0100 Subject: Core/Spell: convert more spells to SpellScripts --- .../2013_01_23_00_world_spell_script_names.sql | 77 +++ src/server/game/Combat/ThreatManager.cpp | 19 +- src/server/game/Entities/Unit/Unit.cpp | 647 +-------------------- src/server/game/Entities/Unit/Unit.h | 42 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 28 - src/server/game/Spells/Auras/SpellAuras.cpp | 11 - src/server/game/Spells/SpellEffects.cpp | 2 +- .../IcecrownCitadel/boss_blood_queen_lana_thel.cpp | 38 ++ .../IcecrownCitadel/boss_the_lich_king.cpp | 37 ++ src/server/scripts/Spells/spell_dk.cpp | 54 ++ src/server/scripts/Spells/spell_druid.cpp | 75 +++ src/server/scripts/Spells/spell_generic.cpp | 180 ++++++ src/server/scripts/Spells/spell_hunter.cpp | 78 ++- src/server/scripts/Spells/spell_item.cpp | 351 ++++++++--- src/server/scripts/Spells/spell_mage.cpp | 197 +++++++ src/server/scripts/Spells/spell_paladin.cpp | 109 +++- src/server/scripts/Spells/spell_priest.cpp | 173 +++++- src/server/scripts/Spells/spell_rogue.cpp | 152 +++++ src/server/scripts/Spells/spell_shaman.cpp | 65 +++ src/server/scripts/Spells/spell_warlock.cpp | 97 +++ src/server/scripts/Spells/spell_warrior.cpp | 164 +++++- 21 files changed, 1795 insertions(+), 801 deletions(-) create mode 100644 sql/updates/world/2013_01_23_00_world_spell_script_names.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_23_00_world_spell_script_names.sql b/sql/updates/world/2013_01_23_00_world_spell_script_names.sql new file mode 100644 index 00000000000..dd8b35ae420 --- /dev/null +++ b/sql/updates/world/2013_01_23_00_world_spell_script_names.sql @@ -0,0 +1,77 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN ( +70871, -- spell_blood_queen_essence_of_the_blood_queen +69383, -- spell_the_lich_king_dark_hunger +50453, -- spell_dk_blood_gorged +-48496, -- spell_dru_living_seed +48504, -- spell_dru_living_seed_proc +28764, -- spell_gen_adaptive_warding +27539, -- spell_gen_obsidian_armor +34074, -- spell_hun_ascpect_of_the_viper +64411, -- spell_item_blessing_of_ancient_kings +71875, -- spell_item_necrotic_touch +71877, -- spell_item_necrotic_touch +71169, -- spell_item_shadows_fate +71903, -- spell_item_shadowmourne +71905, -- spell_item_shadowmourne_soul_fragment +-44449, -- spell_mage_burnout +54646, -- spell_mage_focus_magic +-11119, -- spell_mage_ignite +-29074, -- spell_mage_master_of_elements +-9799, -- spell_pal_eye_for_an_eye +20154, -- spell_pal_seal_of_righteousness +21084 -- spell_pal_seal_of_righteousness +-47509, -- spell_pri_divine_aegis +55680, -- spell_pri_glyph_of_prayer_of_healing +28305, -- spell_pri_mana_leech +13877, -- spell_rog_blade_flurry +33735, -- spell_rog_blade_flurry +51211, -- spell_rog_blade_flurry +65956, -- spell_rog_blade_flurry +57934, -- spell_rog_tricks_of_the_trade +59628, -- spell_rog_tricks_of_the_trade_proc +-974, -- spell_sha_earth_shield +-47230, -- spell_warl_fel_synergy +63108, -- spell_warl_siphon_life +-58872, -- spell_warr_damage_shield +12328, -- spell_warr_sweeping_strikes +18765, -- spell_warr_sweeping_strikes +35429 -- spell_warr_sweeping_strikes +); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(70871, 'spell_blood_queen_essence_of_the_blood_queen'), +(69383, 'spell_the_lich_king_dark_hunger'), +(50453, 'spell_dk_blood_gorged'), +(-48496, 'spell_dru_living_seed'), +(48504, 'spell_dru_living_seed_proc'), +(28764, 'spell_gen_adaptive_warding'), +(27539, 'spell_gen_obsidian_armor'), +(34074, 'spell_hun_ascpect_of_the_viper'), +(64411, 'spell_item_blessing_of_ancient_kings'), +(71875, 'spell_item_necrotic_touch'), +(71877, 'spell_item_necrotic_touch'), +(71169, 'spell_item_shadows_fate'), +(71903, 'spell_item_shadowmourne'), +(71905, 'spell_item_shadowmourne_soul_fragment'), +(-44449, 'spell_mage_burnout'), +(54646, 'spell_mage_focus_magic'), +(-11119, 'spell_mage_ignite'), +(-29074, 'spell_mage_master_of_elements'), +(-9799, 'spell_pal_eye_for_an_eye'), +(20154, 'spell_pal_seal_of_righteousness'), +(21084, 'spell_pal_seal_of_righteousness'), +(-47509, 'spell_pri_divine_aegis'), +(55680, 'spell_pri_glyph_of_prayer_of_healing'), +(28305, 'spell_pri_mana_leech'), +(13877, 'spell_rog_blade_flurry'), +(33735, 'spell_rog_blade_flurry'), +(51211, 'spell_rog_blade_flurry'), +(65956, 'spell_rog_blade_flurry'), +(57934, 'spell_rog_tricks_of_the_trade'), +(59628, 'spell_rog_tricks_of_the_trade_proc'), +(-974, 'spell_sha_earth_shield'), +(-47230, 'spell_warl_fel_synergy'), +(63108, 'spell_warl_siphon_life'), +(-58872, 'spell_warr_damage_shield'), +(12328, 'spell_warr_sweeping_strikes'), +(18765, 'spell_warr_sweeping_strikes'), +(35429, 'spell_warr_sweeping_strikes'); diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 6d291ca301f..249c1696348 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -416,20 +416,17 @@ void ThreatManager::addThreat(Unit* victim, float threat, SpellSchoolMask school void ThreatManager::doAddThreat(Unit* victim, float threat) { - uint32 reducedThreadPercent = victim->GetReducedThreatPercent(); + uint32 redirectThreadPct = victim->GetRedirectThreatPercent(); // must check > 0.0f, otherwise dead loop - if (threat > 0.0f && reducedThreadPercent) + if (threat > 0.0f && redirectThreadPct) { - Unit* redirectTarget = victim->GetMisdirectionTarget(); - if (redirectTarget) - if (Aura* glyphAura = redirectTarget->GetAura(63326)) // Glyph of Vigilance - reducedThreadPercent += glyphAura->GetSpellInfo()->Effects[0].CalcValue(); - - float reducedThreat = threat * reducedThreadPercent / 100.0f; - threat -= reducedThreat; - if (redirectTarget) - _addThreat(redirectTarget, reducedThreat); + if (Unit* redirectTarget = victim->GetRedirectThreatTarget()) + { + float redirectThreat = CalculatePct(threat, redirectThreadPct); + threat -= redirectThreat; + _addThreat(redirectTarget, redirectThreat); + } } _addThreat(victim, threat); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 49b86cff864..e7136a5c26f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -256,8 +256,8 @@ Unit::Unit(bool isWorldObject): WorldObject(isWorldObject) m_speed_rate[i] = 1.0f; m_charmInfo = NULL; - m_reducedThreatPercent = 0; - m_misdirectionTargetGUID = 0; + + _redirectThreadInfo = RedirectThreatInfo(); // remove aurastates allowing special moves for (uint8 i = 0; i < MAX_REACTIVE; ++i) @@ -4984,127 +4984,6 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType SendAttackStateUpdate(&dmgInfo); } -bool Unit::HandleHasteAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellInfo const* hasteSpell = triggeredByAura->GetSpellInfo(); - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = victim; - int32 basepoints0 = 0; - - switch (hasteSpell->SpellFamilyName) - { - case SPELLFAMILY_ROGUE: - { - switch (hasteSpell->Id) - { - // Blade Flurry - case 13877: - case 33735: - { - target = SelectNearbyTarget(victim); - if (!target) - return false; - basepoints0 = damage; - triggered_spell_id = 22482; - break; - } - } - break; - } - } - - // processed charge only counting case - if (!triggered_spell_id) - return true; - - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - - if (!triggerEntry) - { - sLog->outError(LOG_FILTER_UNITS, "Unit::HandleHasteAuraProc: Spell %u has non-existing triggered spell %u", hasteSpell->Id, triggered_spell_id); - return false; - } - - if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id)) - return false; - - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); - - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown); - - return true; -} - -bool Unit::HandleSpellCritChanceAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellInfo const* triggeredByAuraSpell = triggeredByAura->GetSpellInfo(); - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = victim; - int32 basepoints0 = 0; - - switch (triggeredByAuraSpell->SpellFamilyName) - { - case SPELLFAMILY_MAGE: - { - switch (triggeredByAuraSpell->Id) - { - // Focus Magic - case 54646: - { - Unit* caster = triggeredByAura->GetCaster(); - if (!caster) - return false; - - triggered_spell_id = 54648; - target = caster; - break; - } - } - } - } - - // processed charge only counting case - if (!triggered_spell_id) - return true; - - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - - if (!triggerEntry) - { - sLog->outError(LOG_FILTER_UNITS, "Unit::HandleHasteAuraProc: Spell %u has non-existing triggered spell %u", triggeredByAuraSpell->Id, triggered_spell_id); - return false; - } - - // default case - if (!target || (target != this && !target->isAlive())) - return false; - - if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id)) - return false; - - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); - - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown); - - return true; -} - //victim may be NULL bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) { @@ -5128,38 +5007,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere { switch (dummySpell->Id) { - // Bloodworms Health Leech - case 50453: - { - if (Unit* owner = GetOwner()) - { - basepoints0 = int32(damage * 1.50f); - target = owner; - triggered_spell_id = 50454; - break; - } - return false; - } - // Eye for an Eye - case 9799: - case 25988: - { - // return damage % to attacker but < 50% own total health - basepoints0 = int32(std::min(CalculatePct(damage, triggerAmount), CountPctFromMaxHealth(50))); - triggered_spell_id = 25997; - break; - } - // Sweeping Strikes - case 18765: - case 35429: - { - target = SelectNearbyTarget(victim); - if (!target) - return false; - - triggered_spell_id = 26654; - break; - } // Unstable Power case 24658: { @@ -5176,67 +5023,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere RemoveAuraFromStack(24662); return true; } - // Adaptive Warding (Frostfire Regalia set) - case 28764: - { - if (!procSpell) - return false; - - // find Mage Armor - if (!GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0, 0)) - return false; - - switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) - { - case SPELL_SCHOOL_NORMAL: - case SPELL_SCHOOL_HOLY: - return false; // ignored - case SPELL_SCHOOL_FIRE: triggered_spell_id = 28765; break; - case SPELL_SCHOOL_NATURE: triggered_spell_id = 28768; break; - case SPELL_SCHOOL_FROST: triggered_spell_id = 28766; break; - case SPELL_SCHOOL_SHADOW: triggered_spell_id = 28769; break; - case SPELL_SCHOOL_ARCANE: triggered_spell_id = 28770; break; - default: - return false; - } - - target = this; - break; - } - // Obsidian Armor (Justice Bearer`s Pauldrons shoulder) - case 27539: - { - if (!procSpell) - return false; - - switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: triggered_spell_id = 27536; break; - case SPELL_SCHOOL_FIRE: triggered_spell_id = 27533; break; - case SPELL_SCHOOL_NATURE: triggered_spell_id = 27538; break; - case SPELL_SCHOOL_FROST: triggered_spell_id = 27534; break; - case SPELL_SCHOOL_SHADOW: triggered_spell_id = 27535; break; - case SPELL_SCHOOL_ARCANE: triggered_spell_id = 27540; break; - default: - return false; - } - - target = this; - break; - } - // Mana Leech (Passive) (Priest Pet Aura) - case 28305: - { - // Cast on owner - target = GetOwner(); - if (!target) - return false; - - triggered_spell_id = 34650; - break; - } // Mark of Malice case 33493: { @@ -5427,14 +5213,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } return false; } - // Living Seed - case 48504: - { - triggered_spell_id = 48503; - basepoints0 = triggerAmount; - target = this; - break; - } // Kill command case 58914: { @@ -5594,50 +5372,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } - case 71875: // Item - Black Bruise: Necrotic Touch Proc - case 71877: - { - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 71879; - break; - } - // Item - Shadowmourne Legendary - case 71903: - { - if (!victim || !victim->isAlive() || HasAura(73422)) // cant collect shards while under effect of Chaos Bane buff - return false; - - CastSpell(this, 71905, true, NULL, triggeredByAura); - - // this can't be handled in AuraScript because we need to know victim - Aura const* dummy = GetAura(71905); - if (!dummy || dummy->GetStackAmount() < 10) - return false; - - RemoveAurasDueToSpell(71905); - triggered_spell_id = 71904; - target = victim; - break; - } - // Shadow's Fate (Shadowmourne questline) - case 71169: - { - Unit* caster = triggeredByAura->GetCaster(); - if (caster && caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->GetQuestStatus(24547) == QUEST_STATUS_INCOMPLETE) - { - CastSpell(caster, 71203, true); - return true; - } - else - return false; - } - // Essence of the Blood Queen - case 70871: - { - basepoints0 = CalculatePct(int32(damage), triggerAmount); - CastCustomSpell(70872, SPELLVALUE_BASE_POINT0, basepoints0, this); - return true; - } case 65032: // Boom aura (321 Boombot) { if (victim->GetEntry() != 33343) // Scrapbot @@ -5650,13 +5384,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere instance->DoCastSpellOnPlayers(65037); // Achievement criteria marker break; } - // Dark Hunger (The Lich King encounter) - case 69383: - { - basepoints0 = CalculatePct(int32(damage), 50); - triggered_spell_id = 69384; - break; - } } break; } @@ -5674,22 +5401,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere triggered_spell_id = 29442; break; } - // Master of Elements - if (dummySpell->SpellIconID == 1920) - { - if (!procSpell) - return false; - - // mana cost save - int32 cost = int32(procSpell->ManaCost + CalculatePct(GetCreateMana(), procSpell->ManaCostPercentage)); - basepoints0 = CalculatePct(cost, triggerAmount); - if (basepoints0 <= 0) - return false; - - target = this; - triggered_spell_id = 29077; - break; - } // Arcane Potency if (dummySpell->SpellIconID == 2120) { @@ -5707,7 +5418,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } - // Hot Streak if (dummySpell->SpellIconID == 2999) { @@ -5730,20 +5440,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere counter->SetAmount(25); return true; } - // Burnout - if (dummySpell->SpellIconID == 2998) - { - if (!procSpell) - return false; - - int32 cost = int32(procSpell->ManaCost + CalculatePct(GetCreateMana(), procSpell->ManaCostPercentage)); - basepoints0 = CalculatePct(cost, triggerAmount); - if (basepoints0 <= 0) - return false; - triggered_spell_id = 44450; - target = this; - break; - } // Incanter's Regalia set (add trigger chance to Mana Shield) if (dummySpell->SpellFamilyFlags[0] & 0x8000) { @@ -5773,29 +5469,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); return true; } - // Ignite - case 11119: - case 11120: - case 12846: - case 12847: - case 12848: - { - switch (dummySpell->Id) - { - case 11119: basepoints0 = int32(0.04f * damage); break; - case 11120: basepoints0 = int32(0.08f * damage); break; - case 12846: basepoints0 = int32(0.12f * damage); break; - case 12847: basepoints0 = int32(0.16f * damage); break; - case 12848: basepoints0 = int32(0.20f * damage); break; - default: - sLog->outError(LOG_FILTER_UNITS, "Unit::HandleDummyAuraProc: non handled spell id: %u (IG)", dummySpell->Id); - return false; - } - - triggered_spell_id = 12654; - basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE); - break; - } // Glyph of Ice Block case 56372: { @@ -5815,25 +5488,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } - // Blessing of Ancient Kings (Val'anyr, Hammer of Ancient Kings) - case 64411: - { - if (!victim) - return false; - basepoints0 = int32(CalculatePct(damage, 15)); - if (AuraEffect* aurEff = victim->GetAuraEffect(64413, 0, GetGUID())) - { - // The shield can grow to a maximum size of 20, 000 damage absorbtion - aurEff->SetAmount(std::min(aurEff->GetAmount() + basepoints0, 20000)); - - // Refresh and return to prevent replacing the aura - aurEff->GetBase()->RefreshDuration(); - return true; - } - target = victim; - triggered_spell_id = 64413; - break; - } case 47020: // Enter vehicle XT-002 (Scrapbot) { if (GetTypeId() != TYPEID_UNIT) @@ -5854,16 +5508,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere { switch (dummySpell->Id) { - // Sweeping Strikes - case 12328: - { - target = SelectNearbyTarget(victim); - if (!target) - return false; - - triggered_spell_id = 26654; - break; - } // Victorious case 32216: { @@ -5913,14 +5557,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere target = this; break; } - // Damage Shield - if (dummySpell->SpellIconID == 3214) - { - triggered_spell_id = 59653; - // % of amount blocked - basepoints0 = CalculatePct(int32(GetShieldBlockValue()), triggerAmount); - break; - } // Glyph of Blocking if (dummySpell->Id == 58375) { @@ -5991,31 +5627,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage); return true; } - // Fel Synergy - if (dummySpell->SpellIconID == 3222) - { - target = GetGuardianPet(); - if (!target) - return false; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - triggered_spell_id = 54181; - break; - } switch (dummySpell->Id) { - // Siphon Life - case 63108: - { - if (!damage) - break; - // Glyph of Siphon Life - if (HasAura(56216)) - triggerAmount += triggerAmount / 4; - triggered_spell_id = 63106; - target = this; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - break; - } // Glyph of Shadowflame case 63310: { @@ -6126,24 +5739,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere victim->CastSpell(victim, 57669, true, castItem, triggeredByAura); return true; // no hidden cooldown } - // Divine Aegis - if (dummySpell->SpellIconID == 2820) - { - if (!target) - return false; - - // Multiple effects stack, so let's try to find this aura. - int32 bonus = 0; - if (AuraEffect const* aurEff = target->GetAuraEffect(47753, 0)) - bonus = aurEff->GetAmount(); - - basepoints0 = CalculatePct(int32(damage), triggerAmount) + bonus; - if (basepoints0 > target->getLevel() * 125) - basepoints0 = target->getLevel() * 125; - - triggered_spell_id = 47753; - break; - } // Body and Soul if (dummySpell->SpellIconID == 2218) { @@ -6184,31 +5779,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere target = this; break; } - // Glyph of Prayer of Healing - case 55680: - { - triggered_spell_id = 56161; - - SpellInfo const* GoPoH = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!GoPoH) - return false; - - int EffIndex = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++) - { - if (GoPoH->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) - { - EffIndex = i; - break; - } - } - int32 tickcount = GoPoH->GetMaxDuration() / GoPoH->Effects[EffIndex].Amplitude; - if (!tickcount) - return false; - - basepoints0 = CalculatePct(int32(damage), triggerAmount) / tickcount; - break; - } // Improved Shadowform case 47570: case 47569: @@ -6481,13 +6051,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere triggered_spell_id = isWrathSpell ? 48518 : 48517; break; } - // Living Seed - else if (dummySpell->SpellIconID == 2860) - { - triggered_spell_id = 48504; - basepoints0 = CalculatePct(int32(damage), triggerAmount); - break; - } break; } case SPELLFAMILY_ROGUE: @@ -6508,16 +6071,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere triggered_spell_id = 32747; break; } - case 57934: // Tricks of the Trade - { - Unit* redirectTarget = GetMisdirectionTarget(); - RemoveAura(57934); - if (!redirectTarget) - break; - CastSpell(this, 59628, true); - CastSpell(redirectTarget, 57933, true); - break; - } } switch (dummySpell->SpellIconID) @@ -6636,14 +6189,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere switch (dummySpell->Id) { - case 34477: // Misdirection - { - if (!GetMisdirectionTarget()) - return false; - triggered_spell_id = 35079; // 4 sec buff on self - target = this; - break; - } case 57870: // Glyph of Mend Pet { victim->CastSpell(victim, 57894, true, NULL, NULL, GetGUID()); @@ -6654,18 +6199,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } case SPELLFAMILY_PALADIN: { - // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) - if (dummySpell->SpellFamilyFlags[0] & 0x8000000) - { - if (effIndex != 0) - return false; - triggered_spell_id = 25742; - float ap = GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY) + - victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); - basepoints0 = (int32)GetAttackTime(BASE_ATTACK) * int32(ap * 0.022f + 0.044f * holy) / 1000; - break; - } // Light's Beacon - Beacon of Light if (dummySpell->Id == 53651) { @@ -6832,20 +6365,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } - case 25899: // Greater Blessing of Sanctuary - case 20911: // Blessing of Sanctuary - { - target = this; - switch (target->getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 57319; - break; - default: - return false; - } - break; - } // Seal of Vengeance (damage calc on apply aura) case 31801: { @@ -7348,20 +6867,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere target = this; break; } - // Earth Shield - if (dummySpell->SpellFamilyFlags[1] & 0x00000400) - { - // 3.0.8: Now correctly uses the Shaman's own spell critical strike chance to determine the chance of a critical heal. - originalCaster = triggeredByAura->GetCasterGUID(); - target = this; - basepoints0 = triggerAmount; - - // Glyph of Earth Shield - if (AuraEffect* aur = GetAuraEffect(63279, 0)) - AddPct(basepoints0, aur->GetAmount()); - triggered_spell_id = 379; - break; - } // Flametongue Weapon (Passive) if (dummySpell->SpellFamilyFlags[0] & 0x200000) { @@ -7813,114 +7318,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere return true; } -bool Unit::HandleObsModEnergyAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); - //uint32 effIndex = triggeredByAura->GetEffIndex(); - //int32 triggerAmount = triggeredByAura->GetAmount(); - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = victim; - int32 basepoints0 = 0; - - switch (dummySpell->SpellFamilyName) - { - case SPELLFAMILY_HUNTER: - { - // Aspect of the Viper - if (dummySpell->SpellFamilyFlags[1] & 0x40000) - { - uint32 maxmana = GetMaxPower(POWER_MANA); - basepoints0 = CalculatePct(maxmana, GetAttackTime(RANGED_ATTACK) / 1000.0f); - target = this; - triggered_spell_id = 34075; - break; - } - break; - } - } - // processed charge only counting case - if (!triggered_spell_id) - return true; - - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - - // Try handle unknown trigger spells - if (!triggerEntry) - { - sLog->outError(LOG_FILTER_UNITS, "Unit::HandleObsModEnergyAuraProc: Spell %u has non-existing triggered spell %u", dummySpell->Id, triggered_spell_id); - return false; - } - - if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id)) - return false; - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); - - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown); - return true; -} -bool Unit::HandleModDamagePctTakenAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); - //uint32 effIndex = triggeredByAura->GetEffIndex(); - //int32 triggerAmount = triggeredByAura->GetAmount(); - - Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER - ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = victim; - int32 basepoints0 = 0; - - switch (dummySpell->SpellFamilyName) - { - case SPELLFAMILY_PALADIN: - { - // Blessing of Sanctuary - if (dummySpell->SpellFamilyFlags[0] & 0x10000000) - { - switch (getPowerType()) - { - case POWER_MANA: triggered_spell_id = 57319; break; - default: - return false; - } - } - break; - } - } - // processed charge only counting case - if (!triggered_spell_id) - return true; - - SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); - - if (!triggerEntry) - { - sLog->outError(LOG_FILTER_UNITS, "Unit::HandleModDamagePctTakenAuraProc: Spell %u has non-existing triggered spell %u", dummySpell->Id, triggered_spell_id); - return false; - } - - if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id)) - return false; - - if (basepoints0) - CastCustomSpell(target, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); - - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown); - - return true; -} // Used in case when access to whole aura is needed // All procs should be handled like this... @@ -8303,12 +7700,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg RemoveAuraFromStack(auraSpellInfo->Id); return false; } - if (auraSpellInfo->Id == 50720) - { - target = triggeredByAura->GetCaster(); - if (!target) - return false; - } break; case SPELLFAMILY_WARLOCK: { @@ -14536,7 +13927,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u SpellInfo const* spellInfo = i->aura->GetSpellInfo(); uint32 Id = i->aura->GetId(); - AuraApplication const* aurApp = i->aura->GetApplicationOfTarget(GetGUID()); + AuraApplication* aurApp = i->aura->GetApplicationOfTarget(GetGUID()); bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo); @@ -14589,17 +13980,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u case SPELL_AURA_PROC_TRIGGER_DAMAGE: { // target has to be valid - if (!target) + if (!eventInfo.GetProcTarget()) break; - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask); - uint32 newDamage = SpellDamageBonusDone(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE); - newDamage = target->SpellDamageBonusTaken(this, spellInfo, newDamage, SPELL_DIRECT_DAMAGE); - CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo); - DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); - SendSpellNonMeleeDamageLog(&damageInfo); - DealSpellDamage(&damageInfo, true); + triggeredByAura->HandleProcTriggerDamageAuraProc(aurApp, eventInfo); // this function is part of the new proc system takeCharges = true; break; } @@ -14612,22 +13996,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u break; } case SPELL_AURA_OBS_MOD_POWER: - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - takeCharges = true; - break; + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - takeCharges = true; - break; case SPELL_AURA_MOD_MELEE_HASTE: - { - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - takeCharges = true; + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId()); + takeCharges = true; break; - } case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: { sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); @@ -14699,11 +14073,6 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u if (triggeredByAura->GetCasterGUID() == target->GetGUID()) takeCharges = true; break; - case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - takeCharges = true; - break; // CC Auras which use their amount amount to drop // Are there any more auras which need this? case SPELL_AURA_MOD_CONFUSE: diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4bcc9c4b823..9b353d4cc02 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -965,6 +965,28 @@ struct SpellPeriodicAuraLogInfo uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition); +struct RedirectThreatInfo +{ + RedirectThreatInfo() : _targetGUID(0), _threatPct(0) { } + uint64 _targetGUID; + uint32 _threatPct; + + uint64 GetTargetGUID() { return _targetGUID; } + uint32 GetThreatPct() { return _threatPct; } + + void Set(uint64 guid, uint32 pct) + { + _targetGUID = guid; + _threatPct = pct; + } + + void ModifyThreatPct(int32 amount) + { + amount += _threatPct; + _threatPct = uint32(std::max(0, amount)); + } +}; + #define MAX_DECLINED_NAME_CASES 5 struct DeclinedName @@ -2153,13 +2175,12 @@ class Unit : public WorldObject uint32 GetModelForForm(ShapeshiftForm form) const; uint32 GetModelForTotem(PlayerTotemType totemType); - void SetReducedThreatPercent(uint32 pct, uint64 guid) - { - m_reducedThreatPercent = pct; - m_misdirectionTargetGUID = guid; - } - uint32 GetReducedThreatPercent() { return m_reducedThreatPercent; } - Unit* GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; } + // Redirect Threat + void SetRedirectThreat(uint64 guid, uint32 pct) { _redirectThreadInfo.Set(guid, pct); } + void ResetRedirectThreat() { SetRedirectThreat(0, 0); } + void ModifyRedirectThreat(int32 amount) { _redirectThreadInfo.ModifyThreatPct(amount); } + uint32 GetRedirectThreatPercent() { return _redirectThreadInfo.GetThreatPct(); } + Unit* GetRedirectThreatTarget() { return _redirectThreadInfo.GetTargetGUID() ? GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL; } bool IsAIEnabled, NeedChangeAI; bool CreateVehicleKit(uint32 id, uint32 creatureEntry); @@ -2305,10 +2326,6 @@ class Unit : public WorldObject private: bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const* & spellProcEvent); bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleHasteAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleSpellCritChanceAuraProc(Unit* victim, uint32 damage, AuraEffect* triggredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleObsModEnergyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleModDamagePctTakenAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled); bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown); @@ -2341,8 +2358,7 @@ class Unit : public WorldObject ComboPointHolderSet m_ComboPointHolders; - uint32 m_reducedThreatPercent; - uint64 m_misdirectionTargetGUID; + RedirectThreatInfo _redirectThreadInfo; bool m_cleanupDone; // lock made to not add stuff after cleanup before delete bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index d029d2884c9..9230c46db15 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -484,16 +484,6 @@ int32 AuraEffect::CalculateAmount(Unit* caster) case SPELL_AURA_MANA_SHIELD: m_canBeRecalculated = false; break; - case SPELL_AURA_DUMMY: - if (!caster) - break; - // Earth Shield - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[1] & 0x400) - { - amount = caster->SpellHealingBonusDone(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); - amount = GetBase()->GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); - } - break; default: break; } @@ -4694,10 +4684,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (Aura* newAura = target->AddAura(71564, target)) newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount); break; - case 59628: // Tricks of the Trade - if (caster && caster->GetMisdirectionTarget()) - target->SetReducedThreatPercent(100, caster->GetMisdirectionTarget()->GetGUID()); - break; } } // AT REMOVE @@ -4793,20 +4779,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (GetId() == 61777) target->CastSpell(target, GetAmount(), true); break; - case SPELLFAMILY_ROGUE: - // Tricks of the trade - switch (GetId()) - { - case 59628: //Tricks of the trade buff on rogue (6sec duration) - target->SetReducedThreatPercent(0, 0); - break; - case 57934: //Tricks of the trade buff on rogue (30sec duration) - if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE || !caster->GetMisdirectionTarget()) - target->SetReducedThreatPercent(0, 0); - else - target->SetReducedThreatPercent(0, caster->GetMisdirectionTarget()->GetGUID()); - break; - } default: break; } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index a41d25eae09..795908ce4b5 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1537,17 +1537,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b // mods at aura apply or remove switch (GetSpellInfo()->SpellFamilyName) { - case SPELLFAMILY_GENERIC: - switch (GetId()) - { - case 50720: // Vigilance - if (apply) - target->CastSpell(caster, 59665, true, 0, 0, caster->GetGUID()); - else - target->SetReducedThreatPercent(0, 0); - break; - } - break; case SPELLFAMILY_DRUID: // Enrage if ((GetSpellInfo()->SpellFamilyFlags[0] & 0x80000) && GetSpellInfo()->SpellIconID == 961) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 4fdf6654cba..bee770df748 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5791,7 +5791,7 @@ void Spell::EffectRedirectThreat(SpellEffIndex /*effIndex*/) return; if (unitTarget) - m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); + m_caster->SetRedirectThreat(unitTarget->GetGUID(), uint32(damage)); } void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index c8caa3976e4..5643d0ab732 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -46,6 +46,7 @@ enum Spells SPELL_FRENZIED_BLOODTHIRST_VISUAL = 71949, SPELL_VAMPIRIC_BITE = 71726, SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR = 70879, + SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL = 70872, SPELL_FRENZIED_BLOODTHIRST = 70877, SPELL_UNCONTROLLABLE_FRENZY = 70923, SPELL_PRESENCE_OF_THE_DARKFALLEN = 71952, @@ -698,6 +699,42 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader } }; +// 70871 - Essence of the Blood Queen +class spell_blood_queen_essence_of_the_blood_queen : public SpellScriptLoader +{ + public: + spell_blood_queen_essence_of_the_blood_queen() : SpellScriptLoader("spell_blood_queen_essence_of_the_blood_queen") { } + + class spell_blood_queen_essence_of_the_blood_queen_AuraScript : public AuraScript + { + PrepareAuraScript(spell_blood_queen_essence_of_the_blood_queen_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget()); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_blood_queen_essence_of_the_blood_queen_AuraScript::OnProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_blood_queen_essence_of_the_blood_queen_AuraScript(); + } +}; + class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader { public: @@ -849,6 +886,7 @@ void AddSC_boss_blood_queen_lana_thel() new spell_blood_queen_vampiric_bite(); new spell_blood_queen_frenzied_bloodthirst(); new spell_blood_queen_bloodbolt(); + new spell_blood_queen_essence_of_the_blood_queen(); new spell_blood_queen_pact_of_the_darkfallen(); new spell_blood_queen_pact_of_the_darkfallen_dmg(); new spell_blood_queen_pact_of_the_darkfallen_dmg_target(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 452d09cf65f..3bd313fa148 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -145,6 +145,7 @@ enum Spells SPELL_RESTORE_SOUL = 72595, SPELL_RESTORE_SOULS = 73650, // Heroic SPELL_DARK_HUNGER = 69383, // Passive proc healing + SPELL_DARK_HUNGER_HEAL = 69384, SPELL_DESTROY_SOUL = 74086, // Used when Terenas Menethil dies SPELL_SOUL_RIP = 69397, // Deals increasing damage SPELL_SOUL_RIP_DAMAGE = 69398, @@ -3008,6 +3009,41 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader } }; +class spell_the_lich_king_dark_hunger : public SpellScriptLoader +{ + public: + spell_the_lich_king_dark_hunger() : SpellScriptLoader("spell_the_lich_king_dark_hunger") { } + + class spell_the_lich_king_dark_hunger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_dark_hunger_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DARK_HUNGER_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 heal = int32(eventInfo.GetDamageInfo()->GetDamage() / 2); + GetTarget()->CastCustomSpell(SPELL_DARK_HUNGER_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_the_lich_king_dark_hunger_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_dark_hunger_AuraScript(); + } +}; + class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader { public: @@ -3253,6 +3289,7 @@ void AddSC_boss_the_lich_king() new spell_the_lich_king_lights_favor(); new spell_the_lich_king_soul_rip(); new spell_the_lich_king_restore_soul(); + new spell_the_lich_king_dark_hunger(); new spell_the_lich_king_in_frostmourne_room(); new spell_the_lich_king_summon_spirit_bomb(); new spell_the_lich_king_trigger_vile_spirit(); diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 62a0599dab1..73c34d42538 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -31,6 +31,7 @@ enum DeathKnightSpells SPELL_DK_ANTI_MAGIC_SHELL_TALENT = 51052, SPELL_DK_BLACK_ICE_R1 = 49140, SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658, + SPELL_DK_BLOOD_GORGED_HEAL = 50454, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED = 43999, SPELL_DK_CORPSE_EXPLOSION_VISUAL = 51270, SPELL_DK_DEATH_COIL_DAMAGE = 47632, @@ -252,6 +253,58 @@ class spell_dk_blood_boil : public SpellScriptLoader } }; +// 50453 - Bloodworms Health Leech +class spell_dk_blood_gorged : public SpellScriptLoader +{ + public: + spell_dk_blood_gorged() : SpellScriptLoader("spell_dk_blood_gorged") { } + + class spell_dk_blood_gorged_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_blood_gorged_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_GORGED_HEAL)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetTarget()->GetOwner(); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 1.5f); + GetTarget()->CastCustomSpell(SPELL_DK_BLOOD_GORGED_HEAL, SPELLVALUE_BASE_POINT0, bp, _procTarget, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_dk_blood_gorged_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dk_blood_gorged_AuraScript(); + } +}; + // 49158 - Corpse Explosion (51325, 51326, 51327, 51328) class spell_dk_corpse_explosion : public SpellScriptLoader { @@ -958,6 +1011,7 @@ void AddSC_deathknight_spell_scripts() new spell_dk_anti_magic_shell_self(); new spell_dk_anti_magic_zone(); new spell_dk_blood_boil(); + new spell_dk_blood_gorged(); new spell_dk_corpse_explosion(); new spell_dk_death_coil(); new spell_dk_death_gate(); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index e2b918e1c7f..160f14ff670 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -37,6 +37,8 @@ enum DruidSpells SPELL_DRUID_KING_OF_THE_JUNGLE = 48492, SPELL_DRUID_LIFEBLOOM_ENERGIZE = 64372, SPELL_DRUID_LIFEBLOOM_FINAL_HEAL = 33778, + SPELL_DRUID_LIVING_SEED_HEAL = 48503, + SPELL_DRUID_LIVING_SEED_PROC = 48504, SPELL_DRUID_NATURES_SPLENDOR = 57865, SPELL_DRUID_SURVIVAL_INSTINCTS = 50322, SPELL_DRUID_SAVAGE_ROAR = 62071, @@ -327,6 +329,77 @@ class spell_dru_lifebloom : public SpellScriptLoader } }; +// -48496 - Living Seed +class spell_dru_living_seed : public SpellScriptLoader +{ + public: + spell_dru_living_seed() : SpellScriptLoader("spell_dru_living_seed") { } + + class spell_dru_living_seed_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_living_seed_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_LIVING_SEED_PROC)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 amount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_DRUID_LIVING_SEED_PROC, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_dru_living_seed_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_living_seed_AuraScript(); + } +}; + +// 48504 - Living Seed (Proc) +class spell_dru_living_seed_proc : public SpellScriptLoader +{ + public: + spell_dru_living_seed_proc() : SpellScriptLoader("spell_dru_living_seed_proc") { } + + class spell_dru_living_seed_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_living_seed_proc_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_LIVING_SEED_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastCustomSpell(SPELL_DRUID_LIVING_SEED_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_dru_living_seed_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_living_seed_proc_AuraScript(); + } +}; + // 69366 - Moonkin Form passive class spell_dru_moonkin_form_passive : public SpellScriptLoader { @@ -921,6 +994,8 @@ void AddSC_druid_spell_scripts() new spell_dru_innervate(); new spell_dru_insect_swarm(); new spell_dru_lifebloom(); + new spell_dru_living_seed(); + new spell_dru_living_seed_proc(); new spell_dru_moonkin_form_passive(); new spell_dru_owlkin_frenzy(); new spell_dru_predatory_strikes(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 6004ec6cf89..05fad623114 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -72,6 +72,97 @@ class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader } }; +// 28764 - Adaptive Warding (Frostfire Regalia Set) +enum AdaptiveWarding +{ + SPELL_GEN_ADAPTIVE_WARDING_FIRE = 28765, + SPELL_GEN_ADAPTIVE_WARDING_NATURE = 28768, + SPELL_GEN_ADAPTIVE_WARDING_FROST = 28766, + SPELL_GEN_ADAPTIVE_WARDING_SHADOW = 28769, + SPELL_GEN_ADAPTIVE_WARDING_ARCANE = 28770 +}; + +class spell_gen_adaptive_warding : public SpellScriptLoader +{ + public: + spell_gen_adaptive_warding() : SpellScriptLoader("spell_gen_adaptive_warding") { } + + class spell_gen_adaptive_warding_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_adaptive_warding_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_NATURE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_ARCANE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo() + return false; + + // find Mage Armor + if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0)) + return false; + + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_NORMAL: + case SPELL_SCHOOL_HOLY: + return false; + default: + break; + } + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_adaptive_warding_AuraScript(); + } +}; + // 41337 Aura of Anger class spell_gen_aura_of_anger : public SpellScriptLoader { @@ -378,6 +469,93 @@ class spell_gen_nightmare_vine : public SpellScriptLoader } }; +// 27539 - Obsidian Armor +enum ObsidianArmor +{ + SPELL_GEN_OBSIDIAN_ARMOR_HOLY = 27536, + SPELL_GEN_OBSIDIAN_ARMOR_FIRE = 27533, + SPELL_GEN_OBSIDIAN_ARMOR_NATURE = 27538, + SPELL_GEN_OBSIDIAN_ARMOR_FROST = 27534, + SPELL_GEN_OBSIDIAN_ARMOR_SHADOW = 27535, + SPELL_GEN_OBSIDIAN_ARMOR_ARCANE = 27540 +}; + +class spell_gen_obsidian_armor : public SpellScriptLoader +{ + public: + spell_gen_obsidian_armor() : SpellScriptLoader("spell_gen_obsidian_armor") { } + + class spell_gen_obsidian_armor_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_obsidian_armor_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_HOLY) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_FIRE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_NATURE) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_FROST) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_SHADOW) || + !sSpellMgr->GetSpellInfo(SPELL_GEN_OBSIDIAN_ARMOR_ARCANE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo() + return false; + + if (GetFirstSchoolInMask(eventInfo.GetSchoolMask()) == SPELL_SCHOOL_NORMAL) + return false; + + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + uint32 spellId = 0; + switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask())) + { + case SPELL_SCHOOL_HOLY: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_HOLY; + break; + case SPELL_SCHOOL_FIRE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FIRE; + break; + case SPELL_SCHOOL_NATURE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_NATURE; + break; + case SPELL_SCHOOL_FROST: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_FROST; + break; + case SPELL_SCHOOL_SHADOW: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_SHADOW; + break; + case SPELL_SCHOOL_ARCANE: + spellId = SPELL_GEN_OBSIDIAN_ARMOR_ARCANE; + break; + default: + return; + } + GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_gen_obsidian_armor_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_gen_obsidian_armor_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_obsidian_armor_AuraScript(); + } +}; + // 45472 Parachute enum ParachuteSpells { @@ -3343,6 +3521,7 @@ class spell_gen_replenishment : public SpellScriptLoader void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); + new spell_gen_adaptive_warding(); new spell_gen_aura_of_anger(); new spell_gen_av_drekthar_presence(); new spell_gen_burn_brutallus(); @@ -3350,6 +3529,7 @@ void AddSC_generic_spell_scripts() new spell_gen_create_lance(); new spell_gen_netherbloom(); new spell_gen_nightmare_vine(); + new spell_gen_obsidian_armor(); new spell_gen_parachute(); new spell_gen_pet_summoned(); new spell_gen_remove_flight_auras(); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index a9b21807899..877248cf1a8 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -33,12 +33,15 @@ enum HunterSpells { SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, + SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE = 34075, SPELL_HUNTER_BESTIAL_WRATH = 19574, SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359, + SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER = 56851, SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398, SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, + SPELL_HUNTER_MISDIRECTION_PROC = 35079, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX = 55709, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, @@ -99,6 +102,50 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader } }; +// 34074 - Aspect of the Viper +class spell_hun_ascpect_of_the_viper : public SpellScriptLoader +{ + public: + spell_hun_ascpect_of_the_viper() : SpellScriptLoader("spell_hun_ascpect_of_the_viper") { } + + class spell_hun_ascpect_of_the_viper_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_ascpect_of_the_viper_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + uint32 maxMana = GetTarget()->GetMaxPower(POWER_MANA); + int32 mana = CalculatePct(maxMana, GetTarget()->GetAttackTime(RANGED_ATTACK) / 1000.0f); + + if (AuraEffect const* glyphe = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER, EFFECT_0)) + AddPct(mana, glyphe->GetAmount()); + + GetTarget()->CastCustomSpell(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_hun_ascpect_of_the_viper_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_OBS_MOD_POWER); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_hun_ascpect_of_the_viper_AuraScript(); + } +}; + // 53209 - Chimera Shot class spell_hun_chimera_shot : public SpellScriptLoader { @@ -358,16 +405,35 @@ class spell_hun_misdirection : public SpellScriptLoader { PrepareAuraScript(spell_hun_misdirection_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MISDIRECTION_PROC)) + return false; + return true; + } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Unit* caster = GetCaster()) - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) - caster->SetReducedThreatPercent(0, 0); + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + GetTarget()->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->GetRedirectThreatTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_MISDIRECTION_PROC, true, NULL, aurEff); } void Register() { AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + DoCheckProc += AuraCheckProcFn(spell_hun_misdirection_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_hun_misdirection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); } }; @@ -377,7 +443,7 @@ class spell_hun_misdirection : public SpellScriptLoader } }; -// 35079 - Misdirection proc +// 35079 - Misdirection (Proc) class spell_hun_misdirection_proc : public SpellScriptLoader { public: @@ -389,8 +455,7 @@ class spell_hun_misdirection_proc : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (GetCaster()) - GetCaster()->SetReducedThreatPercent(0, 0); + GetTarget()->ResetRedirectThreat(); } void Register() @@ -740,6 +805,7 @@ class spell_hun_target_only_pet_and_owner : public SpellScriptLoader void AddSC_hunter_spell_scripts() { new spell_hun_aspect_of_the_beast(); + new spell_hun_ascpect_of_the_viper(); new spell_hun_chimera_shot(); new spell_hun_disengage(); new spell_hun_invigoration(); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index c38d05bc02a..b8e17f4ecca 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -102,6 +102,63 @@ class spell_item_arcane_shroud : public SpellScriptLoader } }; +// 64411 - Blessing of Ancient Kings (Val'anyr, Hammer of Ancient Kings) +enum BlessingOfAncientKings +{ + SPELL_PROTECTION_OF_ANCIENT_KINGS = 64413 +}; + +class spell_item_blessing_of_ancient_kings : public SpellScriptLoader +{ + public: + spell_item_blessing_of_ancient_kings() : SpellScriptLoader("spell_item_blessing_of_ancient_kings") { } + + class spell_item_blessing_of_ancient_kings_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_blessing_of_ancient_kings_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PROTECTION_OF_ANCIENT_KINGS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 absorb = int32(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 15.0f)); + if (AuraEffect* protEff = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PROTECTION_OF_ANCIENT_KINGS, 0, eventInfo.GetActor()->GetGUID())) + { + // The shield can grow to a maximum size of 20,000 damage absorbtion + protEff->SetAmount(std::min(protEff->GetAmount() + absorb, 20000)); + + // Refresh and return to prevent replacing the aura + aurEff->GetBase()->RefreshDuration(); + } + else + GetTarget()->CastCustomSpell(SPELL_PROTECTION_OF_ANCIENT_KINGS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_blessing_of_ancient_kings_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_blessing_of_ancient_kings_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_blessing_of_ancient_kings_AuraScript(); + } +}; + // 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success // 22999 - Defibrillate (Goblin Jumper Cables XL) have 50% chance on success // 54732 - Defibrillate (Gnomish Army Knife) have 67% chance on success @@ -444,6 +501,47 @@ class spell_item_mingos_fortune_generator : public SpellScriptLoader } }; +// 71875, 71877 - Item - Black Bruise: Necrotic Touch Proc +enum NecroticTouch +{ + SPELL_ITEM_NECROTIC_TOUCH_PROC = 71879 +}; + +class spell_item_necrotic_touch : public SpellScriptLoader +{ + public: + spell_item_necrotic_touch() : SpellScriptLoader("spell_item_necrotic_touch") { } + + class spell_item_necrotic_touch_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_necrotic_touch_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ITEM_NECROTIC_TOUCH_PROC)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + int32 bp = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_ITEM_NECROTIC_TOUCH_PROC, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_item_necrotic_touch_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_necrotic_touch_AuraScript(); + } +}; + // http://www.wowhead.com/item=10720 Gnomish Net-o-Matic Projector // 13120 Net-o-Matic enum NetOMaticSpells @@ -711,6 +809,189 @@ class spell_item_scroll_of_recall : public SpellScriptLoader } }; +// 71169 - Shadow's Fate (Shadowmourne questline) +enum ShadowsFate +{ + SPELL_SOUL_FEAST = 71203, + QUEST_A_FEAST_OF_SOULS = 24547 +}; + +class spell_item_shadows_fate : public SpellScriptLoader +{ + public: + spell_item_shadows_fate() : SpellScriptLoader("spell_item_shadows_fate") { } + + class spell_item_shadows_fate_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadows_fate_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_FEAST)) + return false; + if (!sObjectMgr->GetQuestTemplate(QUEST_A_FEAST_OF_SOULS)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget && _procTarget->GetTypeId() == TYPEID_PLAYER && _procTarget->ToPlayer()->GetQuestStatus(QUEST_A_FEAST_OF_SOULS) == QUEST_STATUS_INCOMPLETE; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_SOUL_FEAST, true); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_shadows_fate_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_shadows_fate_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadows_fate_AuraScript(); + } +}; + +enum Shadowmourne +{ + SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE = 71904, + SPELL_SHADOWMOURNE_SOUL_FRAGMENT = 71905, + SPELL_SHADOWMOURNE_VISUAL_LOW = 72521, + SPELL_SHADOWMOURNE_VISUAL_HIGH = 72523, + SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF = 73422, +}; + +// 71903 - Item - Shadowmourne Legendary +class spell_item_shadowmourne : public SpellScriptLoader +{ + public: + spell_item_shadowmourne() : SpellScriptLoader("spell_item_shadowmourne") { } + + class spell_item_shadowmourne_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadowmourne_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + if (GetTarget()->HasAura(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) // cant collect shards while under effect of Chaos Bane buff + return false; + return eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->isAlive(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_SHADOWMOURNE_SOUL_FRAGMENT, true, NULL, aurEff); + + // this can't be handled in AuraScript of SoulFragments because we need to know victim + if (Aura* soulFragments = GetTarget()->GetAura(SPELL_SHADOWMOURNE_SOUL_FRAGMENT)) + { + if (soulFragments->GetStackAmount() >= 10) + { + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, true, NULL, aurEff); + soulFragments->Remove(); + } + } + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_item_shadowmourne_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_item_shadowmourne_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadowmourne_AuraScript(); + } +}; + +// 71905 - Soul Fragment +class spell_item_shadowmourne_soul_fragment : public SpellScriptLoader +{ + public: + spell_item_shadowmourne_soul_fragment() : SpellScriptLoader("spell_item_shadowmourne_soul_fragment") { } + + class spell_item_shadowmourne_soul_fragment_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_shadowmourne_soul_fragment_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_LOW) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_HIGH) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) + return false; + return true; + } + + void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + switch (GetStackAmount()) + { + case 1: + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); + break; + case 6: + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); + break; + case 10: + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); + target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); + break; + default: + break; + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); + target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); + AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_soul_fragment_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_item_shadowmourne_soul_fragment_AuraScript(); + } +}; + // http://www.wowhead.com/item=7734 Six Demon Bag // 14537 Six Demon Bag enum SixDemonBagSpells @@ -864,70 +1145,6 @@ class spell_item_underbelly_elixir : public SpellScriptLoader } }; -enum eShadowmourneVisuals -{ - SPELL_SHADOWMOURNE_VISUAL_LOW = 72521, - SPELL_SHADOWMOURNE_VISUAL_HIGH = 72523, - SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF = 73422, -}; - -class spell_item_shadowmourne : public SpellScriptLoader -{ -public: - spell_item_shadowmourne() : SpellScriptLoader("spell_item_shadowmourne") { } - - class spell_item_shadowmourne_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_shadowmourne_AuraScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_LOW) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_VISUAL_HIGH) || !sSpellMgr->GetSpellInfo(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF)) - return false; - return true; - } - - void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - switch (GetStackAmount()) - { - case 1: - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true); - break; - case 6: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); - target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true); - break; - case 10: - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF, true); - break; - default: - break; - } - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); - target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); - } - - void Register() - { - AfterEffectApply += AuraEffectApplyFn(spell_item_shadowmourne_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AuraEffectHandleModes(AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)); - AfterEffectRemove += AuraEffectRemoveFn(spell_item_shadowmourne_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_item_shadowmourne_AuraScript(); - } -}; - enum AirRifleSpells { SPELL_AIR_RIFLE_HOLD_VISUAL = 65582, @@ -2249,6 +2466,7 @@ void AddSC_item_spell_scripts() new spell_item_trigger_spell("spell_item_mithril_mechanical_dragonling", SPELL_MITHRIL_MECHANICAL_DRAGONLING); new spell_item_arcane_shroud(); + new spell_item_blessing_of_ancient_kings(); new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); @@ -2257,15 +2475,18 @@ void AddSC_item_spell_scripts() new spell_item_gnomish_death_ray(); new spell_item_make_a_wish(); new spell_item_mingos_fortune_generator(); + new spell_item_necrotic_touch(); new spell_item_net_o_matic(); new spell_item_noggenfogger_elixir(); new spell_item_piccolo_of_the_flaming_fire(); new spell_item_savory_deviate_delight(); new spell_item_scroll_of_recall(); + new spell_item_shadows_fate(); + new spell_item_shadowmourne(); + new spell_item_shadowmourne_soul_fragment(); new spell_item_six_demon_bag(); new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); - new spell_item_shadowmourne(); new spell_item_red_rider_air_rifle(); new spell_item_create_heart_candy(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index a673759a49e..ca835c61a3a 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -28,11 +28,15 @@ enum MageSpells { + SPELL_MAGE_BURNOUT = 29077, SPELL_MAGE_COLD_SNAP = 11958, + SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, SPELL_MAGE_FROST_WARDING_R1 = 11189, SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, SPELL_MAGE_INCANTERS_ABSORBTION_R1 = 44394, SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED = 44413, + SPELL_MAGE_IGNITE = 12654, + SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE = 29077, SPELL_MAGE_SQUIRREL_FORM = 32813, SPELL_MAGE_GIRAFFE_FORM = 32816, SPELL_MAGE_SERPENT_FORM = 32817, @@ -105,6 +109,51 @@ class spell_mage_blast_wave : public SpellScriptLoader } }; +// -44449 - Burnout +class spell_mage_burnout : public SpellScriptLoader +{ + public: + spell_mage_burnout() : SpellScriptLoader("spell_mage_burnout") { } + + class spell_mage_burnout_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_burnout_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BURNOUT)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo() + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask())); + mana = CalculatePct(mana, aurEff->GetAmount()); + + GetTarget()->CastCustomSpell(SPELL_MAGE_BURNOUT, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_burnout_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_burnout_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_burnout_AuraScript(); + } +}; + // 11958 - Cold Snap class spell_mage_cold_snap : public SpellScriptLoader { @@ -219,6 +268,57 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader } }; +// 54646 - Focus Magic +class spell_mage_focus_magic : public SpellScriptLoader +{ + public: + spell_mage_focus_magic() : SpellScriptLoader("spell_mage_focus_magic") { } + + class spell_mage_focus_magic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_focus_magic_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FOCUS_MAGIC_PROC)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget && _procTarget->isAlive(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_MAGE_FOCUS_MAGIC_PROC, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_focus_magic_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_focus_magic_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_focus_magic_AuraScript(); + } +}; + // -11426 - Ice Barrier class spell_mage_ice_barrier : public SpellScriptLoader { @@ -262,6 +362,53 @@ class spell_mage_ice_barrier : public SpellScriptLoader } }; +// -11119 - Ignite +class spell_mage_ignite : public SpellScriptLoader +{ + public: + spell_mage_ignite() : SpellScriptLoader("spell_mage_ignite") { } + + class spell_mage_ignite_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_ignite_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* igniteDot = sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE); + int32 pct = 8 * GetSpellInfo()->GetRank(); + + int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks()); + amount += eventInfo.GetProcTarget()->GetRemainingPeriodicAmount(eventInfo.GetActor()->GetGUID(), SPELL_MAGE_IGNITE, SPELL_AURA_PERIODIC_DAMAGE); + GetTarget()->CastCustomSpell(SPELL_MAGE_IGNITE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_ignite_AuraScript(); + } +}; + // -44457 - Living Bomb class spell_mage_living_bomb : public SpellScriptLoader { @@ -339,6 +486,52 @@ class spell_mage_mana_shield : public SpellScriptLoader } }; +// -29074 - Master of Elements +class spell_mage_master_of_elements : public SpellScriptLoader +{ + public: + spell_mage_master_of_elements() : SpellScriptLoader("spell_mage_master_of_elements") { } + + class spell_mage_master_of_elements_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_master_of_elements_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo() + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask())); + mana = CalculatePct(mana, aurEff->GetAmount()); + + if (mana > 0) + GetTarget()->CastCustomSpell(SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_mage_master_of_elements_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_mage_master_of_elements_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mage_master_of_elements_AuraScript(); + } +}; + enum SilvermoonPolymorph { NPC_AUROSALIA = 18744, @@ -437,11 +630,15 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader void AddSC_mage_spell_scripts() { new spell_mage_blast_wave(); + new spell_mage_burnout(); new spell_mage_cold_snap(); new spell_mage_fire_frost_ward(); + new spell_mage_focus_magic(); new spell_mage_ice_barrier(); + new spell_mage_ignite(); new spell_mage_living_bomb(); new spell_mage_mana_shield(); + new spell_mage_master_of_elements(); new spell_mage_polymorph_cast_visual(); new spell_mage_summon_water_elemental(); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 2f22de97d77..6be2453affb 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -31,6 +31,7 @@ enum PaladinSpells { SPELL_PALADIN_DIVINE_PLEA = 54428, SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF = 67480, + SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE = 57319, SPELL_PALADIN_HOLY_SHOCK_R1 = 20473, SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912, @@ -45,6 +46,8 @@ enum PaladinSpells SPELL_PALADIN_DIVINE_STORM_DUMMY = 54171, SPELL_PALADIN_DIVINE_STORM_HEAL = 54172, + SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE = 25997, + SPELL_PALADIN_FORBEARANCE = 25771, SPELL_PALADIN_AVENGING_WRATH_MARKER = 61987, SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988, @@ -56,6 +59,8 @@ enum PaladinSpells SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, + SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742, + SPELL_GENERIC_ARENA_DAMPENING = 74410, SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411 }; @@ -192,8 +197,8 @@ class spell_pal_blessing_of_faith : public SpellScriptLoader } }; -// 20911 Blessing of Sanctuary -// 25899 Greater Blessing of Sanctuary +// 20911 - Blessing of Sanctuary +// 25899 - Greater Blessing of Sanctuary class spell_pal_blessing_of_sanctuary : public SpellScriptLoader { public: @@ -207,6 +212,8 @@ class spell_pal_blessing_of_sanctuary : public SpellScriptLoader { if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF)) return false; + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE)) + return false; return true; } @@ -223,10 +230,23 @@ class spell_pal_blessing_of_sanctuary : public SpellScriptLoader target->RemoveAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, GetCasterGUID()); } + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + return GetTarget()->getPowerType() == POWER_MANA; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE, true, NULL, aurEff); + } + void Register() { AfterEffectApply += AuraEffectApplyFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); AfterEffectRemove += AuraEffectRemoveFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + DoCheckProc += AuraCheckProcFn(spell_pal_blessing_of_sanctuary_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -417,6 +437,43 @@ class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader } }; +// -9799 - Eye for an Eye +class spell_pal_eye_for_an_eye : public SpellScriptLoader +{ + public: + spell_pal_eye_for_an_eye() : SpellScriptLoader("spell_pal_eye_for_an_eye") { } + + class spell_pal_eye_for_an_eye_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_eye_for_an_eye_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + // return damage % to attacker but < 50% own total health + int32 damage = int32(std::min(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), GetTarget()->GetMaxHealth() / 2)); + GetTarget()->CastCustomSpell(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_eye_for_an_eye_AuraScript(); + } +}; + // 63521 - Guarded by The Light class spell_pal_guarded_by_the_light : public SpellScriptLoader { @@ -794,6 +851,52 @@ class spell_pal_sacred_shield : public SpellScriptLoader } }; +// 20154, 21084 - Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) +class spell_pal_seal_of_righteousness : public SpellScriptLoader +{ + public: + spell_pal_seal_of_righteousness() : SpellScriptLoader("spell_pal_seal_of_righteousness") { } + + class spell_pal_seal_of_righteousness_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_seal_of_righteousness_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + float ap = GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK); + int32 holy = GetTarget()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); + holy += eventInfo.GetProcTarget()->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); + int32 bp = int32((ap * 0.022f + 0.044f * holy) * GetTarget()->GetAttackTime(BASE_ATTACK) / 1000); + GetTarget()->CastCustomSpell(SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pal_seal_of_righteousness_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_righteousness_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_seal_of_righteousness_AuraScript(); + } +}; + void AddSC_paladin_spell_scripts() { new spell_pal_ardent_defender(); @@ -803,6 +906,7 @@ void AddSC_paladin_spell_scripts() new spell_pal_divine_storm(); new spell_pal_divine_storm_dummy(); new spell_pal_exorcism_and_holy_wrath_damage(); + new spell_pal_eye_for_an_eye(); new spell_pal_guarded_by_the_light(); new spell_pal_hand_of_sacrifice(); new spell_pal_hand_of_salvation(); @@ -811,4 +915,5 @@ void AddSC_paladin_spell_scripts() new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); new spell_pal_sacred_shield(); + new spell_pal_seal_of_righteousness(); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 23a39819aa2..e19110d0f62 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -29,24 +29,115 @@ enum PriestSpells { - SPELL_PRIEST_EMPOWERED_RENEW = 63544, - SPELL_PRIEST_GLYPHE_OF_LIGHTWELL = 55673, - SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, - SPELL_PRIEST_PENANCE_R1 = 47540, - SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, - SPELL_PRIEST_PENANCE_R1_HEAL = 47757, - SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619, - SPELL_PRIEST_REFLECTIVE_SHIELD_R1 = 33201, - SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, - SPELL_PRIEST_T9_HEALING_2P = 67201, - SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, + SPELL_PRIEST_DIVINE_AEGIS = 47753, + SPELL_PRIEST_EMPOWERED_RENEW = 63544, + SPELL_PRIEST_GLYPHE_OF_LIGHTWELL = 55673, + SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL = 56161, + SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, + SPELL_PRIEST_MANA_LEECH_PROC = 34650, + SPELL_PRIEST_PENANCE_R1 = 47540, + SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, + SPELL_PRIEST_PENANCE_R1_HEAL = 47757, + SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619, + SPELL_PRIEST_REFLECTIVE_SHIELD_R1 = 33201, + SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, + SPELL_PRIEST_T9_HEALING_2P = 67201, + SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, }; enum PriestSpellIcons { - PRIEST_ICON_ID_BORROWED_TIME = 2899, - PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, - PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, + PRIEST_ICON_ID_BORROWED_TIME = 2899, + PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, + PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, +}; + +// -47509 - Divine Aegis +class spell_pri_divine_aegis : public SpellScriptLoader +{ + public: + spell_pri_divine_aegis() : SpellScriptLoader("spell_pri_divine_aegis") { } + + class spell_pri_divine_aegis_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_divine_aegis_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_AEGIS)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetProcTarget(); + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 absorb = CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()); + + // Multiple effects stack, so let's try to find this aura. + if (AuraEffect const* aegis = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PRIEST_DIVINE_AEGIS, EFFECT_0)) + absorb += aegis->GetAmount(); + + absorb = std::min(absorb, eventInfo.GetProcTarget()->getLevel() * 125); + + GetTarget()->CastCustomSpell(SPELL_PRIEST_DIVINE_AEGIS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pri_divine_aegis_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_divine_aegis_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_divine_aegis_AuraScript(); + } +}; + +// 55680 - Glyph of Prayer of Healing +class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader +{ + public: + spell_pri_glyph_of_prayer_of_healing() : SpellScriptLoader("spell_pri_glyph_of_prayer_of_healing") { } + + class spell_pri_glyph_of_prayer_of_healing_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_glyph_of_prayer_of_healing_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL)) + return false; + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL); + int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); + GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_pri_glyph_of_prayer_of_healing_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_glyph_of_prayer_of_healing_AuraScript(); + } }; // -47788 - Guardian Spirit @@ -166,6 +257,57 @@ class spell_pri_mana_burn : public SpellScriptLoader } }; +// 28305 - Mana Leech (Passive) (Priest Pet Aura) +class spell_pri_mana_leech : public SpellScriptLoader +{ + public: + spell_pri_mana_leech() : SpellScriptLoader("spell_pri_mana_leech") { } + + class spell_pri_mana_leech_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_mana_leech_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_MANA_LEECH_PROC)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetTarget()->GetOwner(); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_PRIEST_MANA_LEECH_PROC, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_pri_mana_leech_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pri_mana_leech_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_mana_leech_AuraScript(); + } +}; + // -49821 - Mind Sear class spell_pri_mind_sear : public SpellScriptLoader { @@ -524,9 +666,12 @@ class spell_pri_vampiric_touch : public SpellScriptLoader void AddSC_priest_spell_scripts() { + new spell_pri_divine_aegis(); + new spell_pri_glyph_of_prayer_of_healing(); new spell_pri_guardian_spirit(); new spell_pri_lightwell_renew(); new spell_pri_mana_burn(); + new spell_pri_mana_leech(); new spell_pri_mind_sear(); new spell_pri_pain_and_suffering_proc(); new spell_pri_penance(); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 156158b4e36..f6391c80d63 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -28,10 +28,68 @@ enum RogueSpells { + SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, SPELL_ROGUE_SHIV_TRIGGERED = 5940, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, +}; + +// 13877, 33735, (check 51211, 65956) - Blade Flurry +class spell_rog_blade_flurry : public SpellScriptLoader +{ + public: + spell_rog_blade_flurry() : SpellScriptLoader("spell_rog_blade_flurry") { } + + class spell_rog_blade_flurry_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_blade_flurry_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget()); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (eventInfo.GetDamageInfo()) + { + int32 damage = eventInfo.GetDamageInfo()->GetDamage(); + GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff); + } + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_rog_blade_flurry_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_blade_flurry_AuraScript(); + } }; // -31228 - Cheat Death @@ -440,8 +498,100 @@ class spell_rog_shiv : public SpellScriptLoader } }; +// 57934 - Tricks of the Trade +class spell_rog_tricks_of_the_trade : public SpellScriptLoader +{ + public: + spell_rog_tricks_of_the_trade() : SpellScriptLoader("spell_rog_tricks_of_the_trade") { } + + class spell_rog_tricks_of_the_trade_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_tricks_of_the_trade_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC)) + return false; + return true; + } + + bool Load() + { + _redirectTarget = NULL; + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + GetTarget()->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _redirectTarget = GetTarget()->GetRedirectThreatTarget(); + return _redirectTarget; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + Unit* target = GetTarget(); + target->CastSpell(_redirectTarget, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST, true); + target->CastSpell(target, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, true); + Remove(AURA_REMOVE_BY_DEFAULT); // maybe handle by proc charges + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + DoCheckProc += AuraCheckProcFn(spell_rog_tricks_of_the_trade_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_rog_tricks_of_the_trade_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } + + private: + Unit* _redirectTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_tricks_of_the_trade_AuraScript(); + } +}; + +// 59628 - Tricks of the Trade (Proc) +class spell_rog_tricks_of_the_trade_proc : public SpellScriptLoader +{ + public: + spell_rog_tricks_of_the_trade_proc() : SpellScriptLoader("spell_rog_tricks_of_the_trade_proc") { } + + class spell_rog_tricks_of_the_trade_proc_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_tricks_of_the_trade_proc_AuraScript); + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->ResetRedirectThreat(); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_proc_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rog_tricks_of_the_trade_proc_AuraScript(); + } +}; + void AddSC_rogue_spell_scripts() { + new spell_rog_blade_flurry(); new spell_rog_cheat_death(); new spell_rog_deadly_poison(); new spell_rog_nerves_of_steel(); @@ -449,4 +599,6 @@ void AddSC_rogue_spell_scripts() new spell_rog_prey_on_the_weak(); new spell_rog_rupture(); new spell_rog_shiv(); + new spell_rog_tricks_of_the_trade(); + new spell_rog_tricks_of_the_trade_proc(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 2994761be6f..b69295150c2 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -33,9 +33,11 @@ enum ShamanSpells SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC = 52752, SPELL_SHAMAN_BIND_SIGHT = 6277, SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025, + SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, SPELL_SHAMAN_EXHAUSTION = 57723, SPELL_SHAMAN_FIRE_NOVA_R1 = 1535, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, + SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD = 63279, SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456, SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441, SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132, @@ -266,6 +268,68 @@ class spell_sha_cleansing_totem_pulse : public SpellScriptLoader } }; +// -974 - Earth Shield +class spell_sha_earth_shield : public SpellScriptLoader +{ + public: + spell_sha_earth_shield() : SpellScriptLoader("spell_sha_earth_shield") { } + + class spell_sha_earth_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_earth_shield_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD)) + return false; + return true; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + { + amount = caster->SpellHealingBonusDone(GetUnitOwner(), GetSpellInfo(), amount, HEAL); + amount = GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, HEAL); + + // Glyph of Earth Shield + //! WORKAROUND + //! this glyphe is a proc + if (AuraEffect* glyphe = caster->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD, EFFECT_0)) + AddPct(amount, glyphe->GetAmount()); + } + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + + //! HACK due to currenct proc system implementation + if (Player* player = GetTarget()->ToPlayer()) + if (player->HasSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL)) + return; + + GetTarget()->CastCustomSpell(SPELL_SHAMAN_EARTH_SHIELD_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff, GetCasterGUID()); + + if (Player* player = GetTarget()->ToPlayer()) + player->AddSpellCooldown(SPELL_SHAMAN_EARTH_SHIELD_HEAL, 0, time(NULL) + 3); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_earth_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_sha_earth_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_sha_earth_shield_AuraScript(); + } +}; + // 6474 - Earthbind Totem - Fix Talent: Earthen Power class spell_sha_earthbind_totem : public SpellScriptLoader { @@ -780,6 +844,7 @@ void AddSC_shaman_spell_scripts() new spell_sha_bloodlust(); new spell_sha_chain_heal(); new spell_sha_cleansing_totem_pulse(); + new spell_sha_earth_shield(); new spell_sha_earthbind_totem(); new spell_sha_earthen_power(); new spell_sha_fire_nova(); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 68ad1315dce..78bfcbab6a0 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -37,6 +37,8 @@ enum WarlockSpells SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, + SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, + SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE = 63106, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, @@ -48,6 +50,7 @@ enum WarlockSpells SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -418,6 +421,49 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader } }; +// -47230 - Fel Synergy +class spell_warl_fel_synergy : public SpellScriptLoader +{ + public: + spell_warl_fel_synergy() : SpellScriptLoader("spell_warl_fel_synergy") { } + + class spell_warl_fel_synergy_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_fel_synergy_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_FEL_SYNERGY_HEAL)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return GetTarget()->GetGuardianPet() && eventInfo.GetDamageInfo()->GetDamage(); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 heal = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_WARLOCK_FEL_SYNERGY_HEAL, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff); // TARGET_UNIT_PET + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warl_fel_synergy_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_fel_synergy_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_fel_synergy_AuraScript(); + } +}; + // -48181 - Haunt class spell_warl_haunt : public SpellScriptLoader { @@ -686,6 +732,55 @@ class spell_warl_shadow_ward : public SpellScriptLoader } }; +// 63108 - Siphon Life +class spell_warl_siphon_life : public SpellScriptLoader +{ + public: + spell_warl_siphon_life() : SpellScriptLoader("spell_warl_siphon_life") { } + + class spell_warl_siphon_life_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_siphon_life_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SIPHON_LIFE_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE)) + return false; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetDamageInfo()->GetDamage(); + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())); + // Glyph of Siphon Life + if (AuraEffect const* glyphe = GetTarget()->GetAuraEffect(SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE, EFFECT_0)) + AddPct(amount, glyphe->GetAmount()); + + GetTarget()->CastCustomSpell(SPELL_WARLOCK_SIPHON_LIFE_HEAL, SPELLVALUE_BASE_POINT0, amount, GetTarget(), true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warl_siphon_life_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warl_siphon_life_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_siphon_life_AuraScript(); + } +}; + // 29858 - Soulshatter class spell_warl_soulshatter : public SpellScriptLoader { @@ -774,12 +869,14 @@ void AddSC_warlock_spell_scripts() new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); new spell_warl_everlasting_affliction(); + new spell_warl_fel_synergy(); new spell_warl_haunt(); new spell_warl_health_funnel(); new spell_warl_life_tap(); new spell_warl_ritual_of_doom_effect(); new spell_warl_seed_of_corruption(); new spell_warl_shadow_ward(); + new spell_warl_siphon_life(); new spell_warl_soulshatter(); new spell_warl_unstable_affliction(); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 822d4b17992..7136f046873 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -31,21 +31,26 @@ enum WarriorSpells SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, + SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162, SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850, SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721, SPELL_WARRIOR_EXECUTE = 20647, SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367, + SPELL_WARRIOR_GLYPH_OF_VIGILANCE = 63326, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, SPELL_WARRIOR_SLAM = 50783, + SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654, SPELL_WARRIOR_TAUNT = 355, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2 = 46860, SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1 = 64849, SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850, + SPELL_WARRIOR_VIGILANCE_PROC = 50725, + SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665, SPELL_PALADIN_BLESSING_OF_SANCTUARY = 20911, SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY = 25899, @@ -195,6 +200,44 @@ class spell_warr_concussion_blow : public SpellScriptLoader } }; +// -58872 - Damage Shield +class spell_warr_damage_shield : public SpellScriptLoader +{ + public: + spell_warr_damage_shield() : SpellScriptLoader("spell_warr_damage_shield") { } + + class spell_warr_damage_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_damage_shield_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE)) + return false; + return true; + } + + void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + // % of amount blocked + int32 damage = CalculatePct(int32(GetTarget()->GetShieldBlockValue()), aurEff->GetAmount()); + GetTarget()->CastCustomSpell(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); + } + + void Register() + { + OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_damage_shield_AuraScript(); + } +}; + // -12162 - Deep Wounds class spell_warr_deep_wounds : public SpellScriptLoader { @@ -551,6 +594,57 @@ class spell_warr_slam : public SpellScriptLoader } }; +// 12328, 18765, 35429 - Sweeping Strikes +class spell_warr_sweeping_strikes : public SpellScriptLoader +{ + public: + spell_warr_sweeping_strikes() : SpellScriptLoader("spell_warr_sweeping_strikes") { } + + class spell_warr_sweeping_strikes_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warr_sweeping_strikes_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK)) + return false; + return true; + } + + bool Load() + { + _procTarget = NULL; + return true; + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget()); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK, true, NULL, aurEff); + } + + void Register() + { + DoCheckProc += AuraCheckProcFn(spell_warr_sweeping_strikes_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_sweeping_strikes_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + + private: + Unit* _procTarget; + }; + + AuraScript* GetAuraScript() const + { + return new spell_warr_sweeping_strikes_AuraScript(); + } +}; + // 50720 - Vigilance class spell_warr_vigilance : public SpellScriptLoader { @@ -563,34 +657,80 @@ class spell_warr_vigilance : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) { + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_VIGILANCE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_PROC)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT)) + return false; if (!sSpellMgr->GetSpellInfo(SPELL_GEN_DAMAGE_REDUCTION_AURA)) return false; return true; } - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + bool Load() { - if (Unit* target = GetTarget()) - target->CastSpell(target, SPELL_GEN_DAMAGE_REDUCTION_AURA, true); + _procTarget = NULL; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_GEN_DAMAGE_REDUCTION_AURA, true); + + if (Unit* caster = GetCaster()) + target->CastSpell(caster, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT, true); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Unit* target = GetTarget()) + //! WORKAROUND + //! this glyph is a proc + if (Unit* caster = GetCaster()) { - if (target->HasAura(SPELL_GEN_DAMAGE_REDUCTION_AURA) && !(target->HasAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY) || - target->HasAura(SPELL_PRIEST_RENEWED_HOPE))) - target->RemoveAurasDueToSpell(SPELL_GEN_DAMAGE_REDUCTION_AURA); + if (AuraEffect const* glyph = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_VIGILANCE, EFFECT_0)) + GetTarget()->ModifyRedirectThreat(glyph->GetAmount()); } } + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->HasAura(SPELL_GEN_DAMAGE_REDUCTION_AURA) && + !(target->HasAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY) || + target->HasAura(SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY) || + target->HasAura(SPELL_PRIEST_RENEWED_HOPE))) + { + target->RemoveAurasDueToSpell(SPELL_GEN_DAMAGE_REDUCTION_AURA); + } + + target->ResetRedirectThreat(); + } + + bool CheckProc(ProcEventInfo& /*eventInfo*/) + { + _procTarget = GetCaster(); + return _procTarget; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_VIGILANCE_PROC, true, NULL, aurEff); + } + void Register() { - OnEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleAfterApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + DoCheckProc += AuraCheckProcFn(spell_warr_vigilance_AuraScript::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_vigilance_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } + private: + Unit* _procTarget; }; AuraScript* GetAuraScript() const @@ -636,6 +776,7 @@ void AddSC_warrior_spell_scripts() new spell_warr_bloodthirst_heal(); new spell_warr_charge(); new spell_warr_concussion_blow(); + new spell_warr_damage_shield(); new spell_warr_deep_wounds(); new spell_warr_execute(); new spell_warr_improved_spell_reflection(); @@ -645,6 +786,7 @@ void AddSC_warrior_spell_scripts() new spell_warr_rend(); new spell_warr_shattering_throw(); new spell_warr_slam(); + new spell_warr_sweeping_strikes(); new spell_warr_vigilance(); new spell_warr_vigilance_trigger(); } -- cgit v1.2.3 From 39c2d892f3e696526b2373fb6990f3a93c2bd9ec Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 23 Jan 2013 17:48:17 +0100 Subject: Core/Log: Allow configuring a maximum file size for a log file. If the file size is about to be exceeded, the core will create a new file titled _.log and start outputting there. --- src/server/shared/Logging/Appender.h | 6 ++++++ src/server/shared/Logging/AppenderFile.cpp | 20 ++++++++++++++++++-- src/server/shared/Logging/AppenderFile.h | 4 +++- src/server/shared/Logging/Log.cpp | 9 ++++++++- src/server/worldserver/worldserver.conf.dist | 9 ++++++++- 5 files changed, 43 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index a8854a8abc6..08628948b90 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -123,6 +123,12 @@ struct LogMessage std::string prefix; std::string param1; time_t mtime; + + ///@ Returns size of the log message content in bytes + uint32 Size() const + { + return prefix.size() + text.size(); + } }; class Appender diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 8189237bb4e..c2f1e0c919d 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -18,11 +18,12 @@ #include "AppenderFile.h" #include "Common.h" -AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags) +AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags, uint64 fileSize) : Appender(id, name, APPENDER_FILE, level, _flags) , filename(_filename) , logDir(_logDir) , mode(_mode) + , _fileSize(fileSize) { dynamicName = std::string::npos != filename.find("%s"); backup = _flags & APPENDER_FLAGS_MAKE_FILE_BACKUP; @@ -46,12 +47,25 @@ void AppenderFile::_write(LogMessage const& message) char namebuf[TRINITY_PATH_MAX]; snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); logfile = OpenFile(namebuf, mode, backup); + _fileSize = ftell(logfile); } if (logfile) { + if (!dynamicName && _fileSize + message.Size() > _maxFileSize) + { + /** @ We assume all log files have a .log extension. + If file "gol.log" is at its max capacity, this will spawn a new file, "gol_.log". If that one reaches capacity, it'll spawn "gol__.log", etc. + */ + filename.replace(filename.end() - 3, filename.end(), "_.log"); + logfile = OpenFile(filename.c_str(), mode, backup); + _write(message); + return; + } + fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str()); fflush(logfile); + _fileSize += message.Size(); if (dynamicName) { @@ -71,5 +85,7 @@ FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mod rename(filename.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore } - return fopen((logDir + filename).c_str(), mode.c_str()); + FILE* ret = fopen((logDir + filename).c_str(), mode.c_str()); + _fileSize = ftell(ret); + return ret; } diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index a3fe285cc7d..4f3055bd6be 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -23,7 +23,7 @@ class AppenderFile: public Appender { public: - AppenderFile(uint8 _id, std::string const& _name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags); + AppenderFile(uint8 _id, std::string const& _name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 maxSize); ~AppenderFile(); FILE* OpenFile(std::string const& _name, std::string const& _mode, bool _backup); @@ -35,6 +35,8 @@ class AppenderFile: public Appender std::string mode; bool dynamicName; bool backup; + uint64 _maxFileSize; + uint64 _fileSize; }; #endif diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 96c72b5eb74..73b75a2a853 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -145,8 +145,15 @@ void Log::CreateAppenderFromConfig(const char* name) filename += m_logsTimestamp; } + uint64 maxFileSize = 0; + if (++iter != tokens.end()) + { + char const* c = *iter; + maxFileSize = atoi(c); + } + uint8 id = NextAppenderId(); - appenders[id] = new AppenderFile(id, name, level, filename.c_str(), m_logsDir.c_str(), mode.c_str(), flags); + appenders[id] = new AppenderFile(id, name, level, filename.c_str(), m_logsDir.c_str(), mode.c_str(), flags, maxFileSize); //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type FILE, Mask %u, File %s, Mode %s\n", name, id, level, filename.c_str(), mode.c_str()); // DEBUG - RemoveMe break; } diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 51c083a3dbe..31d180df751 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2661,7 +2661,7 @@ PlayerDump.DisallowOverwrite = 1 # Appender config values: Given a appender "name" # Appender.name # Description: Defines 'where to log' -# Format: Type,LogLevel,Flags,optional1,optional2 +# Format: Type,LogLevel,Flags,optional1,optional2,optional3 # # Type # 0 - (None) @@ -2712,6 +2712,13 @@ PlayerDump.DisallowOverwrite = 1 # a - (Append) # w - (Overwrite) # +# MaxFileSize: Maximum file size of the log file before creating a new log file +# (read as optional3 if Type = File) +# Size is measured in bytes expressed in a 64-bit unsigned integer. +# Maximum value is 4294967295 (4 gb). Leave blank for no limit. +# NOTE: Does not work with dynamic filenames. +# Example: 536870912 (512 mb) +# Appender.Console=1,3,0 Appender.Server=2,2,0,Server.log,w -- cgit v1.2.3 From 70490c8238d21ff56be48d6b8444344451f8f255 Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Wed, 23 Jan 2013 20:58:01 +0200 Subject: Script/Commands: Add command to join an existing group/party. --- sql/updates/world/2013_01_23_01_world_misc.sql | 10 +++++ src/server/game/Miscellaneous/Language.h | 4 ++ src/server/scripts/Commands/cs_misc.cpp | 56 ++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 sql/updates/world/2013_01_23_01_world_misc.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_23_01_world_misc.sql b/sql/updates/world/2013_01_23_01_world_misc.sql new file mode 100644 index 00000000000..25042e241dd --- /dev/null +++ b/sql/updates/world/2013_01_23_01_world_misc.sql @@ -0,0 +1,10 @@ +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 1145 AND 1148; +INSERT INTO `trinity_string` (`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`) VALUES +(1145,'%s is already in a group!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1146,'%s joined %s''s group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1147,'%s is not in a group!',NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1148,'Group is full!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +DELETE FROM `command` WHERE `name`='group join'; +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('group join',3,'Syntax: .group join $AnyCharacterNameFromGroup [$CharacterName] \r\nAdds to group of player $AnyCharacterNameFromGroup player $CharacterName (or selected).'); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 039e8b816b3..093622467f8 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -847,6 +847,10 @@ enum TrinityStrings LANG_MOVEGENS_EFFECT = 1142, LANG_MOVEFLAGS_GET = 1143, LANG_MOVEFLAGS_SET = 1144, + LANG_GROUP_ALREADY_IN_GROUP = 1145, + LANG_GROUP_PLAYER_JOINED = 1146, + LANG_GROUP_NOT_IN_GROUP = 1147, + LANG_GROUP_FULL = 1148, // Room for more level 3 1144-1199 not used // Debug commands diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 54fe41a8a4d..e2b5ac9487d 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -46,6 +46,7 @@ public: { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, + { "join", SEC_ADMINISTRATOR, false, &HandleGroupJoinCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand petCommandTable[] = @@ -2725,6 +2726,61 @@ public: return true; } + static bool HandleGroupJoinCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerSource = NULL; + Player* playerTarget = NULL; + Group* groupSource = NULL; + Group* groupTarget = NULL; + uint64 guidSource = 0; + uint64 guidTarget = 0; + char* nameplgrStr = strtok((char*)args, " "); + char* nameplStr = strtok(NULL, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameplgrStr, playerSource, groupSource, guidSource, true)) + { + if (groupSource) + { + if (handler->GetPlayerGroupAndGUIDByName(nameplStr, playerTarget, groupTarget, guidTarget, true)) + { + if (!groupTarget && playerTarget->GetGroup() != groupSource) + { + if (!groupSource->IsFull()) + { + groupSource->AddMember(playerTarget); + groupSource->BroadcastGroupUpdate(); + handler->PSendSysMessage(LANG_GROUP_PLAYER_JOINED, playerTarget->GetName().c_str(), playerSource->GetName().c_str()); + return true; + } + else + { + // group is full + handler->PSendSysMessage(LANG_GROUP_FULL); + return true; + } + } + else + { + // group is full or target player already in a group + handler->PSendSysMessage(LANG_GROUP_ALREADY_IN_GROUP, playerTarget->GetName().c_str()); + return true; + } + } + } + else + { + // specified source player is not in a group + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, playerSource->GetName().c_str()); + return true; + } + } + + return true; + } + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) { if (!*args) -- cgit v1.2.3 From d291c78ca0889d569c114d1a638fac466a1fe7a6 Mon Sep 17 00:00:00 2001 From: WishToDie Date: Wed, 23 Jan 2013 21:08:33 +0200 Subject: Typo fix. --- src/server/game/Miscellaneous/Language.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 093622467f8..1aeb16e9c7e 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -851,7 +851,7 @@ enum TrinityStrings LANG_GROUP_PLAYER_JOINED = 1146, LANG_GROUP_NOT_IN_GROUP = 1147, LANG_GROUP_FULL = 1148, - // Room for more level 3 1144-1199 not used + // Room for more level 3 1149-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, -- cgit v1.2.3 From f4de181db00bf323793e2121aac496588c3b9b33 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 23 Jan 2013 20:29:40 +0100 Subject: SQL: Rename SQL merged in PR --- dep/SFMT/SFMT.h | 2 +- dep/SFMT/randomc.h | 2 +- .../2013_01_23_00_world_spell_script_names.sql | 77 ---------------------- .../2013_01_23_02_world_spell_script_names.sql | 77 ++++++++++++++++++++++ src/tools/mesh_extractor/Chunk.cpp | 2 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 12 ++-- 8 files changed, 88 insertions(+), 88 deletions(-) delete mode 100644 sql/updates/world/2013_01_23_00_world_spell_script_names.sql create mode 100644 sql/updates/world/2013_01_23_02_world_spell_script_names.sql (limited to 'src') diff --git a/dep/SFMT/SFMT.h b/dep/SFMT/SFMT.h index 08966e1831c..4004ae1db6e 100644 --- a/dep/SFMT/SFMT.h +++ b/dep/SFMT/SFMT.h @@ -7,7 +7,7 @@ * in effect in addition to the GNU General Public License. * Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University. * Copyright (c) 2008 by Agner Fog. - * Copyright (c) 2012 Trinity Core + * Copyright (c) 2008-2013 Trinity Core * * BSD License: * Redistribution and use in source and binary forms, with or without diff --git a/dep/SFMT/randomc.h b/dep/SFMT/randomc.h index ee5ad9aa43b..eed2c81a205 100644 --- a/dep/SFMT/randomc.h +++ b/dep/SFMT/randomc.h @@ -7,7 +7,7 @@ * in effect in addition to the GNU General Public License. * Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University. * Copyright (c) 2008 by Agner Fog. - * Copyright (c) 2012 Trinity Core + * Copyright (c) 2008-2013 Trinity Core * * BSD License: * Redistribution and use in source and binary forms, with or without diff --git a/sql/updates/world/2013_01_23_00_world_spell_script_names.sql b/sql/updates/world/2013_01_23_00_world_spell_script_names.sql deleted file mode 100644 index dd8b35ae420..00000000000 --- a/sql/updates/world/2013_01_23_00_world_spell_script_names.sql +++ /dev/null @@ -1,77 +0,0 @@ -DELETE FROM `spell_script_names` WHERE `spell_id` IN ( -70871, -- spell_blood_queen_essence_of_the_blood_queen -69383, -- spell_the_lich_king_dark_hunger -50453, -- spell_dk_blood_gorged --48496, -- spell_dru_living_seed -48504, -- spell_dru_living_seed_proc -28764, -- spell_gen_adaptive_warding -27539, -- spell_gen_obsidian_armor -34074, -- spell_hun_ascpect_of_the_viper -64411, -- spell_item_blessing_of_ancient_kings -71875, -- spell_item_necrotic_touch -71877, -- spell_item_necrotic_touch -71169, -- spell_item_shadows_fate -71903, -- spell_item_shadowmourne -71905, -- spell_item_shadowmourne_soul_fragment --44449, -- spell_mage_burnout -54646, -- spell_mage_focus_magic --11119, -- spell_mage_ignite --29074, -- spell_mage_master_of_elements --9799, -- spell_pal_eye_for_an_eye -20154, -- spell_pal_seal_of_righteousness -21084 -- spell_pal_seal_of_righteousness --47509, -- spell_pri_divine_aegis -55680, -- spell_pri_glyph_of_prayer_of_healing -28305, -- spell_pri_mana_leech -13877, -- spell_rog_blade_flurry -33735, -- spell_rog_blade_flurry -51211, -- spell_rog_blade_flurry -65956, -- spell_rog_blade_flurry -57934, -- spell_rog_tricks_of_the_trade -59628, -- spell_rog_tricks_of_the_trade_proc --974, -- spell_sha_earth_shield --47230, -- spell_warl_fel_synergy -63108, -- spell_warl_siphon_life --58872, -- spell_warr_damage_shield -12328, -- spell_warr_sweeping_strikes -18765, -- spell_warr_sweeping_strikes -35429 -- spell_warr_sweeping_strikes -); -INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES -(70871, 'spell_blood_queen_essence_of_the_blood_queen'), -(69383, 'spell_the_lich_king_dark_hunger'), -(50453, 'spell_dk_blood_gorged'), -(-48496, 'spell_dru_living_seed'), -(48504, 'spell_dru_living_seed_proc'), -(28764, 'spell_gen_adaptive_warding'), -(27539, 'spell_gen_obsidian_armor'), -(34074, 'spell_hun_ascpect_of_the_viper'), -(64411, 'spell_item_blessing_of_ancient_kings'), -(71875, 'spell_item_necrotic_touch'), -(71877, 'spell_item_necrotic_touch'), -(71169, 'spell_item_shadows_fate'), -(71903, 'spell_item_shadowmourne'), -(71905, 'spell_item_shadowmourne_soul_fragment'), -(-44449, 'spell_mage_burnout'), -(54646, 'spell_mage_focus_magic'), -(-11119, 'spell_mage_ignite'), -(-29074, 'spell_mage_master_of_elements'), -(-9799, 'spell_pal_eye_for_an_eye'), -(20154, 'spell_pal_seal_of_righteousness'), -(21084, 'spell_pal_seal_of_righteousness'), -(-47509, 'spell_pri_divine_aegis'), -(55680, 'spell_pri_glyph_of_prayer_of_healing'), -(28305, 'spell_pri_mana_leech'), -(13877, 'spell_rog_blade_flurry'), -(33735, 'spell_rog_blade_flurry'), -(51211, 'spell_rog_blade_flurry'), -(65956, 'spell_rog_blade_flurry'), -(57934, 'spell_rog_tricks_of_the_trade'), -(59628, 'spell_rog_tricks_of_the_trade_proc'), -(-974, 'spell_sha_earth_shield'), -(-47230, 'spell_warl_fel_synergy'), -(63108, 'spell_warl_siphon_life'), -(-58872, 'spell_warr_damage_shield'), -(12328, 'spell_warr_sweeping_strikes'), -(18765, 'spell_warr_sweeping_strikes'), -(35429, 'spell_warr_sweeping_strikes'); diff --git a/sql/updates/world/2013_01_23_02_world_spell_script_names.sql b/sql/updates/world/2013_01_23_02_world_spell_script_names.sql new file mode 100644 index 00000000000..dd8b35ae420 --- /dev/null +++ b/sql/updates/world/2013_01_23_02_world_spell_script_names.sql @@ -0,0 +1,77 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN ( +70871, -- spell_blood_queen_essence_of_the_blood_queen +69383, -- spell_the_lich_king_dark_hunger +50453, -- spell_dk_blood_gorged +-48496, -- spell_dru_living_seed +48504, -- spell_dru_living_seed_proc +28764, -- spell_gen_adaptive_warding +27539, -- spell_gen_obsidian_armor +34074, -- spell_hun_ascpect_of_the_viper +64411, -- spell_item_blessing_of_ancient_kings +71875, -- spell_item_necrotic_touch +71877, -- spell_item_necrotic_touch +71169, -- spell_item_shadows_fate +71903, -- spell_item_shadowmourne +71905, -- spell_item_shadowmourne_soul_fragment +-44449, -- spell_mage_burnout +54646, -- spell_mage_focus_magic +-11119, -- spell_mage_ignite +-29074, -- spell_mage_master_of_elements +-9799, -- spell_pal_eye_for_an_eye +20154, -- spell_pal_seal_of_righteousness +21084 -- spell_pal_seal_of_righteousness +-47509, -- spell_pri_divine_aegis +55680, -- spell_pri_glyph_of_prayer_of_healing +28305, -- spell_pri_mana_leech +13877, -- spell_rog_blade_flurry +33735, -- spell_rog_blade_flurry +51211, -- spell_rog_blade_flurry +65956, -- spell_rog_blade_flurry +57934, -- spell_rog_tricks_of_the_trade +59628, -- spell_rog_tricks_of_the_trade_proc +-974, -- spell_sha_earth_shield +-47230, -- spell_warl_fel_synergy +63108, -- spell_warl_siphon_life +-58872, -- spell_warr_damage_shield +12328, -- spell_warr_sweeping_strikes +18765, -- spell_warr_sweeping_strikes +35429 -- spell_warr_sweeping_strikes +); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(70871, 'spell_blood_queen_essence_of_the_blood_queen'), +(69383, 'spell_the_lich_king_dark_hunger'), +(50453, 'spell_dk_blood_gorged'), +(-48496, 'spell_dru_living_seed'), +(48504, 'spell_dru_living_seed_proc'), +(28764, 'spell_gen_adaptive_warding'), +(27539, 'spell_gen_obsidian_armor'), +(34074, 'spell_hun_ascpect_of_the_viper'), +(64411, 'spell_item_blessing_of_ancient_kings'), +(71875, 'spell_item_necrotic_touch'), +(71877, 'spell_item_necrotic_touch'), +(71169, 'spell_item_shadows_fate'), +(71903, 'spell_item_shadowmourne'), +(71905, 'spell_item_shadowmourne_soul_fragment'), +(-44449, 'spell_mage_burnout'), +(54646, 'spell_mage_focus_magic'), +(-11119, 'spell_mage_ignite'), +(-29074, 'spell_mage_master_of_elements'), +(-9799, 'spell_pal_eye_for_an_eye'), +(20154, 'spell_pal_seal_of_righteousness'), +(21084, 'spell_pal_seal_of_righteousness'), +(-47509, 'spell_pri_divine_aegis'), +(55680, 'spell_pri_glyph_of_prayer_of_healing'), +(28305, 'spell_pri_mana_leech'), +(13877, 'spell_rog_blade_flurry'), +(33735, 'spell_rog_blade_flurry'), +(51211, 'spell_rog_blade_flurry'), +(65956, 'spell_rog_blade_flurry'), +(57934, 'spell_rog_tricks_of_the_trade'), +(59628, 'spell_rog_tricks_of_the_trade_proc'), +(-974, 'spell_sha_earth_shield'), +(-47230, 'spell_warl_fel_synergy'), +(63108, 'spell_warl_siphon_life'), +(-58872, 'spell_warr_damage_shield'), +(12328, 'spell_warr_sweeping_strikes'), +(18765, 'spell_warr_sweeping_strikes'), +(35429, 'spell_warr_sweeping_strikes'); diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index 9f2898a46e0..4605ae0f0dd 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -17,7 +17,7 @@ int32 Chunk::FindSubChunkOffset(std::string name) matched = 0; else ++matched; - + if (matched == 4) return ftell(stream) - 4; } diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 9b5c9f9c77b..d6125bdd8e2 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -101,7 +101,7 @@ void ContinentBuilder::Build(bool debug) } CalculateTileBounds(); - + dtNavMeshParams params; params.maxPolys = 1 << STATIC_POLY_BITS; params.maxTiles = TileMap->TileTable.size(); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 981834ec7ac..96aecbcce27 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -20,7 +20,7 @@ public: void Read(FILE* stream) { int count = 0; - + count += fread(&MmidIndex, sizeof(uint32), 1, stream); count += fread(&UniqueId, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 119ac94f94f..acb1ed38e27 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -218,7 +218,7 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) if (fread(data, 1, size, stream) != 1) { printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str()); - return; + return; } // And write it in the file fwrite(data, 1, size, disk); @@ -274,7 +274,7 @@ void MapChunkHeader::Read(FILE* stream) count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); Position = Vector3::Read(stream); count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); - + if (count != 27) printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); } @@ -295,7 +295,7 @@ void MHDR::Read(FILE* stream) count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); - + if (count != 12) printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); } @@ -357,7 +357,7 @@ void ModelHeader::Read(FILE* stream) count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - + if (count != 51) printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); @@ -380,7 +380,7 @@ WorldModelHeader WorldModelHeader::Read(FILE* stream) ret.BoundingBox[0] = Vector3::Read(stream); ret.BoundingBox[1] = Vector3::Read(stream); count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - + if (count != 10) printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); @@ -400,7 +400,7 @@ DoodadInstance DoodadInstance::Read(FILE* stream) count += fread(&ret.QuatZ, sizeof(float), 1, stream); count += fread(&ret.Scale, sizeof(float), 1, stream); count += fread(&ret.LightColor, sizeof(uint32), 1, stream); - + if (count != 7) printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); -- cgit v1.2.3 From 1c0239ea9873f1fbbaf6cf80bb3caf2d350a656a Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 23 Jan 2013 22:56:56 +0100 Subject: Core/DBLayer: Drop support for MySQL versions <5.1 Both server and client libraries must be up to date in order to run TC. --- src/server/shared/Database/DatabaseWorkerPool.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 34b7c5083e3..3df9436a4c4 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -31,6 +31,9 @@ #include "QueryHolder.h" #include "AdhocStatement.h" +#define MIN_MYSQL_SERVER_VERSION 51000u +#define MIN_MYSQL_CLIENT_VERSION 51000u + class PingOperation : public SQLOperation { //! Operation for idle delaythreads @@ -53,6 +56,9 @@ class DatabaseWorkerPool _connections.resize(IDX_SIZE); WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe."); + WPFatal (mysql_get_server_version() >= MIN_MYSQL_SERVER_VERSION && + mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, + "TrinityCore does not support MySQL versions below 5.1"); } ~DatabaseWorkerPool() -- cgit v1.2.3 From 6c5fbc492c7353dcf41c6becc669baa7e2d0205d Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 23 Jan 2013 23:14:18 +0100 Subject: Scripts/Icecrown Citadel: Fixed Essence of the Blood Queen interrupting player spell casts Closes #8665 --- .../scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 5643d0ab732..ab0c44aa6d0 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -720,7 +720,7 @@ class spell_blood_queen_essence_of_the_blood_queen : public SpellScriptLoader { PreventDefaultAction(); int32 heal = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget()); + GetTarget()->CastCustomSpell(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL, SPELLVALUE_BASE_POINT0, heal, GetTarget(), TRIGGERED_FULL_MASK, NULL, aurEff); } void Register() -- cgit v1.2.3 From 5d75ac29b49b4238844f84aedcbbe62c43c8180d Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 23 Jan 2013 23:25:42 +0100 Subject: Tools: Remove a bit of spam when mmaps_generator loads vmaps --- src/server/collision/VMapDefinitions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index 56084389ad6..bb0766dc8ff 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -38,9 +38,9 @@ namespace VMAP #define VMAP_DEBUG_LOG(FILTER, ...) sLog->outDebug(FILTER, __VA_ARGS__) #define VMAP_INFO_LOG(FILTER, ...) sLog->outInfo(FILTER, __VA_ARGS__) #else -#define VMAP_ERROR_LOG(FILTER, ...) printf(__VA_ARGS__) -#define VMAP_DEBUG_LOG(FILTER, ...) printf(__VA_ARGS__) -#define VMAP_INFO_LOG(FILTER, ...) printf(__VA_ARGS__) +#define VMAP_ERROR_LOG(FILTER, ...) (void)sizeof(FILTER) +#define VMAP_DEBUG_LOG(FILTER, ...) (void)sizeof(FILTER) +#define VMAP_INFO_LOG(FILTER, ...) (void)sizeof(FILTER) #endif #endif -- cgit v1.2.3 From fd967ba4c64a71221397523440f2a3da0a9ec5f3 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Thu, 24 Jan 2013 01:20:25 +0100 Subject: Tools/mmaps_generator: Multithreading optimisations. Should save some time generating mmaps. --- src/server/shared/Database/DatabaseWorkerPool.h | 5 +-- src/tools/mmaps_generator/MapBuilder.cpp | 31 ++++---------- src/tools/mmaps_generator/MapBuilder.h | 55 ++++++++++++++++++++----- 3 files changed, 56 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 3df9436a4c4..edbc41be8f7 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -56,9 +56,7 @@ class DatabaseWorkerPool _connections.resize(IDX_SIZE); WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe."); - WPFatal (mysql_get_server_version() >= MIN_MYSQL_SERVER_VERSION && - mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, - "TrinityCore does not support MySQL versions below 5.1"); + WPFatal (mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1"); } ~DatabaseWorkerPool() @@ -79,6 +77,7 @@ class DatabaseWorkerPool { T* t = new T(_queue, _connectionInfo); res &= t->Open(); + WPFatal (mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "TrinityCore does not support MySQL versions below 5.1"); _connections[IDX_ASYNC][i] = t; ++_connectionCount[IDX_ASYNC]; } diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index a62011ddfff..4707feb5857 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -166,45 +166,32 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - - for (int i = 0; i < threads; ++i) - _threads.push_back(new BuilderThread(this)); + + BuilderThreadPool* pool = new BuilderThreadPool(); for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { uint32 mapID = it->first; if (!shouldSkipMap(mapID)) { - if (threads > 1) - { - bool next = false; - while (!next) - { - for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) - { - if ((*_th)->Free) - { - (*_th)->SetMapId(mapID); - (*_th)->activate(); - next = true; - break; - } - } - // Wait for 20 seconds - ACE_OS::sleep(ACE_Time_Value (0, 20000)); - } - } + if (threads > 0) + pool->Enqueue(new BuildAMapPlz(mapID)); else buildMap(mapID); } } + for (int i = 0; i < threads; ++i) + _threads.push_back(new BuilderThread(this, pool->Queue())); + // Free memory for (std::vector::iterator _th = _threads.begin(); _th != _threads.end(); ++_th) { (*_th)->wait(); delete *_th; } + + delete pool; } /**************************************************************************/ diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ea9636b3cc3..ea805fd9235 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -30,6 +30,8 @@ #include "DetourNavMesh.h" #include +#include +#include using namespace VMAP; @@ -123,27 +125,60 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; + + class BuildAMapPlz : public ACE_Method_Request + { + public: + BuildAMapPlz(uint32 mapId) : _mapId(mapId) {} + + virtual int call() + { + /// @ Actually a creative way of unabstracting the class and returning a member variable + return (int)_mapId; + } + + private: + uint32 _mapId; + }; class BuilderThread : public ACE_Task { private: MapBuilder* _builder; - uint32 _mapId; - public: - BuilderThread(MapBuilder* builder) : _builder(builder), Free(true) {} - - void SetMapId(uint32 mapId) { _mapId = mapId; } + ACE_Activation_Queue* _queue; + public: + BuilderThread(MapBuilder* builder, ACE_Activation_Queue* queue) : _builder(builder), _queue(queue) { activate(); } + int svc() { - Free = false; - if (_builder) - _builder->buildMap(_mapId); - Free = true; + BuildAMapPlz* request = NULL; + while (request = (BuildAMapPlz*)_queue->dequeue()) + { + _builder->buildMap(request->call()); + delete request; + request = NULL; + } return 0; } - bool Free; + }; + + class BuilderThreadPool + { + public: + BuilderThreadPool() : _queue(new ACE_Activation_Queue()) {} + ~BuilderThreadPool() { _queue->queue()->close(); delete _queue; } + + void Enqueue(BuildAMapPlz* request) + { + _queue->enqueue(request); + } + + ACE_Activation_Queue* Queue() { return _queue; } + + private: + ACE_Activation_Queue* _queue; }; } -- cgit v1.2.3 From 54027803bdcdefb48007e791f02202a23bf10076 Mon Sep 17 00:00:00 2001 From: Mislav Blažević Date: Wed, 23 Jan 2013 21:11:08 +0100 Subject: Fix error when swapping unique equipped weapon on dual wield Also fix rings and trinkets --- src/server/game/Entities/Player/Player.cpp | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 14878b078bd..208b24ea105 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -10735,7 +10735,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des { if (no_space_count) *no_space_count = count; - return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND; + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND; } if (pItem) @@ -11490,8 +11490,36 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot)) return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE; - // if swap ignore item (equipped also) - InventoryResult res2 = CanEquipUniqueItem(pItem, swap ? eslot : uint8(NULL_SLOT)); + // if we are swapping 2 equiped items, CanEquipUniqueItem check + // should ignore the item we are trying to swap, and not the + // destination item. CanEquipUniqueItem should ignore destination + // item only when we are swapping weapon from bag + uint8 ignore; + switch (eslot) + { + case EQUIPMENT_SLOT_MAINHAND: + ignore = EQUIPMENT_SLOT_OFFHAND; + break; + case EQUIPMENT_SLOT_OFFHAND: + ignore = EQUIPMENT_SLOT_MAINHAND; + break; + case EQUIPMENT_SLOT_FINGER1: + ignore = EQUIPMENT_SLOT_FINGER2; + break; + case EQUIPMENT_SLOT_FINGER2: + ignore = EQUIPMENT_SLOT_FINGER1; + break; + case EQUIPMENT_SLOT_TRINKET1: + ignore = EQUIPMENT_SLOT_TRINKET2; + break; + case EQUIPMENT_SLOT_TRINKET2: + ignore = EQUIPMENT_SLOT_TRINKET1; + break; + } + if (pItem != GetItemByPos(INVENTORY_SLOT_BAG_0, ignore)) + ignore = eslot; + + InventoryResult res2 = CanEquipUniqueItem(pItem, swap ? ignore : uint8(NULL_SLOT)); if (res2 != EQUIP_ERR_OK) return res2; -- cgit v1.2.3 From 3034db92963bb068ee05da7a97d325d6dd4080f1 Mon Sep 17 00:00:00 2001 From: Mislav Blažević Date: Thu, 24 Jan 2013 11:02:08 +0100 Subject: Core/DBLayer: Fixed required version definitions --- src/server/shared/Database/DatabaseWorkerPool.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index edbc41be8f7..9f93e99ab26 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -31,8 +31,8 @@ #include "QueryHolder.h" #include "AdhocStatement.h" -#define MIN_MYSQL_SERVER_VERSION 51000u -#define MIN_MYSQL_CLIENT_VERSION 51000u +#define MIN_MYSQL_SERVER_VERSION 50100u +#define MIN_MYSQL_CLIENT_VERSION 50100u class PingOperation : public SQLOperation { -- cgit v1.2.3 From 23b6a6a7cd27987bff8a5786cfd8dc45349f52ed Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 24 Jan 2013 12:44:58 +0100 Subject: Core/Log: Rotate logs when maximum size is exceeded, backup name will be "filename".datetime - This is an addition to 39c2d89 --- src/server/authserver/authserver.conf.dist | 11 +++- src/server/shared/Logging/AppenderFile.cpp | 83 +++++++++++++++--------------- src/server/shared/Logging/AppenderFile.h | 5 +- 3 files changed, 54 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index 67d22c49da1..dda19c3b849 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -154,7 +154,7 @@ LoginDatabase.WorkerThreads = 1 # Appender config values: Given a appender "name" # Appender.name # Description: Defines 'where to log' -# Format: Type,LogLevel,Flags,optional1,optional2 +# Format: Type,LogLevel,Flags,optional1,optional2,optional3 # # Type # 0 - (None) @@ -205,6 +205,13 @@ LoginDatabase.WorkerThreads = 1 # a - (Append) # w - (Overwrite) # +# MaxFileSize: Maximum file size of the log file before creating a new log file +# (read as optional3 if Type = File) +# Size is measured in bytes expressed in a 64-bit unsigned integer. +# Maximum value is 4294967295 (4 gb). Leave blank for no limit. +# NOTE: Does not work with dynamic filenames. +# Example: 536870912 (512 mb) +# Appender.Console=1,2,0 Appender.Auth=2,2,0,Auth.log,w @@ -250,4 +257,4 @@ Logger.Root=0,3,Console Auth Loggers=Root # -################################################################################################### \ No newline at end of file +################################################################################################### diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index c2f1e0c919d..1ed6350f813 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -18,74 +18,75 @@ #include "AppenderFile.h" #include "Common.h" -AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags, uint64 fileSize) - : Appender(id, name, APPENDER_FILE, level, _flags) - , filename(_filename) - , logDir(_logDir) - , mode(_mode) - , _fileSize(fileSize) +AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags, uint64 fileSize): + Appender(id, name, APPENDER_FILE, level, _flags), + filename(_filename), + logDir(_logDir), + mode(_mode), + maxFileSize(fileSize), + fileSize(0) { dynamicName = std::string::npos != filename.find("%s"); backup = _flags & APPENDER_FLAGS_MAKE_FILE_BACKUP; - logfile = !dynamicName ? OpenFile(_filename, _mode, backup) : NULL; + logfile = !dynamicName ? OpenFile(_filename, _mode, mode == "w" && backup) : NULL; } AppenderFile::~AppenderFile() { - if (logfile) - { - fclose(logfile); - logfile = NULL; - } + CloseFile(); } void AppenderFile::_write(LogMessage const& message) { + bool exceedMaxSize = maxFileSize > 0 && (fileSize + message.Size()) > maxFileSize; + if (dynamicName) { char namebuf[TRINITY_PATH_MAX]; snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); - logfile = OpenFile(namebuf, mode, backup); - _fileSize = ftell(logfile); + logfile = OpenFile(namebuf, mode, backup || exceedMaxSize); } + else if (exceedMaxSize) + logfile = OpenFile(filename, "w", true); - if (logfile) - { - if (!dynamicName && _fileSize + message.Size() > _maxFileSize) - { - /** @ We assume all log files have a .log extension. - If file "gol.log" is at its max capacity, this will spawn a new file, "gol_.log". If that one reaches capacity, it'll spawn "gol__.log", etc. - */ - filename.replace(filename.end() - 3, filename.end(), "_.log"); - logfile = OpenFile(filename.c_str(), mode, backup); - _write(message); - return; - } + if (!logfile) + return; - fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str()); - fflush(logfile); - _fileSize += message.Size(); + fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str()); + fflush(logfile); + fileSize += message.Size(); - if (dynamicName) - { - fclose(logfile); - logfile = NULL; - } - } + if (dynamicName) + CloseFile(); } FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mode, bool backup) { - if (mode == "w" && backup) + std::string fullName(logDir + filename); + if (backup) { - std::string newName(filename); + CloseFile(); + std::string newName(fullName); newName.push_back('.'); newName.append(LogMessage::getTimeStr(time(NULL))); - rename(filename.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore + rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore } - FILE* ret = fopen((logDir + filename).c_str(), mode.c_str()); - _fileSize = ftell(ret); - return ret; + if (FILE* ret = fopen(fullName.c_str(), mode.c_str())) + { + fileSize = ftell(ret); + return ret; + } + + return NULL; +} + +void AppenderFile::CloseFile() +{ + if (logfile) + { + fclose(logfile); + logfile = NULL; + } } diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index 4f3055bd6be..c15974799e1 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -28,6 +28,7 @@ class AppenderFile: public Appender FILE* OpenFile(std::string const& _name, std::string const& _mode, bool _backup); private: + void CloseFile(); void _write(LogMessage const& message); FILE* logfile; std::string filename; @@ -35,8 +36,8 @@ class AppenderFile: public Appender std::string mode; bool dynamicName; bool backup; - uint64 _maxFileSize; - uint64 _fileSize; + uint64 maxFileSize; + uint64 fileSize; }; #endif -- cgit v1.2.3 From 389a4899f4032863955989386a02a6399411ebb3 Mon Sep 17 00:00:00 2001 From: springfieldking Date: Thu, 24 Jan 2013 22:26:11 +0800 Subject: Update src/server/shared/Logging/Log.cpp Fix crash when the last iter plus and change value --- src/server/shared/Logging/Log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 73b75a2a853..48512852dc4 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -146,7 +146,7 @@ void Log::CreateAppenderFromConfig(const char* name) } uint64 maxFileSize = 0; - if (++iter != tokens.end()) + if ( (iter != tokens.end()) && (++iter != tokens.end()) ) { char const* c = *iter; maxFileSize = atoi(c); -- cgit v1.2.3 From 08866f377edae3c32d57195e2d9acabbd85fdd32 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 24 Jan 2013 16:40:35 +0100 Subject: Tools/mmap_generator: Fixed a deadlock at exit --- src/tools/mmaps_generator/MapBuilder.cpp | 8 ++++---- src/tools/mmaps_generator/MapBuilder.h | 20 +++++++++++--------- src/tools/mmaps_generator/PathGenerator.cpp | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 4707feb5857..4a016f267b4 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -166,8 +166,8 @@ namespace MMAP void MapBuilder::buildAllMaps(int threads) { std::vector _threads; - - BuilderThreadPool* pool = new BuilderThreadPool(); + + BuilderThreadPool* pool = threads > 0 ? new BuilderThreadPool() : NULL; for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { @@ -175,13 +175,13 @@ namespace MMAP if (!shouldSkipMap(mapID)) { if (threads > 0) - pool->Enqueue(new BuildAMapPlz(mapID)); + pool->Enqueue(new MapBuildRequest(mapID)); else buildMap(mapID); } } - for (int i = 0; i < threads; ++i) + for (int i = 0; i < threads; ++i) _threads.push_back(new BuilderThread(this, pool->Queue())); // Free memory diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ea805fd9235..3ffaea0ab66 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -125,11 +125,11 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext; }; - - class BuildAMapPlz : public ACE_Method_Request + + class MapBuildRequest : public ACE_Method_Request { public: - BuildAMapPlz(uint32 mapId) : _mapId(mapId) {} + MapBuildRequest(uint32 mapId) : _mapId(mapId) {} virtual int call() { @@ -141,7 +141,7 @@ namespace MMAP uint32 _mapId; }; - class BuilderThread : public ACE_Task + class BuilderThread : public ACE_Task_Base { private: MapBuilder* _builder; @@ -149,19 +149,21 @@ namespace MMAP public: BuilderThread(MapBuilder* builder, ACE_Activation_Queue* queue) : _builder(builder), _queue(queue) { activate(); } - + int svc() { - BuildAMapPlz* request = NULL; - while (request = (BuildAMapPlz*)_queue->dequeue()) + /// @ Set a timeout for dequeue attempts (only used when the queue is empty) as it will never get populated after thread starts + ACE_Time_Value timeout(5); + ACE_Method_Request* request = NULL; + while ((request = _queue->dequeue(&timeout)) != NULL) { _builder->buildMap(request->call()); delete request; request = NULL; } + return 0; } - }; class BuilderThreadPool @@ -170,7 +172,7 @@ namespace MMAP BuilderThreadPool() : _queue(new ACE_Activation_Queue()) {} ~BuilderThreadPool() { _queue->queue()->close(); delete _queue; } - void Enqueue(BuildAMapPlz* request) + void Enqueue(MapBuildRequest* request) { _queue->enqueue(request); } diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 01059099f98..47d35b517d5 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -292,5 +292,5 @@ int main(int argc, char** argv) if (!silent) printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); - return 1; + return 0; } -- cgit v1.2.3 From cc605e060509d1255dfb2659200efa3c6f03fdf2 Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 17 Jan 2013 17:35:47 +0100 Subject: Core/Misc: Minor cosmetic changes here and there --- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Groups/Group.cpp | 2 +- src/server/game/Handlers/BattleGroundHandler.cpp | 4 ++-- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/Server/WorldSocket.cpp | 2 +- src/server/game/World/World.cpp | 29 +++++++++--------------- 7 files changed, 18 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c232a7a936c..fbc40db790e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21759,7 +21759,7 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) } } -bool Player::CanJoinToBattleground() const +bool Player::CanJoinToBattleground(Battleground const* /*bg*/) const { // check Deserter debuff if (HasAura(26013)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a1e6591413f..a69f8c44715 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2227,7 +2227,7 @@ class Player : public Unit, public GridObject uint32 GetBGTeam() const { return m_bgData.bgTeam ? m_bgData.bgTeam : GetTeam(); } void LeaveBattleground(bool teleportToEntryPoint = true); - bool CanJoinToBattleground() const; + bool CanJoinToBattleground(Battleground const* bg) const; bool CanReportAfkDueToLimit(); void ReportedAfkBy(Player* reporter); void ClearAfkReports() { m_bgData.bgAfkReporter.clear(); } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 734a1bfbaad..711e07ef941 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1818,7 +1818,7 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* if (bgOrTemplate->GetTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue()) return ERR_IN_NON_RANDOM_BG; // check for deserter debuff in case not arena queue - if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground()) + if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground(bgOrTemplate)) return ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS; // check if member can join any more battleground queues if (!member->HasFreeBattlegroundQueueId()) diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index e70f127d600..0213df31630 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -138,7 +138,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) } // check Deserter debuff - if (!_player->CanJoinToBattleground()) + if (!_player->CanJoinToBattleground(bg)) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); @@ -413,7 +413,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) if (action == 1 && ginfo.ArenaType == 0) { //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue - if (!_player->CanJoinToBattleground()) + if (!_player->CanJoinToBattleground(bg)) { //send bg command result to show nice message WorldPacket data2; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c16a33ad97c..1aadd7f319d 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1342,7 +1342,7 @@ void WorldSession::HandleComplainOpcode(WorldPacket& recvData) recvData >> unk1; // probably language recvData >> unk2; // message type? recvData >> unk3; // probably channel id - recvData >> unk4; // unk random value + recvData >> unk4; // time recvData >> description; // spam description string (messagetype, channel name, player name, message) break; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index b9955fac523..c80d25be139 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -1033,4 +1033,4 @@ void WorldSocket::SendAuthResponseError(uint8 code) WorldPacket packet(SMSG_AUTH_RESPONSE, 1); packet << uint8(code); SendPacket(packet); -} \ No newline at end of file +} diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 67444475849..26a7986bcb8 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -225,7 +225,7 @@ void World::AddSession(WorldSession* s) void World::AddSession_(WorldSession* s) { - ASSERT (s); + ASSERT(s); //NOTE - Still there is race condition in WorldSession* being used in the Sockets @@ -260,7 +260,7 @@ void World::AddSession_(WorldSession* s) uint32 Sessions = GetActiveAndQueuedSessionCount(); uint32 pLimit = GetPlayerAmountLimit(); - uint32 QueueSize = GetQueuedSessionCount(); //number of players in the queue + uint32 QueueSize = GetQueuedSessionCount(); //number of players in the queue //so we don't count the user trying to //login as a session and queue the socket that we are using @@ -269,7 +269,7 @@ void World::AddSession_(WorldSession* s) if (pLimit > 0 && Sessions >= pLimit && AccountMgr::IsPlayerAccount(s->GetSecurity()) && !HasRecentlyDisconnected(s)) { - AddQueuedPlayer (s); + AddQueuedPlayer(s); UpdateMaxSessionCounters(); sLog->outInfo(LOG_FILTER_GENERAL, "PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId(), ++QueueSize); return; @@ -775,7 +775,7 @@ void World::LoadConfigSettings(bool reload) if (int32(m_int_configs[CONFIG_START_PLAYER_MONEY]) < 0) { sLog->outError(LOG_FILTER_SERVER_LOADING, "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.", m_int_configs[CONFIG_START_PLAYER_MONEY], MAX_MONEY_AMOUNT, 0); - m_int_configs[CONFIG_START_PLAYER_MONEY] = 0; + m_int_configs[CONFIG_START_PLAYER_MONEY] = 0; } else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > MAX_MONEY_AMOUNT) { @@ -1292,12 +1292,7 @@ void World::SetInitialWorldSettings() //No SQL injection as values are treated as integers // not send custom type REALM_FFA_PVP to realm list - uint32 server_type; - if (IsFFAPvPRealm()) - server_type = REALM_TYPE_PVP; - else - server_type = getIntConfig(CONFIG_GAME_TYPE); - + uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE); uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE); LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query @@ -1398,8 +1393,8 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Item Random Enchantments Table..."); LoadRandomEnchantmentsTable(); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Disables"); - DisableMgr::LoadDisables(); // must be before loading quests and items + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Disables"); // must be before loading quests and items + DisableMgr::LoadDisables(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Items..."); // must be after LoadRandomEnchantmentsTable and LoadPageTexts sObjectMgr->LoadItemTemplates(); @@ -1579,9 +1574,11 @@ void World::SetInitialWorldSettings() ///- Load dynamic data tables from the database sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Item Auctions..."); sAuctionMgr->LoadAuctionItems(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Auctions..."); sAuctionMgr->LoadAuctions(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Guilds..."); sGuildMgr->LoadGuilds(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading ArenaTeams..."); @@ -1843,7 +1840,6 @@ void World::DetectDBCLang() m_defaultDbcLocale = LocaleConstant(default_locale); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Using %s DBC Locale as default. All available DBC locales: %s", localeNames[m_defaultDbcLocale], availableLocalsStr.empty() ? "" : availableLocalsStr.c_str()); - } void World::RecordTimeDiff(const char *text, ...) @@ -1883,7 +1879,6 @@ void World::LoadAutobroadcasts() if (!result) { sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty!"); - return; } @@ -1891,7 +1886,6 @@ void World::LoadAutobroadcasts() do { - Field* fields = result->Fetch(); std::string message = fields[0].GetString(); @@ -1900,8 +1894,7 @@ void World::LoadAutobroadcasts() ++count; } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u autobroadcasts definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u autobroadcast definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } /// Update the World ! @@ -2951,8 +2944,8 @@ void World::LoadDBVersion() if (result) { Field* fields = result->Fetch(); - m_DBVersion = fields[0].GetString(); + m_DBVersion = fields[0].GetString(); // will be overwrite by config values if different and non-0 m_int_configs[CONFIG_CLIENTCACHE_VERSION] = fields[1].GetUInt32(); } -- cgit v1.2.3 From 53a3373a985e4c266ed0197e9e537d3de1ffab33 Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 24 Jan 2013 16:56:32 +0100 Subject: Core/Logging: Fix all possible crashes when using bad Appender config settings --- src/server/shared/Logging/Log.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 48512852dc4..f5ef6dfcc5b 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -89,8 +89,9 @@ void Log::CreateAppenderFromConfig(const char* name) options = ConfigMgr::GetStringDefault(options.c_str(), ""); Tokenizer tokens(options, ','); Tokenizer::const_iterator iter = tokens.begin(); + uint8 size = tokens.size(); - if (tokens.size() < 2) + if (size < 2) { fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name, options.c_str()); return; @@ -98,16 +99,15 @@ void Log::CreateAppenderFromConfig(const char* name) AppenderFlags flags = APPENDER_FLAGS_NONE; AppenderType type = AppenderType(atoi(*iter)); - ++iter; - LogLevel level = LogLevel(atoi(*iter)); + LogLevel level = LogLevel(atoi(*(++iter))); if (level > LOG_LEVEL_FATAL) { fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name); return; } - if (++iter != tokens.end()) - flags = AppenderFlags(atoi(*iter)); + if (size > 2) + flags = AppenderFlags(atoi(*(++iter))); switch (type) { @@ -115,7 +115,7 @@ void Log::CreateAppenderFromConfig(const char* name) { AppenderConsole* appender = new AppenderConsole(NextAppenderId(), name, level, flags); appenders[appender->getId()] = appender; - if (++iter != tokens.end()) + if (iter != tokens.end()) appender->InitColors(*iter); //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type CONSOLE, Mask %u\n", appender->getName().c_str(), appender->getId(), appender->getLogLevel()); // DEBUG - RemoveMe break; @@ -125,16 +125,16 @@ void Log::CreateAppenderFromConfig(const char* name) std::string filename; std::string mode = "a"; - if (++iter == tokens.end()) + if (size < 4) { fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name); return; } - filename = *iter; + filename = *(++iter); - if (++iter != tokens.end()) - mode = *iter; + if (size > 4) + mode = *(++iter); if (flags & APPENDER_FLAGS_USE_TIMESTAMP) { @@ -146,11 +146,8 @@ void Log::CreateAppenderFromConfig(const char* name) } uint64 maxFileSize = 0; - if ( (iter != tokens.end()) && (++iter != tokens.end()) ) - { - char const* c = *iter; - maxFileSize = atoi(c); - } + if (size > 5) + maxFileSize = atoi(*(++iter)); uint8 id = NextAppenderId(); appenders[id] = new AppenderFile(id, name, level, filename.c_str(), m_logsDir.c_str(), mode.c_str(), flags, maxFileSize); -- cgit v1.2.3 From bf0c976f76d3ae2078f503748888f1eaf5586b2b Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 24 Jan 2013 17:23:34 +0100 Subject: Core/Players: Fixed uninitialized variable for item swaps --- src/server/game/Entities/Player/Player.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fbc40db790e..66162142fdc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11491,7 +11491,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool // should ignore the item we are trying to swap, and not the // destination item. CanEquipUniqueItem should ignore destination // item only when we are swapping weapon from bag - uint8 ignore; + uint8 ignore = uint8(NULL_SLOT); switch (eslot) { case EQUIPMENT_SLOT_MAINHAND: @@ -11513,7 +11513,8 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool ignore = EQUIPMENT_SLOT_TRINKET1; break; } - if (pItem != GetItemByPos(INVENTORY_SLOT_BAG_0, ignore)) + + if (ignore == uint8(NULL_SLOT) || pItem != GetItemByPos(INVENTORY_SLOT_BAG_0, ignore)) ignore = eslot; InventoryResult res2 = CanEquipUniqueItem(pItem, swap ? ignore : uint8(NULL_SLOT)); -- cgit v1.2.3 From 0d3cc3ae3acdf3e92af4b027b822666b20352774 Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 24 Jan 2013 21:50:58 +0100 Subject: Core/Log: Fix console colors (missing change from 53a3373) Closes #9051 --- src/server/shared/Logging/Log.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index f5ef6dfcc5b..920ce4ce570 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -115,8 +115,8 @@ void Log::CreateAppenderFromConfig(const char* name) { AppenderConsole* appender = new AppenderConsole(NextAppenderId(), name, level, flags); appenders[appender->getId()] = appender; - if (iter != tokens.end()) - appender->InitColors(*iter); + if (size > 3) + appender->InitColors(*(++iter)); //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type CONSOLE, Mask %u\n", appender->getName().c_str(), appender->getId(), appender->getLogLevel()); // DEBUG - RemoveMe break; } -- cgit v1.2.3 From 1c7ade5e54454d285c843e633f69b911a1d81fb9 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 24 Jan 2013 22:46:45 +0100 Subject: Scripts/Icecrown Citadel: Fixed Deathbringer Saurfang's Blood Power scaling on first attempt. Closes #3283 --- .../IcecrownCitadel/boss_deathbringer_saurfang.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 23e4fc19dd2..d688205938a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -415,6 +415,13 @@ class boss_deathbringer_saurfang : public CreatureScript } } + void SpellHit(Unit* caster, SpellInfo const* spell) + { + if (spell->Id == SPELL_BLOOD_LINK_POWER) + if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER)) + bloodPower->RecalculateAmountOfEffects(); + } + void UpdateAI(uint32 const diff) { if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) @@ -1004,8 +1011,6 @@ class spell_deathbringer_blood_link : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { GetHitUnit()->CastCustomSpell(SPELL_BLOOD_LINK_POWER, SPELLVALUE_BASE_POINT0, GetEffectValue(), GetHitUnit(), true); - if (Aura* bloodPower = GetHitUnit()->GetAura(SPELL_BLOOD_POWER)) - bloodPower->RecalculateAmountOfEffects(); PreventHitDefaultEffect(EFFECT_0); } @@ -1093,13 +1098,6 @@ class spell_deathbringer_blood_power : public SpellScriptLoader DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE); DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); } - - bool Load() - { - if (GetUnitOwner()->getPowerType() != POWER_ENERGY) - return false; - return true; - } }; SpellScript* GetSpellScript() const -- cgit v1.2.3 From 705d0c88657e04ee0b4610e2f40ba9378228d670 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 24 Jan 2013 22:51:42 +0100 Subject: Scripts/Icecrown Citadel: Fixed possible crash with Bone Spike Graveyard Closes #7171 --- .../Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index e751ec2bd7b..4763896cf72 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -53,7 +53,7 @@ enum Spells SPELL_COLDFLAME_SUMMON = 69147, }; -uint32 const boneSpikeSummonId[3] = {69062, 72669, 72670}; +uint32 const BoneSpikeSummonId[3] = {69062, 72669, 72670}; enum Events { @@ -515,6 +515,20 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader { PrepareSpellScript(spell_marrowgar_bone_spike_graveyard_SpellScript); + bool Validate(SpellInfo const* /*spell*/) + { + for (uint32 i = 0; i < 3; ++i) + if (!sSpellMgr->GetSpellInfo(BoneSpikeSummonId[i])) + return false; + + return true; + } + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT && GetCaster()->IsAIEnabled; + } + SpellCastResult CheckCast() { return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 0.0f, true, -SPELL_IMPALED) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS; @@ -536,7 +550,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader break; didHit = true; - target->CastCustomSpell(boneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); + target->CastCustomSpell(BoneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); } if (didHit) -- cgit v1.2.3 From c36aa6e7af667580d9a8e4da9971ce8a33e9352b Mon Sep 17 00:00:00 2001 From: thomas33 Date: Fri, 25 Jan 2013 12:25:06 +0100 Subject: fix typo --- src/server/game/Globals/ObjectMgr.cpp | 2 +- src/server/shared/Database/Implementation/WorldDatabase.cpp | 2 +- src/server/shared/Database/Implementation/WorldDatabase.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 30257797470..891bc9b253a 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -4730,7 +4730,7 @@ void ObjectMgr::LoadWaypointScripts() for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr) actionSet.insert(itr->first); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WOLRD_SEL_WAYPOINT_DATA_ACTION); + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ACTION); PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 399a4eeb031..b807736f47b 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -60,7 +60,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID, "UPDATE waypoint_data SET wpguid = 0", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS, "SELECT id, point FROM waypoint_data WHERE (abs(position_x - ?) <= ?) and (abs(position_y - ?) <= ?) and (abs(position_z - ?) <= ?)", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, "SELECT wpguid FROM waypoint_data WHERE id = ? and wpguid <> 0", CONNECTION_SYNCH); - PrepareStatement(WOLRD_SEL_WAYPOINT_DATA_ACTION, "SELECT DISTINCT action FROM waypoint_data", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_WAYPOINT_DATA_ACTION, "SELECT DISTINCT action FROM waypoint_data", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, "SELECT MAX(guid) FROM waypoint_scripts", CONNECTION_SYNCH); PrepareStatement(WORLD_INS_CREATURE_ADDON, "INSERT INTO creature_addon(guid, path_id) VALUES (?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_UPD_CREATURE_ADDON_PATH, "UPDATE creature_addon SET path_id = ? WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 30cc45c535a..032baf29dd9 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -80,7 +80,7 @@ enum WorldDatabaseStatements WORLD_SEL_WAYPOINT_DATA_MAX_POINT, WORLD_SEL_WAYPOINT_DATA_BY_POS, WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, - WOLRD_SEL_WAYPOINT_DATA_ACTION, + WORLD_SEL_WAYPOINT_DATA_ACTION, WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, WORLD_UPD_CREATURE_ADDON_PATH, WORLD_INS_CREATURE_ADDON, -- cgit v1.2.3 From 61495d18a3423d5b7f44425f902342d4a3a3892c Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Fri, 25 Jan 2013 21:40:21 +0100 Subject: Core/Log: Fix crash due to uninitialized variable --- src/server/shared/Logging/AppenderFile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 1ed6350f813..25141815de6 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -24,7 +24,8 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, co logDir(_logDir), mode(_mode), maxFileSize(fileSize), - fileSize(0) + fileSize(0), + logfile(NULL) { dynamicName = std::string::npos != filename.find("%s"); backup = _flags & APPENDER_FLAGS_MAKE_FILE_BACKUP; -- cgit v1.2.3 From 6acfa490659875af8ea546aa223d07b3c9ad21cc Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Sat, 26 Jan 2013 00:41:46 +0200 Subject: Script/Commands: Implement command to list the members of a group/party. --- sql/updates/world/2013_01_26_00_world_misc.sql | 8 +++ src/server/game/Miscellaneous/Language.h | 4 +- src/server/scripts/Commands/cs_misc.cpp | 75 ++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 sql/updates/world/2013_01_26_00_world_misc.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_26_00_world_misc.sql b/sql/updates/world/2013_01_26_00_world_misc.sql new file mode 100644 index 00000000000..429d900d765 --- /dev/null +++ b/sql/updates/world/2013_01_26_00_world_misc.sql @@ -0,0 +1,8 @@ +DELETE FROM `trinity_string` WHERE `entry` IN (1149,1150); +INSERT INTO `trinity_string` (`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`) VALUES +(1149,'Group type: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1150,'Name: %s (%s), GUID: %u, Flags: %s, Roles: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + +DELETE FROM `command` WHERE `name`='group list'; +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('group list',3,'Syntax: .group list [$CharacterName] \r\nLists all the members of the group/party the player is in.'); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 1aeb16e9c7e..8b416339bc7 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -851,7 +851,9 @@ enum TrinityStrings LANG_GROUP_PLAYER_JOINED = 1146, LANG_GROUP_NOT_IN_GROUP = 1147, LANG_GROUP_FULL = 1148, - // Room for more level 3 1149-1199 not used + LANG_GROUP_TYPE = 1149, + LANG_GROUP_PLAYER_NAME_GUID = 1150, + // Room for more level 3 1151-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index e2b5ac9487d..3721f221178 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,6 +33,8 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" +#include "LFG.h" +#include "GroupMGR.h" class misc_commandscript : public CommandScript { @@ -47,6 +49,7 @@ public: { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, { "join", SEC_ADMINISTRATOR, false, &HandleGroupJoinCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, false, &HandleGroupListCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand petCommandTable[] = @@ -2781,6 +2784,78 @@ public: return true; } + static bool HandleGroupListCommand(ChatHandler* handler, char const* args) + { + Player* playerTarget; + uint64 guidTarget; + std::string nameTarget; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) + { + playerTarget = sObjectMgr->GetPlayerByLowGUID(parseGUID); + guidTarget = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) + return false; + + Group* groupTarget = NULL; + if (playerTarget) + groupTarget = playerTarget->GetGroup(); + + if (!groupTarget) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); + stmt->setUInt32(0, guidTarget); + PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); + if (resultGroup) + groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32()); + } + + if (groupTarget) + { + handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); + Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); + Group::MemberSlotList::const_iterator itr; + for (itr = members.begin(); itr != members.end(); ++itr) + { + std::ostringstream flags, roles; + if ((*itr).flags & MEMBER_FLAG_ASSISTANT) + flags << "Assistant "; + if ((*itr).flags & MEMBER_FLAG_MAINTANK) + flags << "MainTank "; + if ((*itr).flags & MEMBER_FLAG_MAINASSIST) + flags << "MainAssist "; + + if ((*itr).roles & PLAYER_ROLE_LEADER) + roles << "Leader "; + if ((*itr).roles & PLAYER_ROLE_TANK) + roles << "Tank "; + if ((*itr).roles & PLAYER_ROLE_HEALER) + roles << "Healer "; + if ((*itr).roles & PLAYER_ROLE_DAMAGE) + roles << "Damage "; + + Player* p = ObjectAccessor::FindPlayer((*itr).guid); + const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; + + std::string flagsStr = (flags.str().empty()) ? "None" : flags.str(); + std::string rolesStr = (roles.str().empty()) ? "None" : roles.str(); + + handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, (*itr).name.c_str(), onlineState, GUID_LOPART((*itr).guid), flagsStr.c_str(), rolesStr.c_str()); + } + return true; + } + else + { + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); + return true; + } + + return true; + } + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) { if (!*args) -- cgit v1.2.3 From 1348e4e44d4a762abc338adbfc58bb22648fa4a9 Mon Sep 17 00:00:00 2001 From: WishToDie Date: Sat, 26 Jan 2013 00:57:10 +0200 Subject: Fix Typo. --- src/server/scripts/Commands/cs_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 3721f221178..3196e81a951 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -34,7 +34,7 @@ #include "Player.h" #include "Pet.h" #include "LFG.h" -#include "GroupMGR.h" +#include "GroupMgr.h" class misc_commandscript : public CommandScript { -- cgit v1.2.3 From a45f7fd878ba9060c3b4a38f353ac0de4b22c388 Mon Sep 17 00:00:00 2001 From: MrSmite Date: Sat, 19 Jan 2013 02:14:20 -0500 Subject: Adds CONF option to show quest levels in dialogs. Example: [13] Westfall Stew Default = 0 (off). Make sure to set UI.ShowQuestLevelsInDialogs to 1 to turn it on NOTES: * DO NOT supply the quest level when using commands such as .lookup quest, it is not actually part of the title (even though it will be printed in the result) * Also adds the level in the quest tracker and quest log * If locale is used, the level is added after the proper title is looked up * LUA Mods that offer this feature do not work properly with TC, most will not put the level in all dialogs. Users who have such mods should disable the mod's feature or they may see the quest level listed twice. Example: [13][13] Westfall Stew --- src/server/game/Entities/Creature/GossipDef.cpp | 35 +++++++++++++++++++++++++ src/server/game/Entities/Creature/GossipDef.h | 2 ++ src/server/game/World/World.cpp | 1 + src/server/game/World/World.h | 1 + src/server/worldserver/worldserver.conf.dist | 8 ++++++ 5 files changed, 47 insertions(+) (limited to 'src') diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index f5877a3b927..a26e84a5311 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -142,6 +142,9 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const data << uint32(_questMenu.GetMenuItemCount()); // max count 0x20 + // Store this instead of checking the Singleton every loop iteration + bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); + for (uint8 i = 0; i < _questMenu.GetMenuItemCount(); ++i) { QuestMenuItem const& item = _questMenu.GetItem(i); @@ -160,6 +163,9 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) ObjectMgr::GetLocaleString(localeData->Title, locale, title); + if (questLevelInTitle) + AddQuestLevelToTitle(title, quest->GetQuestLevel()); + data << title; // max 0x200 } @@ -252,6 +258,10 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title size_t count_pos = data.wpos(); data << uint8 (_questMenu.GetMenuItemCount()); uint32 count = 0; + + // Store this instead of checking the Singleton every loop iteration + bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); + for (; count < _questMenu.GetMenuItemCount(); ++count) { QuestMenuItem const& qmi = _questMenu.GetItem(count); @@ -267,6 +277,9 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) ObjectMgr::GetLocaleString(localeData->Title, locale, title); + if (questLevelInTitle) + AddQuestLevelToTitle(title, quest->GetQuestLevel()); + data << uint32(questID); data << uint32(qmi.QuestIcon); data << int32(quest->GetQuestLevel()); @@ -310,6 +323,9 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, } } + if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) + AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); + WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size data << uint64(npcGUID); data << uint64(0); // wotlk, something todo with quest sharing? @@ -499,6 +515,9 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << float(quest->GetPointY()); data << uint32(quest->GetPointOpt()); + if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) + AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); + data << questTitle; data << questObjectives; data << questDetails; @@ -545,6 +564,9 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b } } + if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) + AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); + WorldPacket data(SMSG_QUESTGIVER_OFFER_REWARD, 50); // guess size data << uint64(npcGUID); data << uint32(quest->GetQuestId()); @@ -645,6 +667,9 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, return; } + if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) + AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); + WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size data << uint64(npcGUID); data << uint32(quest->GetQuestId()); @@ -694,3 +719,13 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, _session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); } + +static void PlayerMenu::AddQuestLevelToTitle(std::string &title, int32 level) +{ + // Adds the quest level to the front of the quest title + // example: [13] Westfall Stew + + std::stringstream questTitlePretty; + questTitlePretty << "[" << level << "] " << title; + title = questTitlePretty.str(); +} diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index 6c5f465bbf0..f13f19bba55 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -277,6 +277,8 @@ class PlayerMenu void SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, bool enableNext) const; void SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const; + static void AddQuestLevelToTitle(std::string &title, int32 level); + private: GossipMenu _gossipMenu; QuestMenu _questMenu; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 26a7986bcb8..c43cbbd417e 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1224,6 +1224,7 @@ void World::LoadConfigSettings(bool reload) // misc m_bool_configs[CONFIG_PDUMP_NO_PATHS] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowPaths", true); m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true); + m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = ConfigMgr::GetBoolDefault("UI.ShowQuestLevelsInDialogs", false); // call ScriptMgr if we're reloading the configuration m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = ConfigMgr::GetBoolDefault("Wintergrasp.Enable", false); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 4a7629cb3af..95c10329690 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -165,6 +165,7 @@ enum WorldBoolConfigs CONFIG_WARDEN_ENABLED, CONFIG_ENABLE_MMAPS, CONFIG_WINTERGRASP_ENABLE, + CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs? BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 31d180df751..641fe1ebb62 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2651,6 +2651,14 @@ PlayerDump.DisallowPaths = 1 PlayerDump.DisallowOverwrite = 1 +# +# UI.ShowQuestLevelsInDialogs +# Description: Show quest levels next to quest titles in UI dialogs +# Example: [13] Westfall Stew +# Default: 0 (do not show) + +UI.ShowQuestLevelsInDialogs = 0 + # ################################################################################################### -- cgit v1.2.3 From a3d07b5e6ac45c23ec4116028c4bccae9307083b Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 26 Jan 2013 13:25:06 +0100 Subject: Core/Spells: Fixed Darkflight, Two Forms and Running Wild for worgens. Closes #8905 --- .../2013_01_26_00_world_spell_script_names_434.sql | 7 + src/server/game/Spells/Auras/SpellAuraEffects.cpp | 34 ++--- src/server/scripts/Spells/spell_generic.cpp | 157 +++++++++++++++++++++ 3 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 sql/updates/world/2013_01_26_00_world_spell_script_names_434.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_26_00_world_spell_script_names_434.sql b/sql/updates/world/2013_01_26_00_world_spell_script_names_434.sql new file mode 100644 index 00000000000..d0c4a61c422 --- /dev/null +++ b/sql/updates/world/2013_01_26_00_world_spell_script_names_434.sql @@ -0,0 +1,7 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_running_wild'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_two_forms'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_darkflight'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(87840,'spell_gen_running_wild'), +(68996,'spell_gen_two_forms'), +(68992,'spell_gen_darkflight'); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 186cdb8c552..18128660436 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2774,6 +2774,8 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo if (apply) { uint32 creatureEntry = GetMiscValue(); + uint32 displayId = 0; + uint32 vehicleId = 0; // Festive Holiday Mount if (target->HasAura(62061)) @@ -2784,30 +2786,28 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo creatureEntry = 15665; } - CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(creatureEntry); - if (!ci) + if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(creatureEntry)) { - sLog->outError(LOG_FILTER_SQL, "AuraMounted: `creature_template`='%u' not found in database (only need its modelid)", GetMiscValue()); - return; - } + uint32 team = 0; + if (target->GetTypeId() == TYPEID_PLAYER) + team = target->ToPlayer()->GetTeam(); - uint32 team = 0; - if (target->GetTypeId() == TYPEID_PLAYER) - team = target->ToPlayer()->GetTeam(); + displayId = ObjectMgr::ChooseDisplayId(team, ci); + sObjectMgr->GetCreatureModelRandomGender(&displayId); - uint32 displayID = ObjectMgr::ChooseDisplayId(team, ci); - sObjectMgr->GetCreatureModelRandomGender(&displayID); + vehicleId = ci->VehicleId; - //some spell has one aura of mount and one of vehicle - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON - && GetSpellInfo()->Effects[i].MiscValue == GetMiscValue()) - displayID = 0; + //some spell has one aura of mount and one of vehicle + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON + && GetSpellInfo()->Effects[i].MiscValue == GetMiscValue()) + displayId = 0; + } - target->Mount(displayID, ci->VehicleId, GetMiscValue()); + target->Mount(displayId, vehicleId, creatureEntry); // cast speed aura - if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscValueB()))) + if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(GetAmount())) target->CastSpell(target, mountCapability->SpeedModSpell, true); } else diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 54cb346a033..d1d4f660172 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3163,6 +3163,160 @@ class spell_gen_replenishment : public SpellScriptLoader } }; +enum RunningWildMountIds +{ + RUNNING_WILD_MODEL_MALE = 29422, + RUNNING_WILD_MODEL_FEMALE = 29423, + SPELL_ALTERED_FORM = 97709, +}; + +class spell_gen_running_wild : public SpellScriptLoader +{ + public: + spell_gen_running_wild() : SpellScriptLoader("spell_gen_running_wild") { } + + class spell_gen_running_wild_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_running_wild_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_MALE)) + return false; + if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_FEMALE)) + return false; + return true; + } + + void HandleMount(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + PreventDefaultAction(); + + target->Mount(target->getGender() == GENDER_FEMALE ? RUNNING_WILD_MODEL_FEMALE : RUNNING_WILD_MODEL_MALE, 0, 0); + + // cast speed aura + if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(aurEff->GetAmount())) + target->CastSpell(target, mountCapability->SpeedModSpell, TRIGGERED_FULL_MASK); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_gen_running_wild_AuraScript::HandleMount, EFFECT_1, SPELL_AURA_MOUNTED, AURA_EFFECT_HANDLE_REAL); + } + }; + + class spell_gen_running_wild_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_running_wild_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ALTERED_FORM)) + return false; + return true; + } + + bool Load() + { + // Definitely not a good thing, but currently the only way to do something at cast start + // Should be replaced as soon as possible with a new hook: BeforeCastStart + GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK); + return false; + } + + void Register() + { + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_running_wild_AuraScript(); + } + + SpellScript* GetSpellScript() const + { + return new spell_gen_running_wild_SpellScript(); + } +}; + +class spell_gen_two_forms : public SpellScriptLoader +{ + public: + spell_gen_two_forms() : SpellScriptLoader("spell_gen_two_forms") { } + + class spell_gen_two_forms_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_two_forms_SpellScript); + + SpellCastResult CheckCast() + { + if (GetCaster()->isInCombat()) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + // Player cannot transform to human form if he is forced to be worgen for some reason (Darkflight) + if (GetCaster()->GetAuraEffectsByType(SPELL_AURA_WORGEN_ALTERED_FORM).size() > 1) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + return SPELL_CAST_OK; + } + + void HandleTransform(SpellEffIndex effIndex) + { + Unit* target = GetHitUnit(); + PreventHitDefaultEffect(effIndex); + if (target->HasAuraType(SPELL_AURA_WORGEN_ALTERED_FORM)) + target->RemoveAurasByType(SPELL_AURA_WORGEN_ALTERED_FORM); + else // Basepoints 1 for this aura control whether to trigger transform transition animation or not. + target->CastCustomSpell(SPELL_ALTERED_FORM, SPELLVALUE_BASE_POINT0, 1, target, TRIGGERED_FULL_MASK); + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_two_forms_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_gen_two_forms_SpellScript::HandleTransform, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_two_forms_SpellScript(); + } +}; + +class spell_gen_darkflight : public SpellScriptLoader +{ + public: + spell_gen_darkflight() : SpellScriptLoader("spell_gen_darkflight") { } + + class spell_gen_darkflight_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_darkflight_SpellScript); + + void TriggerTransform() + { + GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK); + } + + void Register() + { + AfterCast += SpellCastFn(spell_gen_darkflight_SpellScript::TriggerTransform); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_darkflight_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3243,4 +3397,7 @@ void AddSC_generic_spell_scripts() new spell_gen_increase_stats_buff("spell_mage_arcane_brilliance"); new spell_gen_increase_stats_buff("spell_mage_dalaran_brilliance"); new spell_gen_replenishment(); + new spell_gen_running_wild(); + new spell_gen_two_forms(); + new spell_gen_darkflight(); } -- cgit v1.2.3 From f0800d392655f9d55a8e16e64984fb1630f7c4fe Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Sat, 26 Jan 2013 19:19:55 +0200 Subject: Scripts/ShadowmoonValley: Fixup script for Lord Illidan Stormrage quest to be doable. Notice: this whole script needs a proper rewrite(contains wrong Illidan npc id,bad dialogues,etc). --- .../scripts/Outland/zone_shadowmoon_valley.cpp | 75 +++++++++++++++------- 1 file changed, 52 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index 0a016f0923c..a1bfc0a090a 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -661,6 +661,7 @@ class npc_karynaku : public CreatureScript /*#### # npc_overlord_morghor +# this whole script is wrong and needs a rewrite.even the illidan npc used is the wrong one.npc id 23467 may be the correct one ####*/ enum eOverlordData { @@ -766,7 +767,7 @@ public: Player* player = Unit::GetPlayer(*me, PlayerGUID); Creature* Illi = Creature::GetCreature(*me, IllidanGUID); - if (!player || !Illi) + if (!player) { EnterEvadeMode(); return 0; @@ -794,14 +795,21 @@ public: return 2000; break; case 5: - Illi->SetVisible(true); - Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (Illi) + { + Illi->SetVisible(true); + Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Illi->SetDisplayId(21526); + } return 350; break; case 6: - Illi->CastSpell(Illi, SPELL_ONE, true); - Illi->SetTarget(me->GetGUID()); - me->SetTarget(IllidanGUID); + if (Illi) + { + Illi->CastSpell(Illi, SPELL_ONE, true); + Illi->SetTarget(me->GetGUID()); + me->SetTarget(IllidanGUID); + } return 2000; break; case 7: @@ -810,10 +818,15 @@ public: break; case 8: me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - return 9000; + return 2500; + break; + case 9: + // missing text "Lord Illidan, this is the Dragonmaw that I, and others, have told you about. He will lead us to victory!" + return 5000; break; case 10: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); return 5000; break; case 11: @@ -821,42 +834,53 @@ public: return 6000; break; case 12: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); return 5500; break; case 13: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); return 4000; break; case 14: - Illi->SetTarget(PlayerGUID); + if (Illi) + Illi->SetTarget(PlayerGUID); return 1500; break; case 15: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); return 1500; break; case 16: - Illi->CastSpell(player, SPELL_TWO, true); + if (Illi) + Illi->CastSpell(player, SPELL_TWO, true); player->RemoveAurasDueToSpell(SPELL_THREE); player->RemoveAurasDueToSpell(SPELL_FOUR); return 5000; break; case 17: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); return 5000; break; case 18: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); return 5000; break; case 19: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); + if (Illi) + Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); return 5000; break; case 20: - Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Illi->SetDisableGravity(true); + if (Illi) + { + Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Illi->SetDisableGravity(true); + } return 500; break; case 21: @@ -864,8 +888,11 @@ public: return 500; break; case 22: - Illi->SetVisible(false); - Illi->setDeathState(JUST_DIED); + if (Illi) + { + Illi->SetVisible(false); + Illi->setDeathState(JUST_DIED); + } return 1000; break; case 23: @@ -886,7 +913,7 @@ public: break; case 27: { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f); if (Yarzill) Yarzill->SetTarget(PlayerGUID); return 500; @@ -921,9 +948,11 @@ public: } break; case 32: - me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; + me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); + return 5000; break; case 33: + me->SetTarget(0); Reset(); return 100; break; @@ -940,7 +969,7 @@ public: if (ConversationTimer <= diff) { - if (Event && IllidanGUID && PlayerGUID) + if (Event && PlayerGUID) ConversationTimer = NextStep(++Step); } else ConversationTimer -= diff; } -- cgit v1.2.3 From 18f5de77c3efb73a781e40a81d3a1438bc1f1b11 Mon Sep 17 00:00:00 2001 From: Nay Date: Sat, 26 Jan 2013 17:48:47 +0000 Subject: Core/GossipDef: Fix a build error from 9812afe08be *slaps MrSmite* --- src/server/game/Entities/Creature/GossipDef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index a26e84a5311..a2305a8a56d 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -720,7 +720,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); } -static void PlayerMenu::AddQuestLevelToTitle(std::string &title, int32 level) +void PlayerMenu::AddQuestLevelToTitle(std::string &title, int32 level) { // Adds the quest level to the front of the quest title // example: [13] Westfall Stew -- cgit v1.2.3 From 480c8471566c36081ea5602380408363dde307c1 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 26 Jan 2013 19:48:54 +0100 Subject: Core: Some cosmetic changes --- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Scripting/ScriptLoader.cpp | 4 ++-- src/server/scripts/Spells/spell_hunter.cpp | 8 ++++---- src/server/scripts/Spells/spell_priest.cpp | 12 ++++++------ src/server/scripts/Spells/spell_shaman.cpp | 6 +++--- src/server/scripts/Spells/spell_warlock.cpp | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 66162142fdc..82a1164b423 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14291,7 +14291,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool VendorItemData const* vendorItems = creature->GetVendorItems(); if (!vendorItems || vendorItems->Empty()) { - sLog->outError(LOG_FILTER_SQL, "Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", creature->GetGUIDLow(), creature->GetEntry()); + sLog->outError(LOG_FILTER_SQL, "Creature (GUID: %u, Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", creature->GetGUIDLow(), creature->GetEntry()); canTalk = false; } break; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 3da9ac8fade..efd45188d42 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -66,6 +66,7 @@ void AddSC_list_commandscript(); void AddSC_lookup_commandscript(); void AddSC_message_commandscript(); void AddSC_misc_commandscript(); +void AddSC_mmaps_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); @@ -76,7 +77,6 @@ void AddSC_tele_commandscript(); void AddSC_ticket_commandscript(); void AddSC_titles_commandscript(); void AddSC_wp_commandscript(); -void AddSC_mmaps_commandscript(); #ifdef SCRIPTS //world @@ -696,6 +696,7 @@ void AddCommandScripts() AddSC_list_commandscript(); AddSC_message_commandscript(); AddSC_misc_commandscript(); + AddSC_mmaps_commandscript(); AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); @@ -706,7 +707,6 @@ void AddCommandScripts() AddSC_ticket_commandscript(); AddSC_titles_commandscript(); AddSC_wp_commandscript(); - AddSC_mmaps_commandscript(); } void AddWorldScripts() diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 877248cf1a8..891a7daaa1f 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -38,7 +38,7 @@ enum HunterSpells SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359, - SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER = 56851, + SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER = 56851, SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398, SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, SPELL_HUNTER_MISDIRECTION_PROC = 35079, @@ -116,7 +116,7 @@ class spell_hun_ascpect_of_the_viper : public SpellScriptLoader { if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE)) return false; - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER)) return false; return true; } @@ -128,8 +128,8 @@ class spell_hun_ascpect_of_the_viper : public SpellScriptLoader uint32 maxMana = GetTarget()->GetMaxPower(POWER_MANA); int32 mana = CalculatePct(maxMana, GetTarget()->GetAttackTime(RANGED_ATTACK) / 1000.0f); - if (AuraEffect const* glyphe = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPHE_OF_ASPECT_OF_THE_VIPER, EFFECT_0)) - AddPct(mana, glyphe->GetAmount()); + if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER, EFFECT_0)) + AddPct(mana, glyph->GetAmount()); GetTarget()->CastCustomSpell(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index e19110d0f62..4e86a895484 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -31,8 +31,8 @@ enum PriestSpells { SPELL_PRIEST_DIVINE_AEGIS = 47753, SPELL_PRIEST_EMPOWERED_RENEW = 63544, - SPELL_PRIEST_GLYPHE_OF_LIGHTWELL = 55673, - SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL = 56161, + SPELL_PRIEST_GLYPH_OF_LIGHTWELL = 55673, + SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL = 56161, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, SPELL_PRIEST_MANA_LEECH_PROC = 34650, SPELL_PRIEST_PENANCE_R1 = 47540, @@ -114,7 +114,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL)) return false; return true; } @@ -123,9 +123,9 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader { PreventDefaultAction(); - SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL); + SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL); int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks()); - GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPHE_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); + GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff); } void Register() @@ -212,7 +212,7 @@ class spell_pri_lightwell_renew : public SpellScriptLoader if (Unit* caster = GetCaster()) { // Bonus from Glyph of Lightwell - if (AuraEffect* modHealing = caster->GetAuraEffect(SPELL_PRIEST_GLYPHE_OF_LIGHTWELL, EFFECT_0)) + if (AuraEffect* modHealing = caster->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_LIGHTWELL, EFFECT_0)) AddPct(amount, modHealing->GetAmount()); } } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index b69295150c2..f970807bb94 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -296,9 +296,9 @@ class spell_sha_earth_shield : public SpellScriptLoader // Glyph of Earth Shield //! WORKAROUND - //! this glyphe is a proc - if (AuraEffect* glyphe = caster->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD, EFFECT_0)) - AddPct(amount, glyphe->GetAmount()); + //! this glyph is a proc + if (AuraEffect* glyph = caster->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD, EFFECT_0)) + AddPct(amount, glyph->GetAmount()); } } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 78bfcbab6a0..a9a4b2d749a 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -38,7 +38,7 @@ enum WarlockSpells SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, - SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE = 63106, + SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, @@ -746,7 +746,7 @@ class spell_warl_siphon_life : public SpellScriptLoader { if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SIPHON_LIFE_HEAL)) return false; - if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE)) + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE)) return false; return true; } @@ -762,8 +762,8 @@ class spell_warl_siphon_life : public SpellScriptLoader int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())); // Glyph of Siphon Life - if (AuraEffect const* glyphe = GetTarget()->GetAuraEffect(SPELL_WARLOCK_GLYPHE_OF_SIPHON_LIFE, EFFECT_0)) - AddPct(amount, glyphe->GetAmount()); + if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE, EFFECT_0)) + AddPct(amount, glyph->GetAmount()); GetTarget()->CastCustomSpell(SPELL_WARLOCK_SIPHON_LIFE_HEAL, SPELLVALUE_BASE_POINT0, amount, GetTarget(), true, NULL, aurEff); } -- cgit v1.2.3 From ceed5ea42f046b0b91e41f877bc53b6436e04a69 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 26 Jan 2013 19:57:11 +0100 Subject: Scripts/Icecrown Citadel: Fix warning --- .../scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index d688205938a..af727348719 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -415,7 +415,7 @@ class boss_deathbringer_saurfang : public CreatureScript } } - void SpellHit(Unit* caster, SpellInfo const* spell) + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) { if (spell->Id == SPELL_BLOOD_LINK_POWER) if (Aura* bloodPower = me->GetAura(SPELL_BLOOD_POWER)) -- cgit v1.2.3 From 1b551cc157a3324e0523abca55138fd7af10b2ca Mon Sep 17 00:00:00 2001 From: Nay Date: Sat, 26 Jan 2013 21:31:48 +0000 Subject: Scripts/Commands: Add guild info to .pinfo Original patch by @secharles, modified Closes #8946 --- .../world/2013_01_26_05_world_misc_pinfo.sql | 5 +++++ src/server/game/Miscellaneous/Language.h | 1 + src/server/scripts/Commands/cs_misc.cpp | 23 ++++++++++++++++++++++ .../Database/Implementation/CharacterDatabase.cpp | 1 + .../Database/Implementation/CharacterDatabase.h | 1 + 5 files changed, 31 insertions(+) create mode 100644 sql/updates/world/2013_01_26_05_world_misc_pinfo.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_26_05_world_misc_pinfo.sql b/sql/updates/world/2013_01_26_05_world_misc_pinfo.sql new file mode 100644 index 00000000000..2c0a28066d4 --- /dev/null +++ b/sql/updates/world/2013_01_26_05_world_misc_pinfo.sql @@ -0,0 +1,5 @@ +DELETE FROM `trinity_string` WHERE `entry`=749; +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES +(749, 'Guild: %s (%u) Rank: %s Note: %s OffNote: %s'); + +UPDATE `command` SET `help`='Syntax: .pinfo [$player_name/#GUID]\r\n\r\nOutput account information and guild information for selected player or player find by $player_name or #GUID.' WHERE `name`='pinfo'; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 8b416339bc7..e13cc86747c 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -522,6 +522,7 @@ enum TrinityStrings LANG_PINFO_BAN = 453, LANG_PINFO_MAP_ONLINE = 714, LANG_PINFO_MAP_OFFLINE = 716, + LANG_PINFO_GUILD_INFO = 749, LANG_YOU_SET_EXPLORE_ALL = 551, LANG_YOU_SET_EXPLORE_NOTHING = 552, diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 3196e81a951..367591080d2 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1734,6 +1734,29 @@ public: else handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + + result = CharacterDatabase.Query(stmt); + if (result) + { + uint32 guildId = 0; + std::string guildName = ""; + std::string guildRank = ""; + std::string note = ""; + std::string officeNote = ""; + + Field* fields = result->Fetch(); + guildId = fields[0].GetUInt32(); + guildName = fields[1].GetString(); + //rankId = fields[2].GetUInt8(); + guildRank = fields[3].GetString(); + note = fields[4].GetString(); + officeNote = fields[5].GetString(); + + handler->PSendSysMessage(LANG_PINFO_GUILD_INFO, guildName.c_str(), guildId, guildRank.c_str(), note.c_str(), officeNote.c_str()); + } + return true; } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 1c2410b8b53..b3d818c7565 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -101,6 +101,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH); + PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gm.rank, gr.rname, gm.pnote, gm.offnote FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid JOIN guild_rank gr ON g.guildid = gr.guildid WHERE gm.guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, " diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index e4728e19934..7c064a98e17 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -105,6 +105,7 @@ enum CharacterDatabaseStatements CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, CHAR_SEL_CHARACTER_DECLINEDNAMES, CHAR_SEL_GUILD_MEMBER, + CHAR_SEL_GUILD_MEMBER_EXTENDED, CHAR_SEL_CHARACTER_ARENAINFO, CHAR_SEL_CHARACTER_ACHIEVEMENTS, CHAR_SEL_CHARACTER_CRITERIAPROGRESS, -- cgit v1.2.3 From e1d12de2b14534e35916e58afbe4e7016f0b6ff7 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 27 Jan 2013 11:56:56 +0100 Subject: Core/Battlegrounds: Fixed arena scoreboards not showing all players. --- src/server/game/Battlegrounds/BattlegroundMgr.cpp | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 24e69a151b5..6133bd60258 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -589,6 +589,27 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original bg->SetRated(isRated); bg->SetRandom(isRandom); + // Set up correct min/max player counts for scoreboards + if (bg->isArena()) + { + uint32 maxPlayersPerTeam = 0; + switch (arenaType) + { + case ARENA_TYPE_2v2: + maxPlayersPerTeam = 2; + break; + case ARENA_TYPE_3v3: + maxPlayersPerTeam = 3; + break; + case ARENA_TYPE_5v5: + maxPlayersPerTeam = 5; + break; + } + + bg->SetMaxPlayersPerTeam(maxPlayersPerTeam); + bg->SetMaxPlayers(maxPlayersPerTeam * 2); + } + return bg; } @@ -649,8 +670,8 @@ bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data) bg->SetArenaorBGType(data.IsArena); bg->SetMinPlayersPerTeam(data.MinPlayersPerTeam); bg->SetMaxPlayersPerTeam(data.MaxPlayersPerTeam); - bg->SetMinPlayers(data.MinPlayersPerTeam* 2); - bg->SetMaxPlayers(data.MaxPlayersPerTeam* 2); + bg->SetMinPlayers(data.MinPlayersPerTeam * 2); + bg->SetMaxPlayers(data.MaxPlayersPerTeam * 2); bg->SetName(data.BattlegroundName); bg->SetTeamStartLoc(ALLIANCE, data.Team1StartLocX, data.Team1StartLocY, data.Team1StartLocZ, data.Team1StartLocO); bg->SetTeamStartLoc(HORDE, data.Team2StartLocX, data.Team2StartLocY, data.Team2StartLocZ, data.Team2StartLocO); -- cgit v1.2.3 From 6e80357f8e8b4e820bab8bd05fb8457c3cb46d11 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 27 Jan 2013 17:33:01 +0100 Subject: Core/Authserver: Added possibility to allow realm connections both from "world" and local networks. --- sql/base/auth_database.sql | 2 ++ sql/updates/auth/2013_01_27_00_auth_realmlist.sql | 3 ++ src/server/authserver/Realms/RealmList.cpp | 42 ++++++++++++---------- src/server/authserver/Realms/RealmList.h | 6 ++-- src/server/authserver/Server/AuthSocket.cpp | 30 +++++++++++++++- src/server/authserver/Server/AuthSocket.h | 5 +++ .../Database/Implementation/LoginDatabase.cpp | 2 +- src/server/shared/Utilities/Util.cpp | 16 ++++++++- src/server/shared/Utilities/Util.h | 8 +++++ 9 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 sql/updates/auth/2013_01_27_00_auth_realmlist.sql (limited to 'src') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index a052a74c837..5050906b008 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -193,6 +193,8 @@ CREATE TABLE `realmlist` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL DEFAULT '', `address` varchar(255) NOT NULL DEFAULT '127.0.0.1', + `localAddress` varchar(255) NOT NULL DEFAULT '127.0.0.1', + `localSubnetMask` varchar(255) NOT NULL DEFAULT '255.255.255.0', `port` smallint(5) unsigned NOT NULL DEFAULT '8085', `icon` tinyint(3) unsigned NOT NULL DEFAULT '0', `flag` tinyint(3) unsigned NOT NULL DEFAULT '2', diff --git a/sql/updates/auth/2013_01_27_00_auth_realmlist.sql b/sql/updates/auth/2013_01_27_00_auth_realmlist.sql new file mode 100644 index 00000000000..0c3b18448e6 --- /dev/null +++ b/sql/updates/auth/2013_01_27_00_auth_realmlist.sql @@ -0,0 +1,3 @@ +ALTER TABLE `realmlist` + ADD `localAddress` varchar(255) NOT NULL DEFAULT '127.0.0.1' AFTER `address`, + ADD `localSubnetMask` varchar(255) NOT NULL DEFAULT '255.255.255.0' AFTER `localAddress`; diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 72873e40ce5..b4becc96451 100644 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -31,12 +31,12 @@ void RealmList::Initialize(uint32 updateInterval) UpdateRealms(true); } -void RealmList::UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr const& address, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) +void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) { // Create new if not exist or update existed Realm& realm = m_realms[name]; - realm.m_ID = ID; + realm.m_ID = id; realm.name = name; realm.icon = icon; realm.flag = flag; @@ -45,7 +45,9 @@ void RealmList::UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr co realm.populationLevel = popu; // Append port to IP address. - address.addr_to_string(realm.address, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16); + realm.ExternalAddress = address; + realm.LocalAddress = localAddr; + realm.LocalSubnetMask = localSubmask; realm.gamebuild = build; } @@ -77,23 +79,27 @@ void RealmList::UpdateRealms(bool init) do { Field* fields = result->Fetch(); - uint32 realmId = fields[0].GetUInt32(); - std::string name = fields[1].GetString(); - std::string address = fields[2].GetString(); - uint16 port = fields[3].GetUInt16(); - uint8 icon = fields[4].GetUInt8(); - RealmFlags flag = RealmFlags(fields[5].GetUInt8()); - uint8 timezone = fields[6].GetUInt8(); - uint8 allowedSecurityLevel = fields[7].GetUInt8(); - float pop = fields[8].GetFloat(); - uint32 build = fields[9].GetUInt32(); - - ACE_INET_Addr addr(port, address.c_str(), AF_INET); - - UpdateRealm(realmId, name, addr, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); + uint32 realmId = fields[0].GetUInt32(); + std::string name = fields[1].GetString(); + std::string externalAddress = fields[2].GetString(); + std::string localAddress = fields[3].GetString(); + std::string localSubmask = fields[4].GetString(); + uint16 port = fields[5].GetUInt16(); + uint8 icon = fields[6].GetUInt8(); + RealmFlags flag = RealmFlags(fields[7].GetUInt8()); + uint8 timezone = fields[8].GetUInt8(); + uint8 allowedSecurityLevel = fields[9].GetUInt8(); + float pop = fields[10].GetFloat(); + uint32 build = fields[11].GetUInt32(); + + ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET); + ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET); + ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET); + + UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) - sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\" at %s.", name.c_str(), m_realms[name].address); + sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port); } while (result->NextRow()); } diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h index 1949c34df9a..68e6524c334 100644 --- a/src/server/authserver/Realms/RealmList.h +++ b/src/server/authserver/Realms/RealmList.h @@ -40,7 +40,9 @@ enum RealmFlags // Storage object for a realm struct Realm { - char address[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16]; + ACE_INET_Addr ExternalAddress; + ACE_INET_Addr LocalAddress; + ACE_INET_Addr LocalSubnetMask; std::string name; uint8 icon; RealmFlags flag; @@ -72,7 +74,7 @@ public: private: void UpdateRealms(bool init=false); - void UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr const& address, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); + void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); RealmMap m_realms; uint32 m_UpdateInterval; diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index 8ab4ab8a1a2..b0bce520d4f 100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -818,6 +818,28 @@ bool AuthSocket::_HandleReconnectProof() } } +ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr) +{ + // Attempt to send best address for client + if (clientAddr.is_loopback()) + { + // Try guessing if realm is also connected locally + if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback()) + return clientAddr; + + // Assume that user connecting from the machine that authserver is located on + // has all realms available in his local network + return realm.LocalAddress; + } + + // Check if connecting client is in the same network + if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask)) + return realm.LocalAddress; + + // Return external IP + return realm.ExternalAddress; +} + // Realm List command handler bool AuthSocket::_HandleRealmList() { @@ -845,6 +867,9 @@ bool AuthSocket::_HandleRealmList() // Update realm list if need sRealmList->UpdateIfNeed(); + ACE_INET_Addr clientAddr; + socket().peer().get_remote_addr(clientAddr); + // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; @@ -876,6 +901,9 @@ bool AuthSocket::_HandleRealmList() name = ss.str(); } + // We don't need the port number from which client connects with but the realm's port + clientAddr.set_port_number(i->second.ExternalAddress.get_port_number()); + uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; uint8 AmountOfCharacters = 0; @@ -891,7 +919,7 @@ bool AuthSocket::_HandleRealmList() pkt << lock; // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; - pkt << i->second.address; + pkt << GetAddressString(GetAddressForClient(i->second, clientAddr)); pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index 87fd092381e..6c13f85a022 100644 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -23,6 +23,9 @@ #include "BigNumber.h" #include "RealmSocket.h" +class ACE_INET_Addr; +struct Realm; + // Handle login commands class AuthSocket: public RealmSocket::Session { @@ -36,6 +39,8 @@ public: virtual void OnAccept(void); virtual void OnClose(void); + static ACE_INET_Addr const& GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr); + bool _HandleLogonChallenge(); bool _HandleLogonProof(); bool _HandleReconnectChallenge(); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 70d509af6fe..3fc6649bd4d 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -22,7 +22,7 @@ void LoginDatabaseConnection::DoPrepareStatements() if (!m_reconnecting) m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS); - PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index 0d9314c48a3..1bba3c2db09 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -22,7 +22,6 @@ #include "SFMT.h" #include "Errors.h" // for ASSERT #include -#include typedef ACE_TSS SFMTRandTSS; static SFMTRandTSS sfmtRand; @@ -239,6 +238,21 @@ bool IsIPAddress(char const* ipaddress) return inet_addr(ipaddress) != INADDR_NONE; } +std::string GetAddressString(ACE_INET_Addr const& addr) +{ + char buf[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16]; + addr.addr_to_string(buf, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16); + return buf; +} + +bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask) +{ + uint32 mask = subnetMask.get_ip_address(); + if ((net.get_ip_address() & mask) == (addr.get_ip_address() & mask)) + return true; + return false; +} + /// create PID file uint32 CreatePIDFile(const std::string& filename) { diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index e7218d7ba72..a379bfd32fc 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -25,6 +25,7 @@ #include #include #include +#include // Searcher for map of structs template struct Finder @@ -343,6 +344,13 @@ void utf8printf(FILE* out, const char *str, ...); void vutf8printf(FILE* out, const char *str, va_list* ap); bool IsIPAddress(char const* ipaddress); + +/// Checks if address belongs to the a network with specified submask +bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask); + +/// Transforms ACE_INET_Addr address into string format "dotted_ip:port" +std::string GetAddressString(ACE_INET_Addr const& addr); + uint32 CreatePIDFile(const std::string& filename); std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); -- cgit v1.2.3 From 98f01c2b12e6a2aeef8b2f9810e5a3cce9d5e475 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 28 Jan 2013 02:54:27 +0000 Subject: Core/Misc: Fix compile errors introduced in previous merge There are probably other merge issues that got through, please report them --- src/server/game/Battlegrounds/Battleground.cpp | 6 ++- src/server/game/Handlers/BattleGroundHandler.cpp | 4 +- .../MovementGenerators/RandomMovementGenerator.cpp | 2 +- src/server/game/Movement/Spline/MoveSplineInit.cpp | 57 +++++++++++----------- .../scripts/Kalimdor/Firelands/boss_alysrazor.cpp | 2 +- src/server/scripts/Spells/spell_mage.cpp | 6 +-- src/server/scripts/Spells/spell_priest.cpp | 3 +- src/server/scripts/Spells/spell_warlock.cpp | 46 +++++++++++++---- src/server/scripts/Spells/spell_warrior.cpp | 41 ---------------- src/tools/CMakeLists.txt | 2 +- src/tools/map_extractor/System.cpp | 2 +- 11 files changed, 81 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index e2ae9f50452..445d1295629 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -973,7 +973,7 @@ void Battleground::EndBattleground(uint32 winner) player->GetSession()->SendPacket(&pvpLogData); WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); player->GetSession()->SendPacket(&data); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); @@ -1204,9 +1204,13 @@ void Battleground::AddPlayer(Player* player) sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player->GetGUID()); SendPacketToTeam(team, &data, player, false); + // BG Status packet + BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); + uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, queueSlot, STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(m_TypeID), GetElapsedTime(), GetArenaType()); player->GetSession()->SendPacket(&data); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); // add arena specific auras diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index d28b67106c4..9955879d37a 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -538,7 +538,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->CleanupAfterTaxiFlight(); } - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr @@ -622,7 +622,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // this line is checked, i only don't know if GetElapsedTime() is changing itself after bg end! // send status in Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), arenaType); SendPacket(&data); continue; } diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 67136792fa6..723b0748494 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -165,7 +165,7 @@ bool RandomMovementGenerator::GetResetPos(Creature* creature, float& x creature->GetRespawnPosition(x, y, z, NULL, &radius); // use current if in range - if (creature.IsWithinDist2d(x, y, radius)) + if (creature->IsWithinDist2d(x, y, radius)) creature->GetPosition(x, y, z); return true; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index a8ae40926b8..f7d876d7aa3 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -60,23 +60,22 @@ namespace Movement int32 MoveSplineInit::Launch() { - MoveSpline& move_spline = *unit.movespline; + MoveSpline& move_spline = *unit->movespline; - Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); + Location real_position(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZMinusOffset(), unit->GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) + if (unit->GetTransGUID()) { - transport = true; - real_position.x = unit.GetTransOffsetX(); - real_position.y = unit.GetTransOffsetY(); - real_position.z = unit.GetTransOffsetZ(); - real_position.orientation = unit.GetTransOffsetO(); + real_position.x = unit->GetTransOffsetX(); + real_position.y = unit->GetTransOffsetY(); + real_position.z = unit->GetTransOffsetZ(); + real_position.orientation = unit->GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it - // this also allows CalculatePath spline position and update map position in much greater intervals + // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports - if (!move_spline.Finalized() && move_spline.onTransport == (unit.GetTransGUID() != 0)) + if (!move_spline.Finalized() && move_spline.onTransport == (unit->GetTransGUID() != 0)) real_position = move_spline.ComputePosition(); // should i do the things that user should do? - no. @@ -86,7 +85,7 @@ namespace Movement // correct first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; - move_spline.onTransport = (unit.GetTransGUID() != 0); + move_spline.onTransport = (unit->GetTransGUID() != 0); uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) @@ -105,27 +104,27 @@ namespace Movement if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; - unit.m_movementInfo.SetMovementFlags(moveFlags); + unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data.append(unit->GetPackGUID()); - if (unit.GetTransGUID()) + if (unit->GetTransGUID()) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data.appendPackGUID(unit.GetTransGUID()); - data << int8(unit.GetTransSeat()); + data.appendPackGUID(unit->GetTransGUID()); + data << int8(unit->GetTransSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); - unit->SendMessageToSet(&data,true); - + unit->SendMessageToSet(&data, true); + return move_spline.Duration(); } void MoveSplineInit::Stop() { - MoveSpline& move_spline = *unit.movespline; + MoveSpline& move_spline = *unit->movespline; // No need to stop if we are not moving if (move_spline.Finalized()) @@ -133,30 +132,30 @@ namespace Movement Location loc = move_spline.ComputePosition(); args.flags = MoveSplineFlag::Done; - unit.m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD); + unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); - data.append(unit.GetPackGUID()); - if (unit.GetTransGUID()) + data.append(unit->GetPackGUID()); + if (unit->GetTransGUID()) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - data.appendPackGUID(unit.GetTransGUID()); - data << int8(unit.GetTransSeat()); + data.appendPackGUID(unit->GetTransGUID()); + data << int8(unit->GetTransSeat()); } PacketBuilder::WriteStopMovement(loc, args.splineId, data); - unit.SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } - MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) + MoveSplineInit::MoveSplineInit(Unit* m) : unit(m) { args.splineId = splineIdGen.NewId(); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); + args.TransformForTransport = unit->GetTransGUID(); // mix existing state into new - args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); - args.flags.flying = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY); + args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); + args.flags.flying = unit->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); args.flags.smoothGroundPath = true; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this } @@ -202,7 +201,7 @@ namespace Movement void MoveSplineInit::SetFall() { args.flags.EnableFalling(); - args.flags.fallingSlow = unit.HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); + args.flags.fallingSlow = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW); } Vector3 TransportPathTransform::operator()(Vector3 input) diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp index 1dc70c5e505..b7816242afc 100644 --- a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp +++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp @@ -298,7 +298,7 @@ class npc_blazing_monstrosity : public CreatureScript passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Hack to relocate vehicle on vehicle so exiting players are not moved under map - Movement::MoveSplineInit init(*passenger); + Movement::MoveSplineInit init(passenger); init.DisableTransportPathTransformations(); init.MoveTo(0.6654003f, 0.0f, 1.9815f); init.SetFacing(0.0f); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index e14327b0f36..7bd1753116b 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -688,7 +688,7 @@ class spell_mage_mage_ward : public SpellScriptLoader if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) { int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); - GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_TRIGGERED, &bp, NULL, NULL, true); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); } } @@ -720,14 +720,14 @@ class spell_mage_mana_shield : public SpellScriptLoader if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0)) { int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount()); - GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_TRIGGERED, &bp, NULL, NULL, true); + GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true); } } void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) - GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTER_S_ABSORPTION_KNOCKBACK, true); + GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_R1, true); } void Register() diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 94b12818626..c2bfc913893 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -54,8 +54,9 @@ enum PriestSpells enum PriestSpellIcons { + PRIEST_ICON_ID_BORROWED_TIME = 2899, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, - PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874 + PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, }; // -47509 - Divine Aegis diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 31833524861..df415a7bb08 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -29,28 +29,29 @@ enum WarlockSpells { SPELL_WARLOCK_BANE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, + SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, SPELL_WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018, SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020, - SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, - SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, + SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, + SPELL_WARLOCK_HAUNT = 48181, + SPELL_WARLOCK_HAUNT_HEAL = 48210, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, - SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, - SPELL_WARLOCK_HAUNT = 48181, - SPELL_WARLOCK_HAUNT_HEAL = 48210, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, + SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, - SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, + SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -647,6 +648,34 @@ class spell_warl_life_tap : public SpellScriptLoader } }; +// 18541 - Ritual of Doom Effect +class spell_warl_ritual_of_doom_effect : public SpellScriptLoader +{ + public: + spell_warl_ritual_of_doom_effect() : SpellScriptLoader("spell_warl_ritual_of_doom_effect") { } + + class spell_warl_ritual_of_doom_effect_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_ritual_of_doom_effect_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, GetEffectValue(), true); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_ritual_of_doom_effect_SpellScript(); + } +}; + // 27285 - Seed of Corruption /// Updated 4.3.4 class spell_warl_seed_of_corruption : public SpellScriptLoader @@ -846,7 +875,6 @@ void AddSC_warlock_spell_scripts() new spell_warl_bane_of_doom(); new spell_warl_banish(); new spell_warl_create_healthstone(); - new spell_warl_curse_of_doom(); new spell_warl_demonic_circle_summon(); new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index c155c39ffdb..9e2cb8aad71 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -31,7 +31,6 @@ enum WarriorSpells SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, SPELL_WARRIOR_CHARGE = 34846, - SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162, SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850, SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868, @@ -43,7 +42,6 @@ enum WarriorSpells SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976, SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, SPELL_WARRIOR_SLAM = 50782, - SPELL_WARRIOR_SLAM = 50783, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654, SPELL_WARRIOR_TAUNT = 355, SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859, @@ -201,44 +199,6 @@ class spell_warr_concussion_blow : public SpellScriptLoader } }; -// -58872 - Damage Shield -class spell_warr_damage_shield : public SpellScriptLoader -{ - public: - spell_warr_damage_shield() : SpellScriptLoader("spell_warr_damage_shield") { } - - class spell_warr_damage_shield_AuraScript : public AuraScript - { - PrepareAuraScript(spell_warr_damage_shield_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE)) - return false; - return true; - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // % of amount blocked - int32 damage = CalculatePct(int32(GetTarget()->GetShieldBlockValue()), aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff); - } - - void Register() - { - OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_warr_damage_shield_AuraScript(); - } -}; - /// Updated 4.3.4 class spell_warr_deep_wounds : public SpellScriptLoader { @@ -770,7 +730,6 @@ void AddSC_warrior_spell_scripts() new spell_warr_bloodthirst_heal(); new spell_warr_charge(); new spell_warr_concussion_blow(); - new spell_warr_damage_shield(); new spell_warr_deep_wounds(); new spell_warr_execute(); new spell_warr_improved_spell_reflection(); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 49c17913c64..671de25dfd3 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -12,4 +12,4 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) add_subdirectory(mmaps_generator) -add_subdirectory(mesh_extractor) +# add_subdirectory(mesh_extractor) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 800328810a7..7b591ddfc85 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -901,7 +901,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, { for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) { - adt_MCNK * cell = cells->getMCNK(i,j); + adt_MCNK * cell = adt.cells[i][j]; if (!cell) continue; holes[i][j] = cell->holes; -- cgit v1.2.3 From 112c2a8dd0b1186fab878dcd2da8f666ae2fcdf8 Mon Sep 17 00:00:00 2001 From: Nay Date: Mon, 28 Jan 2013 12:53:51 +0000 Subject: Core/Misc: Fix a merge failure in SpellAuraEffects.cpp Thanks Tuxity and Vincent --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index ac7f0348b84..ef0587feb53 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -538,12 +538,6 @@ int32 AuraEffect::CalculateAmount(Unit* caster) case SPELL_AURA_SCHOOL_ABSORB: case SPELL_AURA_MANA_SHIELD: m_canBeRecalculated = false; - case 57669: // Replenishment (0.2% from max) - amount = CalculatePct(GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA), amount); - break; - case 61782: // Infinite Replenishment - amount = GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA) * 0.0025f; - break; break; case SPELL_AURA_MOUNTED: if (MountCapabilityEntry const* mountCapability = GetBase()->GetUnitOwner()->GetMountCapability(uint32(GetMiscValueB()))) -- cgit v1.2.3 From 29cd1dbec17c25745a53a6e7419e63ac411b81ab Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 28 Jan 2013 19:50:01 +0100 Subject: Core/Quest: Bloody Breakout Closes #641 --- .../EasternKingdoms/ScarletEnclave/chapter2.cpp | 77 +++++++++++----------- 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp index 6985ad2c4ad..a4c11209e52 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp @@ -160,7 +160,7 @@ public: ## npc_koltira_deathweaver ######*/ -enum eKoltira +enum Koltira { SAY_BREAKOUT1 = 0, SAY_BREAKOUT2 = 1, @@ -180,10 +180,9 @@ enum eKoltira NPC_CRIMSON_ACOLYTE = 29007, NPC_HIGH_INQUISITOR_VALROTH = 29001, - NPC_KOLTIRA_ALT = 28447, //not sure about this id - //NPC_DEATH_KNIGHT_MOUNT = 29201, + //NPC_DEATH_KNIGHT_MOUNT = 29201, MODEL_DEATH_KNIGHT_MOUNT = 25278 }; @@ -198,17 +197,12 @@ public: { creature->SetStandState(UNIT_STAND_STATE_STAND); - if (npc_escortAI* pEscortAI = CAST_AI(npc_koltira_deathweaver::npc_koltira_deathweaverAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID()); + if (npc_escortAI* escortAI = CAST_AI(npc_koltira_deathweaver::npc_koltira_deathweaverAI, creature->AI())) + escortAI->Start(false, false, player->GetGUID()); } return true; } - CreatureAI* GetAI(Creature* creature) const - { - return new npc_koltira_deathweaverAI(creature); - } - struct npc_koltira_deathweaverAI : public npc_escortAI { npc_koltira_deathweaverAI(Creature* creature) : npc_escortAI(creature) @@ -216,20 +210,17 @@ public: me->SetReactState(REACT_DEFENSIVE); } - uint32 m_uiWave; - uint32 m_uiWave_Timer; - uint64 m_uiValrothGUID; - void Reset() { if (!HasEscortState(STATE_ESCORT_ESCORTING)) { - m_uiWave = 0; - m_uiWave_Timer = 3000; - m_uiValrothGUID = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + wave = 0; + waveTimer = 3000; + valrothGUID = 0; me->LoadEquipment(0, true); - me->RemoveAura(SPELL_ANTI_MAGIC_ZONE); + me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE); + me->RemoveAurasDueToSpell(SPELL_KOLTIRA_TRANSFORM); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } @@ -239,22 +230,21 @@ public: { case 0: Talk(SAY_BREAKOUT1); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); break; case 1: me->SetStandState(UNIT_STAND_STATE_KNEEL); break; case 2: me->SetStandState(UNIT_STAND_STATE_STAND); - //me->UpdateEntry(NPC_KOLTIRA_ALT); //unclear if we must update or not DoCast(me, SPELL_KOLTIRA_TRANSFORM); me->LoadEquipment(me->GetEquipmentId()); break; case 3: SetEscortPaused(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetStandState(UNIT_STAND_STATE_KNEEL); Talk(SAY_BREAKOUT2); - DoCast(me, SPELL_ANTI_MAGIC_ZONE); // cast again that makes bubble up + DoCast(me, SPELL_ANTI_MAGIC_ZONE); break; case 4: SetRun(true); @@ -274,9 +264,8 @@ public: summoned->AI()->AttackStart(player); if (summoned->GetEntry() == NPC_HIGH_INQUISITOR_VALROTH) - m_uiValrothGUID = summoned->GetGUID(); + valrothGUID = summoned->GetGUID(); - summoned->AddThreat(me, 0.0f); summoned->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); } @@ -292,51 +281,51 @@ public: if (HasEscortState(STATE_ESCORT_PAUSED)) { - if (m_uiWave_Timer <= uiDiff) + if (waveTimer <= uiDiff) { - switch (m_uiWave) + switch (wave) { case 0: Talk(SAY_BREAKOUT3); SummonAcolyte(3); - m_uiWave_Timer = 20000; + waveTimer = 20000; break; case 1: Talk(SAY_BREAKOUT4); SummonAcolyte(3); - m_uiWave_Timer = 20000; + waveTimer = 20000; break; case 2: Talk(SAY_BREAKOUT5); SummonAcolyte(4); - m_uiWave_Timer = 20000; + waveTimer = 20000; break; case 3: Talk(SAY_BREAKOUT6); me->SummonCreature(NPC_HIGH_INQUISITOR_VALROTH, 1642.329f, -6045.818f, 127.583f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); - m_uiWave_Timer = 1000; + waveTimer = 1000; break; case 4: { - Creature* temp = Unit::GetCreature(*me, m_uiValrothGUID); + Creature* temp = Unit::GetCreature(*me, valrothGUID); if (!temp || !temp->isAlive()) { Talk(SAY_BREAKOUT8); - m_uiWave_Timer = 5000; + waveTimer = 5000; } else { - m_uiWave_Timer = 2500; - return; //return, we don't want m_uiWave to increment now + waveTimer = 2500; + return; } break; } case 5: Talk(SAY_BREAKOUT9); me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE); - // i do not know why the armor will also be removed - m_uiWave_Timer = 2500; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + waveTimer = 2500; break; case 6: Talk(SAY_BREAKOUT10); @@ -344,14 +333,24 @@ public: break; } - ++m_uiWave; + ++wave; } else - m_uiWave_Timer -= uiDiff; + waveTimer -= uiDiff; } } - }; + + private: + uint8 wave; + uint32 waveTimer; + uint64 valrothGUID; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_koltira_deathweaverAI(creature); + } }; //Scarlet courier -- cgit v1.2.3 From 1b180e683e99078322a6f7a604a637cd6afe5b81 Mon Sep 17 00:00:00 2001 From: Nay Date: Tue, 29 Jan 2013 02:25:24 +0000 Subject: Core&DB/Trainers: Remove `trainer_spell` from `creature_template` since it is not longer necessary on Cata --- .../2013_01_29_00_world_creature_template_434.sql | 1 + src/server/game/Entities/Creature/Creature.cpp | 10 +-- src/server/game/Entities/Creature/Creature.h | 1 - src/server/game/Globals/ObjectMgr.cpp | 87 ++++++++++----------- src/server/scripts/Commands/cs_reload.cpp | 91 +++++++++++----------- .../Database/Implementation/WorldDatabase.cpp | 2 +- 6 files changed, 88 insertions(+), 104 deletions(-) create mode 100644 sql/updates/world/2013_01_29_00_world_creature_template_434.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_29_00_world_creature_template_434.sql b/sql/updates/world/2013_01_29_00_world_creature_template_434.sql new file mode 100644 index 00000000000..52954b2b9f5 --- /dev/null +++ b/sql/updates/world/2013_01_29_00_world_creature_template_434.sql @@ -0,0 +1 @@ +ALTER TABLE `creature_template` DROP `trainer_spell`; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a2bed013640..0157cdf9130 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -925,15 +925,7 @@ bool Creature::isCanTrainingOf(Player* player, bool msg) const } break; case TRAINER_TYPE_TRADESKILLS: - if (GetCreatureTemplate()->trainer_spell && !player->HasSpell(GetCreatureTemplate()->trainer_spell)) - { - if (msg) - { - player->PlayerTalkClass->ClearMenus(); - player->PlayerTalkClass->SendGossipMenu(11031, GetGUID()); - } - return false; - } + // There's no Blacksmith specialization on Cataclysm, conditions are not required for tradeskills break; default: return false; // checked and error output at creature_template loading diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 9ac5deb56f5..255014a7bbf 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -109,7 +109,6 @@ struct CreatureTemplate uint32 dynamicflags; uint32 family; // enum CreatureFamily values (optional) uint32 trainer_type; - uint32 trainer_spell; uint32 trainer_class; uint32 trainer_race; float minrangedmg; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 05d986e3f92..c4721f3cc09 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -390,15 +390,15 @@ void ObjectMgr::LoadCreatureTemplates() "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, " // 22 23 24 25 26 27 28 29 30 31 32 33 34 "speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " - // 35 36 37 38 39 40 41 42 43 44 - "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 45 46 47 48 49 50 51 52 53 54 55 + // 35 36 37 38 39 40 41 42 43 + "dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " + // 44 45 46 47 48 49 50 51 52 53 54 "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " - // 56 57 58 59 60 61 62 63 64 65 66 67 68 69 + // 55 56 59 60 61 62 63 64 65 66 67 68 69 70 "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 70 71 72 73 74 75 76 77 78 79 80 81 + // 71 72 73 74 75 76 77 78 79 80 81 82 "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 82 83 84 85 86 87 88 + // 83 84 85 86 87 88 89 " questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName " "FROM creature_template;"); @@ -459,48 +459,47 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.dynamicflags = fields[35].GetUInt32(); creatureTemplate.family = uint32(fields[36].GetUInt8()); creatureTemplate.trainer_type = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_spell = fields[38].GetUInt32(); - creatureTemplate.trainer_class = uint32(fields[39].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[40].GetUInt8()); - creatureTemplate.minrangedmg = fields[41].GetFloat(); - creatureTemplate.maxrangedmg = fields[42].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[43].GetUInt16()); - creatureTemplate.type = uint32(fields[44].GetUInt8()); - creatureTemplate.type_flags = fields[45].GetUInt32(); - creatureTemplate.type_flags2 = fields[46].GetUInt32(); - creatureTemplate.lootid = fields[47].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[48].GetUInt32(); - creatureTemplate.SkinLootId = fields[49].GetUInt32(); + creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); + creatureTemplate.minrangedmg = fields[40].GetFloat(); + creatureTemplate.maxrangedmg = fields[41].GetFloat(); + creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); + creatureTemplate.type = uint32(fields[43].GetUInt8()); + creatureTemplate.type_flags = fields[44].GetUInt32(); + creatureTemplate.type_flags2 = fields[45].GetUInt32(); + creatureTemplate.lootid = fields[46].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); + creatureTemplate.SkinLootId = fields[48].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[50 + i - 1].GetInt16(); + creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[56 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[64].GetUInt32(); - creatureTemplate.VehicleId = fields[65].GetUInt32(); - creatureTemplate.mingold = fields[66].GetUInt32(); - creatureTemplate.maxgold = fields[67].GetUInt32(); - creatureTemplate.AIName = fields[68].GetString(); - creatureTemplate.MovementType = uint32(fields[69].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[70].GetUInt8()); - creatureTemplate.HoverHeight = fields[71].GetFloat(); - creatureTemplate.ModHealth = fields[72].GetFloat(); - creatureTemplate.ModMana = fields[73].GetFloat(); - creatureTemplate.ModManaExtra = fields[74].GetFloat(); - creatureTemplate.ModArmor = fields[75].GetFloat(); - creatureTemplate.RacialLeader = fields[76].GetBool(); + creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); + creatureTemplate.VehicleId = fields[64].GetUInt32(); + creatureTemplate.mingold = fields[65].GetUInt32(); + creatureTemplate.maxgold = fields[66].GetUInt32(); + creatureTemplate.AIName = fields[67].GetString(); + creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); + creatureTemplate.HoverHeight = fields[70].GetFloat(); + creatureTemplate.ModHealth = fields[71].GetFloat(); + creatureTemplate.ModMana = fields[72].GetFloat(); + creatureTemplate.ModManaExtra = fields[73].GetFloat(); + creatureTemplate.ModArmor = fields[74].GetFloat(); + creatureTemplate.RacialLeader = fields[75].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[77 + i].GetUInt32(); + creatureTemplate.questItems[i] = fields[76 + i].GetUInt32(); - creatureTemplate.movementId = fields[83].GetUInt32(); - creatureTemplate.RegenHealth = fields[84].GetBool(); - creatureTemplate.equipmentId = fields[85].GetUInt32(); - creatureTemplate.MechanicImmuneMask = fields[86].GetUInt32(); - creatureTemplate.flags_extra = fields[87].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[88].GetCString()); + creatureTemplate.movementId = fields[82].GetUInt32(); + creatureTemplate.RegenHealth = fields[83].GetBool(); + creatureTemplate.equipmentId = fields[84].GetUInt32(); + creatureTemplate.MechanicImmuneMask = fields[85].GetUInt32(); + creatureTemplate.flags_extra = fields[86].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[87].GetCString()); ++count; } @@ -662,12 +661,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) continue; } - if (cInfo->trainer_spell != difficultyInfo->trainer_spell) - { - sLog->outError(LOG_FILTER_SQL, "Creature (Entry: %u) has different `trainer_spell` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]); - continue; - } - if (!difficultyInfo->AIName.empty()) { sLog->outError(LOG_FILTER_SQL, "Creature (Entry: %u) lists difficulty %u mode entry %u with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead.", diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index f5f998bbf0d..52721f9866d 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -452,54 +452,53 @@ public: cInfo->dynamicflags = fields[33].GetUInt32(); cInfo->family = fields[34].GetUInt8(); cInfo->trainer_type = fields[35].GetUInt8(); - cInfo->trainer_spell = fields[36].GetUInt32(); - cInfo->trainer_class = fields[37].GetUInt8(); - cInfo->trainer_race = fields[38].GetUInt8(); - cInfo->minrangedmg = fields[39].GetFloat(); - cInfo->maxrangedmg = fields[40].GetFloat(); - cInfo->rangedattackpower = fields[41].GetUInt16(); - cInfo->type = fields[42].GetUInt8(); - cInfo->type_flags = fields[43].GetUInt32(); - cInfo->lootid = fields[44].GetUInt32(); - cInfo->pickpocketLootId = fields[45].GetUInt32(); - cInfo->SkinLootId = fields[46].GetUInt32(); + cInfo->trainer_class = fields[36].GetUInt8(); + cInfo->trainer_race = fields[37].GetUInt8(); + cInfo->minrangedmg = fields[38].GetFloat(); + cInfo->maxrangedmg = fields[39].GetFloat(); + cInfo->rangedattackpower = fields[40].GetUInt16(); + cInfo->type = fields[41].GetUInt8(); + cInfo->type_flags = fields[42].GetUInt32(); + cInfo->lootid = fields[43].GetUInt32(); + cInfo->pickpocketLootId = fields[44].GetUInt32(); + cInfo->SkinLootId = fields[45].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[47 + i -1].GetUInt16(); - - cInfo->spells[0] = fields[53].GetUInt32(); - cInfo->spells[1] = fields[54].GetUInt32(); - cInfo->spells[2] = fields[55].GetUInt32(); - cInfo->spells[3] = fields[56].GetUInt32(); - cInfo->spells[4] = fields[57].GetUInt32(); - cInfo->spells[5] = fields[58].GetUInt32(); - cInfo->spells[6] = fields[59].GetUInt32(); - cInfo->spells[7] = fields[60].GetUInt32(); - cInfo->PetSpellDataId = fields[61].GetUInt32(); - cInfo->VehicleId = fields[62].GetUInt32(); - cInfo->mingold = fields[63].GetUInt32(); - cInfo->maxgold = fields[64].GetUInt32(); - cInfo->AIName = fields[65].GetString(); - cInfo->MovementType = fields[66].GetUInt8(); - cInfo->InhabitType = fields[67].GetUInt8(); - cInfo->HoverHeight = fields[68].GetFloat(); - cInfo->ModHealth = fields[69].GetFloat(); - cInfo->ModMana = fields[70].GetFloat(); - cInfo->ModManaExtra = fields[71].GetFloat(); - cInfo->ModArmor = fields[72].GetFloat(); - cInfo->RacialLeader = fields[73].GetBool(); - cInfo->questItems[0] = fields[74].GetUInt32(); - cInfo->questItems[1] = fields[75].GetUInt32(); - cInfo->questItems[2] = fields[76].GetUInt32(); - cInfo->questItems[3] = fields[77].GetUInt32(); - cInfo->questItems[4] = fields[78].GetUInt32(); - cInfo->questItems[5] = fields[79].GetUInt32(); - cInfo->movementId = fields[80].GetUInt32(); - cInfo->RegenHealth = fields[81].GetBool(); - cInfo->equipmentId = fields[82].GetUInt32(); - cInfo->MechanicImmuneMask = fields[83].GetUInt32(); - cInfo->flags_extra = fields[84].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[85].GetCString()); + cInfo->resistance[i] = fields[46 + i -1].GetUInt16(); + + cInfo->spells[0] = fields[52].GetUInt32(); + cInfo->spells[1] = fields[53].GetUInt32(); + cInfo->spells[2] = fields[54].GetUInt32(); + cInfo->spells[3] = fields[55].GetUInt32(); + cInfo->spells[4] = fields[56].GetUInt32(); + cInfo->spells[5] = fields[57].GetUInt32(); + cInfo->spells[6] = fields[58].GetUInt32(); + cInfo->spells[7] = fields[59].GetUInt32(); + cInfo->PetSpellDataId = fields[60].GetUInt32(); + cInfo->VehicleId = fields[61].GetUInt32(); + cInfo->mingold = fields[62].GetUInt32(); + cInfo->maxgold = fields[63].GetUInt32(); + cInfo->AIName = fields[64].GetString(); + cInfo->MovementType = fields[65].GetUInt8(); + cInfo->InhabitType = fields[66].GetUInt8(); + cInfo->HoverHeight = fields[67].GetFloat(); + cInfo->ModHealth = fields[68].GetFloat(); + cInfo->ModMana = fields[69].GetFloat(); + cInfo->ModManaExtra = fields[70].GetFloat(); + cInfo->ModArmor = fields[71].GetFloat(); + cInfo->RacialLeader = fields[72].GetBool(); + cInfo->questItems[0] = fields[73].GetUInt32(); + cInfo->questItems[1] = fields[74].GetUInt32(); + cInfo->questItems[2] = fields[75].GetUInt32(); + cInfo->questItems[3] = fields[76].GetUInt32(); + cInfo->questItems[4] = fields[77].GetUInt32(); + cInfo->questItems[5] = fields[78].GetUInt32(); + cInfo->movementId = fields[79].GetUInt32(); + cInfo->RegenHealth = fields[80].GetBool(); + cInfo->equipmentId = fields[81].GetUInt32(); + cInfo->MechanicImmuneMask = fields[82].GetUInt32(); + cInfo->flags_extra = fields[83].GetUInt32(); + cInfo->ScriptID = sObjectMgr->GetScriptId(fields[84].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 899ed51da0d..185ac647e33 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -78,7 +78,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); -- cgit v1.2.3 From d92347bc22fb213e19dcd0739e85970c1e74d319 Mon Sep 17 00:00:00 2001 From: Souler Date: Tue, 29 Jan 2013 15:10:47 +0000 Subject: Scripts/Mage: Unsummon current mage's Water Elemental before summoning a new one Closes #8433 --- src/server/scripts/Spells/spell_mage.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 7bd1753116b..ddd65b26496 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -25,6 +25,7 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Pet.h" enum MageSpells { @@ -904,6 +905,14 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); + + if (Player* player = caster->ToPlayer()) + if (Guardian* elemental = player->GetGuardianPet()) + // Check if the pet we are going to unsummon is the mage's water elemental + if (elemental->GetEntry() == sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY)->Effects[EFFECT_0].MiscValue || + elemental->GetEntry() == sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT)->Effects[EFFECT_0].MiscValue) + elemental->UnSummon(); + // Glyph of Eternal Water if (caster->HasAura(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER)) caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT, true); -- cgit v1.2.3 From 92d92df80960f046cac8cde15599b510cbc34109 Mon Sep 17 00:00:00 2001 From: Nay Date: Wed, 30 Jan 2013 01:33:12 +0000 Subject: Core/Object: Re-add a line that somehow got removed in a merge Thanks Warpten for noticing --- src/server/game/Entities/Object/Object.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 53e7c3405a0..292554620e4 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1014,6 +1014,7 @@ void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const valCount = PLAYER_END_NOT_SELF; for (uint16 index = 0; index < valCount; ++index) + if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (_changesMask.GetBit(index) && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) updateMask->SetBit(index); } -- cgit v1.2.3 From b427068c39188474879c848ba44070ef8a1e246b Mon Sep 17 00:00:00 2001 From: Shocker Date: Wed, 30 Jan 2013 07:05:19 +0200 Subject: Core/Titles: There are now 4 title fields (only 2 titles for now, Ruthless and Cataclysmic Gladiator). Also remove some unused outdated defines WARNING! Run the SQL query before you start your emulator because it will reset all titles on login otherwise --- .../2013_01_30_00_characters_characters.sql | 2 + src/server/game/Entities/Player/Player.h | 49 +--------------------- 2 files changed, 4 insertions(+), 47 deletions(-) create mode 100644 sql/updates/characters/2013_01_30_00_characters_characters.sql (limited to 'src') diff --git a/sql/updates/characters/2013_01_30_00_characters_characters.sql b/sql/updates/characters/2013_01_30_00_characters_characters.sql new file mode 100644 index 00000000000..1ddb4c8900d --- /dev/null +++ b/sql/updates/characters/2013_01_30_00_characters_characters.sql @@ -0,0 +1,2 @@ +-- Add missing fields for new titles field +UPDATE `characters` SET knownTitles = CONCAT(knownTitles, '0 0 ') WHERE (LENGTH(knownTitles) - LENGTH(REPLACE(knownTitles, ' ', ''))) = 6; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 511c3356b15..979dfc42040 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -531,53 +531,8 @@ enum PlayerFlags PLAYER_FLAGS_UNK31 = 0x80000000 }; -// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1< Date: Wed, 30 Jan 2013 08:39:06 +0100 Subject: Core/Misc: Remove some calls to const_cast --- src/server/game/Battlefield/Battlefield.cpp | 4 ++-- src/server/game/Handlers/AddonHandler.cpp | 28 +++++++++++----------- src/server/game/Handlers/MiscHandler.cpp | 4 ++-- src/server/game/Handlers/TicketHandler.cpp | 2 +- src/server/game/Server/Protocol/PacketLog.cpp | 2 +- src/server/game/Server/WorldSession.cpp | 2 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 20 ++++++++-------- src/server/game/Spells/Auras/SpellAuras.cpp | 4 ++-- src/server/game/Warden/Warden.cpp | 2 +- src/server/game/Warden/WardenMac.cpp | 2 +- src/server/game/Warden/WardenWin.cpp | 2 +- .../DarkPortal/instance_dark_portal.cpp | 2 +- src/server/shared/Logging/AppenderFile.cpp | 4 ++-- src/server/shared/Packets/ByteBuffer.h | 2 ++ src/server/worldserver/RemoteAccess/RASocket.cpp | 3 ++- 15 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index dffdb2361d5..5f5a14814eb 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -816,7 +816,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, Position pos, TeamId team) Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team) { //Get map object - Map* map = const_cast(sMapMgr->CreateBaseMap(m_MapId)); + Map* map = sMapMgr->CreateBaseMap(m_MapId); if (!map) { sLog->outError(LOG_FILTER_BATTLEFIELD, "Battlefield::SpawnCreature: Can't create creature entry: %u map not found", entry); @@ -854,7 +854,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z, float o) { // Get map object - Map* map = const_cast(sMapMgr->CreateBaseMap(571)); // *vomits* + Map* map = sMapMgr->CreateBaseMap(571); // *vomits* if (!map) return 0; diff --git a/src/server/game/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp index 7e62280f17c..68c93259fcb 100644 --- a/src/server/game/Handlers/AddonHandler.cpp +++ b/src/server/game/Handlers/AddonHandler.cpp @@ -30,7 +30,7 @@ AddonHandler::~AddonHandler() { } -bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) +bool AddonHandler::BuildAddonPacket(WorldPacket* source, WorldPacket* target) { ByteBuffer AddOnPacked; uLongf AddonRealSize; @@ -38,10 +38,10 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) uint32 TempValue; // broken addon packet, can't be received from real client - if (Source->rpos() + 4 > Source->size()) + if (source->rpos() + 4 > source->size()) return false; - *Source >> TempValue; // get real size of the packed structure + *source >> TempValue; // get real size of the packed structure // empty addon packet, nothing process, can't be received from real client if (!TempValue) @@ -49,13 +49,13 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) AddonRealSize = TempValue; // temp value because ZLIB only excepts uLongf - CurrentPosition = Source->rpos(); // get the position of the pointer in the structure + CurrentPosition = source->rpos(); // get the position of the pointer in the structure AddOnPacked.resize(AddonRealSize); // resize target for zlib action - if (!uncompress(const_cast(AddOnPacked.contents()), &AddonRealSize, const_cast((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)!= Z_OK) + if (!uncompress(AddOnPacked.contents(), &AddonRealSize, source->contents() + CurrentPosition, source->size() - CurrentPosition)!= Z_OK) { - Target->Initialize(SMSG_ADDON_INFO); + target->Initialize(SMSG_ADDON_INFO); uint32 addonsCount; AddOnPacked >> addonsCount; // addons count? @@ -81,14 +81,14 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) sLog->outDebug(LOG_FILTER_NETWORKIO, "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk2); uint8 state = (enabled ? 2 : 1); - *Target << uint8(state); + *target << uint8(state); uint8 unk1 = (enabled ? 1 : 0); - *Target << uint8(unk1); + *target << uint8(unk1); if (unk1) { uint8 unk = (crc != 0x4c1c776d); // If addon is Standard addon CRC - *Target << uint8(unk); + *target << uint8(unk); if (unk) { unsigned char tdata[256] = @@ -110,18 +110,18 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 }; - Target->append(tdata, sizeof(tdata)); + target->append(tdata, sizeof(tdata)); } - *Target << uint32(0); + *target << uint32(0); } uint8 unk3 = (enabled ? 0 : 1); - *Target << uint8(unk3); + *target << uint8(unk3); if (unk3) { // String, 256 (null terminated?) - *Target << uint8(0); + *target << uint8(0); } } @@ -129,7 +129,7 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) AddOnPacked >> unk4; uint32 count = 0; - *Target << uint32(count); + *target << uint32(count); if (AddOnPacked.rpos() != AddOnPacked.size()) sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under read!"); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 1aadd7f319d..aa4c9f35085 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -976,7 +976,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket& recvData) dest.resize(decompressedSize); uLongf realSize = decompressedSize; - if (uncompress(const_cast(dest.contents()), &realSize, const_cast(recvData.contents() + recvData.rpos()), recvData.size() - recvData.rpos()) != Z_OK) + if (uncompress(dest.contents(), &realSize, recvData.contents() + recvData.rpos(), recvData.size() - recvData.rpos()) != Z_OK) { recvData.rfinish(); // unnneded warning spam in this case sLog->outError(LOG_FILTER_NETWORKIO, "UAD: Failed to decompress account data"); @@ -1017,7 +1017,7 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recvData) ByteBuffer dest; dest.resize(destSize); - if (size && compress(const_cast(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) + if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK) { sLog->outDebug(LOG_FILTER_NETWORKIO, "RAD: Failed to compress account data"); return; diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index 4463613a97b..2da2735a3f9 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -69,7 +69,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData) dest.resize(decompressedSize); uLongf realSize = decompressedSize; - if (uncompress(const_cast(dest.contents()), &realSize, const_cast(recvData.contents() + pos), recvData.size() - pos) == Z_OK) + if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK) { dest >> chatLog; ticket->SetChatLog(times, chatLog); diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp index 649f4130c06..fe8b6804020 100644 --- a/src/server/game/Server/Protocol/PacketLog.cpp +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -55,7 +55,7 @@ void PacketLog::LogPacket(WorldPacket const& packet, Direction direction) data << uint8(direction); for (uint32 i = 0; i < packet.size(); i++) - data << const_cast(packet)[i]; + data << packet[i]; fwrite(data.contents(), 1, data.size(), _file); fflush(_file); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 6a26dafde79..6c689319bc7 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -961,7 +961,7 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data) ByteBuffer addonInfo; addonInfo.resize(size); - if (uncompress(const_cast(addonInfo.contents()), &uSize, const_cast(data.contents() + pos), data.size() - pos) == Z_OK) + if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK) { uint32 addonsCount; addonInfo >> addonsCount; // addons count diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 9230c46db15..05119af2582 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -488,7 +488,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) break; } - GetBase()->CallScriptEffectCalcAmountHandlers(const_cast(this), amount, m_canBeRecalculated); + GetBase()->CallScriptEffectCalcAmountHandlers(this, amount, m_canBeRecalculated); amount *= GetBase()->GetStackAmount(); return amount; } @@ -522,7 +522,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load) break; } - GetBase()->CallScriptEffectCalcPeriodicHandlers(const_cast(this), m_isPeriodic, m_amplitude); + GetBase()->CallScriptEffectCalcPeriodicHandlers(this, m_isPeriodic, m_amplitude); if (!m_isPeriodic) return; @@ -598,7 +598,7 @@ void AuraEffect::CalculateSpellMod() default: break; } - GetBase()->CallScriptEffectCalcSpellModHandlers(const_cast(this), m_spellmod); + GetBase()->CallScriptEffectCalcSpellModHandlers(this, m_spellmod); } void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply) @@ -657,15 +657,15 @@ void AuraEffect::HandleEffect(AuraApplication * aurApp, uint8 mode, bool apply) // call scripts helping/replacing effect handlers bool prevented = false; if (apply) - prevented = GetBase()->CallScriptEffectApplyHandlers(const_cast(this), const_cast(aurApp), (AuraEffectHandleModes)mode); + prevented = GetBase()->CallScriptEffectApplyHandlers(this, aurApp, (AuraEffectHandleModes)mode); else - prevented = GetBase()->CallScriptEffectRemoveHandlers(const_cast(this), const_cast(aurApp), (AuraEffectHandleModes)mode); + prevented = GetBase()->CallScriptEffectRemoveHandlers(this, aurApp, (AuraEffectHandleModes)mode); // check if script events have removed the aura or if default effect prevention was requested if ((apply && aurApp->GetRemoveMode()) || prevented) return; - (*this.*AuraEffectHandler [GetAuraType()])(const_cast(aurApp), mode, apply); + (*this.*AuraEffectHandler[GetAuraType()])(aurApp, mode, apply); // check if script events have removed the aura or if default effect prevention was requested if (apply && aurApp->GetRemoveMode()) @@ -673,9 +673,9 @@ void AuraEffect::HandleEffect(AuraApplication * aurApp, uint8 mode, bool apply) // call scripts triggering additional events after apply/remove if (apply) - GetBase()->CallScriptAfterEffectApplyHandlers(const_cast(this), const_cast(aurApp), (AuraEffectHandleModes)mode); + GetBase()->CallScriptAfterEffectApplyHandlers(this, aurApp, (AuraEffectHandleModes)mode); else - GetBase()->CallScriptAfterEffectRemoveHandlers(const_cast(this), const_cast(aurApp), (AuraEffectHandleModes)mode); + GetBase()->CallScriptAfterEffectRemoveHandlers(this, aurApp, (AuraEffectHandleModes)mode); } void AuraEffect::HandleEffect(Unit* target, uint8 mode, bool apply) @@ -980,7 +980,7 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { - bool prevented = GetBase()->CallScriptEffectProcHandlers(const_cast(this), const_cast(aurApp), eventInfo); + bool prevented = GetBase()->CallScriptEffectProcHandlers(this, aurApp, eventInfo); if (prevented) return; @@ -1005,7 +1005,7 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) break; } - GetBase()->CallScriptAfterEffectProcHandlers(const_cast(this), const_cast(aurApp), eventInfo); + GetBase()->CallScriptAfterEffectProcHandlers(this, aurApp, eventInfo); } void AuraEffect::CleanupTriggeredSpells(Unit* target) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 795908ce4b5..4500152133e 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2048,14 +2048,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) { - CallScriptProcHandlers(const_cast(aurApp), eventInfo); + CallScriptProcHandlers(aurApp, eventInfo); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (aurApp->HasEffect(i)) // OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc() GetEffect(i)->HandleProc(aurApp, eventInfo); - CallScriptAfterProcHandlers(const_cast(aurApp), eventInfo); + CallScriptAfterProcHandlers(aurApp, eventInfo); // Remove aura if we've used last charge to proc if (IsUsingCharges() && !GetCharges()) diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index a99688c8844..af695c482cf 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -219,7 +219,7 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) { - _warden->DecryptData(const_cast(recvData.contents()), recvData.size()); + _warden->DecryptData(recvData.contents(), recvData.size()); uint8 opcode; recvData >> opcode; sLog->outDebug(LOG_FILTER_WARDEN, "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size())); diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index 7c2979e0dc6..fa84cd216b6 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -206,7 +206,7 @@ void WardenMac::RequestData() buff.hexlike(); // Encrypt with warden RC4 key. - EncryptData(const_cast(buff.contents()), buff.size()); + EncryptData(buff.contents(), buff.size()); WorldPacket pkt(SMSG_WARDEN_DATA, buff.size()); pkt.append(buff); diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 4da05eded0c..bf423459222 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -310,7 +310,7 @@ void WardenWin::RequestData() buff.hexlike(); // Encrypt with warden RC4 key - EncryptData(const_cast(buff.contents()), buff.size()); + EncryptData(buff.contents(), buff.size()); WorldPacket pkt(SMSG_WARDEN_DATA, buff.size()); pkt.append(buff); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp index 9c17ed10d9c..78b655bb73b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp @@ -122,7 +122,7 @@ public: bool IsEncounterInProgress() const { - if (const_cast(this)->GetData(TYPE_MEDIVH) == IN_PROGRESS) + if (GetData(TYPE_MEDIVH) == IN_PROGRESS) return true; return false; diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 25141815de6..e29459299f7 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -20,12 +20,12 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags, uint64 fileSize): Appender(id, name, APPENDER_FILE, level, _flags), + logfile(NULL), filename(_filename), logDir(_logDir), mode(_mode), maxFileSize(fileSize), - fileSize(0), - logfile(NULL) + fileSize(0) { dynamicName = std::string::npos != filename.find("%s"); backup = _flags & APPENDER_FLAGS_MAKE_FILE_BACKUP; diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 22dad8d7dd1..bf2980aa45d 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -381,6 +381,8 @@ class ByteBuffer return *this; } + uint8 * contents() { return &_storage[0]; } + const uint8 *contents() const { return &_storage[0]; } size_t size() const { return _storage.size(); } diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp index e0f4e7f0de6..94950703271 100644 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ b/src/server/worldserver/RemoteAccess/RASocket.cpp @@ -388,7 +388,8 @@ void RASocket::zprint(void* callbackArg, const char * szText) ACE_Message_Block* mb = new ACE_Message_Block(sz); mb->copy(szText, sz); - if (socket->putq(mb, const_cast(&ACE_Time_Value::zero)) == -1) + ACE_Time_Value tv = ACE_Time_Value::zero; + if (socket->putq(mb, &tv) == -1) { sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Failed to enqueue message, queue is full or closed. Error is %s", ACE_OS::strerror(errno)); mb->release(); -- cgit v1.2.3 From 2c32393a394a38e0ba6b4b054b6b446320093b17 Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 30 Jan 2013 08:42:01 +0100 Subject: Core/Misc: Always state what columns are affected by MySQL statements --- src/server/shared/Database/Implementation/LoginDatabase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 3fc6649bd4d..227680b2d6b 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -26,7 +26,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban')", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban')", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED, "SELECT bandate, unbandate FROM account_banned WHERE id = ? AND active = 1", CONNECTION_SYNCH); @@ -47,7 +47,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_ID, "SELECT 1 FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_ACCOUNT_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC); -- cgit v1.2.3 From c4e4cb1b5c4b407c44da30fb254a6c248503451b Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 30 Jan 2013 09:06:19 +0100 Subject: Core/Misc: Remove using directive from header files (It will eventually lead to name collisions) --- src/server/collision/BoundingIntervalHierarchy.cpp | 12 +++-- src/server/collision/BoundingIntervalHierarchy.h | 33 ++++-------- .../collision/BoundingIntervalHierarchyWrapper.h | 8 +-- src/server/collision/DynamicTree.cpp | 61 ++++++++++++---------- src/server/collision/DynamicTree.h | 26 ++++----- src/server/collision/Maps/MapTree.h | 2 +- src/server/collision/Models/WorldModel.h | 28 +++++----- src/server/collision/RegularGrid.h | 16 ++---- src/server/game/Maps/Map.cpp | 6 +-- .../game/Movement/Spline/MovementPacketBuilder.cpp | 1 + .../game/Movement/Spline/MovementPacketBuilder.h | 1 + src/tools/mmaps_generator/TerrainBuilder.cpp | 24 ++++----- src/tools/mmaps_generator/VMapExtensions.cpp | 4 +- 13 files changed, 110 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp index ad3753ea3c9..bca738d1ff6 100644 --- a/src/server/collision/BoundingIntervalHierarchy.cpp +++ b/src/server/collision/BoundingIntervalHierarchy.cpp @@ -18,6 +18,12 @@ #include "BoundingIntervalHierarchy.h" +#if defined __APPLE__ + #define isnan std::isnan +#elif defined _MSC_VER + #define isnan _isnan +#endif + void BIH::buildHierarchy(std::vector &tempTree, buildData &dat, BuildStats &stats) { // create space for the first node @@ -51,7 +57,7 @@ void BIH::subdivide(int left, int right, std::vector &tempTree, buildDat prevAxis = axis; prevSplit = split; // perform quick consistency checks - Vector3 d( gridBox.hi - gridBox.lo ); + G3D::Vector3 d( gridBox.hi - gridBox.lo ); if (d.x < 0 || d.y < 0 || d.z < 0) throw std::logic_error("negative node extents"); for (int i = 0; i < 3; i++) @@ -255,11 +261,11 @@ bool BIH::writeToFile(FILE* wf) const bool BIH::readFromFile(FILE* rf) { uint32 treeSize; - Vector3 lo, hi; + G3D::Vector3 lo, hi; uint32 check=0, count=0; check += fread(&lo, sizeof(float), 3, rf); check += fread(&hi, sizeof(float), 3, rf); - bounds = AABox(lo, hi); + bounds = G3D::AABox(lo, hi); check += fread(&treeSize, sizeof(uint32), 1, rf); tree.resize(treeSize); check += fread(&tree[0], sizeof(uint32), treeSize, rf); diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h index 7cbaedbfba6..997f9c99e5f 100644 --- a/src/server/collision/BoundingIntervalHierarchy.h +++ b/src/server/collision/BoundingIntervalHierarchy.h @@ -31,20 +31,8 @@ #include #include -#ifdef __APPLE__ - #define isnan(x) ( std::isnan(x) ) -#endif - #define MAX_STACK_SIZE 64 -#ifdef _MSC_VER - #define isnan(x) _isnan(x) -#endif - -using G3D::Vector3; -using G3D::AABox; -using G3D::Ray; - static inline uint32 floatToRawIntBits(float f) { union @@ -69,7 +57,7 @@ static inline float intBitsToFloat(uint32 i) struct AABound { - Vector3 lo, hi; + G3D::Vector3 lo, hi; }; /** Bounding Interval Hierarchy Class. @@ -105,12 +93,11 @@ class BIH dat.maxPrims = leafSize; dat.numPrims = primitives.size(); dat.indices = new uint32[dat.numPrims]; - dat.primBound = new AABox[dat.numPrims]; + dat.primBound = new G3D::AABox[dat.numPrims]; getBounds(primitives[0], bounds); for (uint32 i=0; i - void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const + void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const { float intervalMin = -1.f; float intervalMax = -1.f; - Vector3 org = r.origin(); - Vector3 dir = r.direction(); - Vector3 invDir; + G3D::Vector3 org = r.origin(); + G3D::Vector3 dir = r.direction(); + G3D::Vector3 invDir; for (int i=0; i<3; ++i) { invDir[i] = 1.f / dir[i]; @@ -270,7 +257,7 @@ class BIH } template - void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const + void intersectPoint(const G3D::Vector3 &p, IsectCallback& intersectCallback) const { if (!bounds.contains(p)) return; @@ -353,12 +340,12 @@ class BIH protected: std::vector tree; std::vector objects; - AABox bounds; + G3D::AABox bounds; struct buildData { uint32 *indices; - AABox *primBound; + G3D::AABox *primBound; uint32 numPrims; int maxPrims; }; @@ -410,4 +397,4 @@ class BIH void subdivide(int left, int right, std::vector &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats); }; -#endif // _BIH_H \ No newline at end of file +#endif // _BIH_H diff --git a/src/server/collision/BoundingIntervalHierarchyWrapper.h b/src/server/collision/BoundingIntervalHierarchyWrapper.h index 315f3004306..305d57b0075 100644 --- a/src/server/collision/BoundingIntervalHierarchyWrapper.h +++ b/src/server/collision/BoundingIntervalHierarchyWrapper.h @@ -37,7 +37,7 @@ class BIHWrap MDLCallback(RayCallback& callback, const T* const* objects_array, uint32 objects_size ) : objects(objects_array), _callback(callback), objects_size(objects_size) {} - bool operator() (const Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/) + bool operator() (const G3D::Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/) { if (Idx >= objects_size) return false; @@ -46,7 +46,7 @@ class BIHWrap return false; } - void operator() (const Vector3& p, uint32 Idx) + void operator() (const G3D::Vector3& p, uint32 Idx) { if (Idx >= objects_size) return false; @@ -98,7 +98,7 @@ public: } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& maxDist) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& maxDist) { balance(); MDLCallback temp_cb(intersectCallback, m_objects.getCArray(), m_objects.size()); @@ -106,7 +106,7 @@ public: } template - void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) + void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback) { balance(); MDLCallback callback(intersectCallback, m_objects.getCArray(), m_objects.size()); diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp index c6754278d17..c70a4b78a03 100644 --- a/src/server/collision/DynamicTree.cpp +++ b/src/server/collision/DynamicTree.cpp @@ -27,15 +27,24 @@ #include "GameObjectModel.h" #include "ModelInstance.h" +#include +#include +#include + using VMAP::ModelInstance; -using G3D::Ray; + +namespace { + +int CHECK_TREE_PERIOD = 200; + +} // namespace template<> struct HashTrait< GameObjectModel>{ static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; } }; template<> struct PositionTrait< GameObjectModel> { - static void getPosition(const GameObjectModel& g, Vector3& p) { p = g.getPosition(); } + static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); } }; template<> struct BoundsTrait< GameObjectModel> { @@ -49,11 +58,6 @@ static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2 } */ -int valuesPerNode = 5, numMeanSplits = 3; - -int UNBALANCED_TIMES_LIMIT = 5; -int CHECK_TREE_PERIOD = 200; - typedef RegularGrid2D > ParentTree; struct DynTreeImpl : public ParentTree/*, public Intersectable*/ @@ -103,43 +107,43 @@ struct DynTreeImpl : public ParentTree/*, public Intersectable*/ int unbalanced_times; }; -DynamicMapTree::DynamicMapTree() : impl(*new DynTreeImpl()) +DynamicMapTree::DynamicMapTree() : impl(new DynTreeImpl()) { } DynamicMapTree::~DynamicMapTree() { - delete &impl; + delete impl; } void DynamicMapTree::insert(const GameObjectModel& mdl) { - impl.insert(mdl); + impl->insert(mdl); } void DynamicMapTree::remove(const GameObjectModel& mdl) { - impl.remove(mdl); + impl->remove(mdl); } bool DynamicMapTree::contains(const GameObjectModel& mdl) const { - return impl.contains(mdl); + return impl->contains(mdl); } void DynamicMapTree::balance() { - impl.balance(); + impl->balance(); } int DynamicMapTree::size() const { - return impl.size(); + return impl->size(); } void DynamicMapTree::update(uint32 t_diff) { - impl.update(t_diff); + impl->update(t_diff); } struct DynamicTreeIntersectionCallback @@ -147,7 +151,7 @@ struct DynamicTreeIntersectionCallback bool did_hit; uint32 phase_mask; DynamicTreeIntersectionCallback(uint32 phasemask) : did_hit(false), phase_mask(phasemask) {} - bool operator()(const Ray& r, const GameObjectModel& obj, float& distance) + bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance) { did_hit = obj.intersectRay(r, distance, true, phase_mask); return did_hit; @@ -163,7 +167,7 @@ struct DynamicTreeIntersectionCallback_WithLogger { sLog->outDebug(LOG_FILTER_MAPS, "Dynamic Intersection log"); } - bool operator()(const Ray& r, const GameObjectModel& obj, float& distance) + bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance) { sLog->outDebug(LOG_FILTER_MAPS, "testing intersection with %s", obj.name.c_str()); bool hit = obj.intersectRay(r, distance, true, phase_mask); @@ -177,17 +181,20 @@ struct DynamicTreeIntersectionCallback_WithLogger bool didHit() const { return did_hit;} }; -bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const +bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, + const G3D::Vector3& endPos, float& maxDist) const { float distance = maxDist; DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectRay(ray, callback, distance, endPos); + impl->intersectRay(ray, callback, distance, endPos); if (callback.didHit()) maxDist = distance; return callback.didHit(); } -bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& startPos, const Vector3& endPos, Vector3& resultHit, float modifyDist) const +bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3& startPos, + const G3D::Vector3& endPos, G3D::Vector3& resultHit, + float modifyDist) const { bool result = false; float maxDist = (endPos - startPos).magnitude(); @@ -199,7 +206,7 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star resultHit = endPos; return false; } - Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 + G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 G3D::Ray ray(startPos, dir); float dist = maxDist; if (getIntersectionTime(phasemask, ray, endPos, dist)) @@ -227,26 +234,26 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const { - Vector3 v1(x1, y1, z1), v2(x2, y2, z2); + G3D::Vector3 v1(x1, y1, z1), v2(x2, y2, z2); float maxDist = (v2 - v1).magnitude(); if (!G3D::fuzzyGt(maxDist, 0) ) return true; - Ray r(v1, (v2-v1) / maxDist); + G3D::Ray r(v1, (v2-v1) / maxDist); DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectRay(r, callback, maxDist, v2); + impl->intersectRay(r, callback, maxDist, v2); return !callback.did_hit; } float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const { - Vector3 v(x, y, z); - Ray r(v, Vector3(0, 0, -1)); + G3D::Vector3 v(x, y, z); + G3D::Ray r(v, G3D::Vector3(0, 0, -1)); DynamicTreeIntersectionCallback callback(phasemask); - impl.intersectZAllignedRay(r, callback, maxSearchDist); + impl->intersectZAllignedRay(r, callback, maxSearchDist); if (callback.didHit()) return v.z - maxSearchDist; diff --git a/src/server/collision/DynamicTree.h b/src/server/collision/DynamicTree.h index ca199a9cd70..8e541fd453a 100644 --- a/src/server/collision/DynamicTree.h +++ b/src/server/collision/DynamicTree.h @@ -20,34 +20,36 @@ #ifndef _DYNTREE_H #define _DYNTREE_H -#include -#include -#include -#include - -//#include "ModelInstance.h" #include "Define.h" -//#include "GameObjectModel.h" namespace G3D { + class Ray; class Vector3; } -using G3D::Vector3; class GameObjectModel; +struct DynTreeImpl; class DynamicMapTree { - struct DynTreeImpl& impl; + DynTreeImpl *impl; + public: DynamicMapTree(); ~DynamicMapTree(); - bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const; - bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const; - bool getObjectHitPos(uint32 phasemask, const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const; + bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, + float z2, uint32 phasemask) const; + + bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, + const G3D::Vector3& endPos, float& maxDist) const; + + bool getObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1, + const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos, + float pModifyDist) const; + float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const; void insert(const GameObjectModel&); diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index c8e9628dff1..5de8e616d2b 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -72,7 +72,7 @@ namespace VMAP bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const; float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const; bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const; - bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const; + bool GetLocationInfo(const G3D::Vector3 &pos, LocationInfo &info) const; bool InitMap(const std::string &fname, VMapManager2* vm); void UnloadMap(VMapManager2* vm); diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h index ade9efbb040..cea32cfedfb 100644 --- a/src/server/collision/Models/WorldModel.h +++ b/src/server/collision/Models/WorldModel.h @@ -47,11 +47,11 @@ namespace VMAP class WmoLiquid { public: - WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type); + WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type); WmoLiquid(const WmoLiquid &other); ~WmoLiquid(); WmoLiquid& operator=(const WmoLiquid &other); - bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const; + bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const; uint32 GetType() const { return iType; } float *GetHeightStorage() { return iHeight; } uint8 *GetFlagsStorage() { return iFlags; } @@ -60,14 +60,14 @@ namespace VMAP static bool readFromFile(FILE* rf, WmoLiquid* &liquid); private: WmoLiquid(): iHeight(0), iFlags(0) {}; - uint32 iTilesX; //!< number of tiles in x direction, each + uint32 iTilesX; //!< number of tiles in x direction, each uint32 iTilesY; - Vector3 iCorner; //!< the lower corner - uint32 iType; //!< liquid type - float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values - uint8 *iFlags; //!< info if liquid tile is used + G3D::Vector3 iCorner; //!< the lower corner + uint32 iType; //!< liquid type + float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values + uint8 *iFlags; //!< info if liquid tile is used public: - void getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const; + void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const; }; /*! holding additional info for WMO group files */ @@ -76,16 +76,16 @@ namespace VMAP public: GroupModel(): iLiquid(0) {} GroupModel(const GroupModel &other); - GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound): + GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound): iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {} ~GroupModel() { delete iLiquid; } //! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry! - void setMeshData(std::vector &vert, std::vector &tri); + void setMeshData(std::vector &vert, std::vector &tri); void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; } bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const; - bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const; - bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const; + bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const; + bool GetLiquidLevel(const G3D::Vector3 &pos, float &liqHeight) const; uint32 GetLiquidType() const; bool writeToFile(FILE* wf); bool readFromFile(FILE* rf); @@ -96,12 +96,12 @@ namespace VMAP G3D::AABox iBound; uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor uint32 iGroupWMOID; - std::vector vertices; + std::vector vertices; std::vector triangles; BIH meshTree; WmoLiquid* iLiquid; public: - void getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid); + void getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid); }; /*! Holds a model (converted M2 or WMO) in its original coordinate space */ class WorldModel diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h index f38bf357a19..d1832c1ea06 100644 --- a/src/server/collision/RegularGrid.h +++ b/src/server/collision/RegularGrid.h @@ -3,18 +3,12 @@ #include -#include #include #include #include #include "Errors.h" -using G3D::Vector2; -using G3D::Vector3; -using G3D::AABox; -using G3D::Ray; - template struct NodeCreator{ static Node * makeNode(int /*x*/, int /*y*/) { return new Node();} @@ -54,7 +48,7 @@ public: void insert(const T& value) { - Vector3 pos; + G3D::Vector3 pos; PositionFunc::getPosition(value, pos); Node& node = getGridFor(pos.x, pos.y); node.insert(value); @@ -109,13 +103,13 @@ public: } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float max_dist) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float max_dist) { intersectRay(ray, intersectCallback, max_dist, ray.origin() + ray.direction() * max_dist); } template - void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist, const Vector3& end) + void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist, const G3D::Vector3& end) { Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y); if (!cell.isValid()) @@ -191,7 +185,7 @@ public: } template - void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) + void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback) { Cell cell = Cell::ComputeCell(point.x, point.y); if (!cell.isValid()) @@ -202,7 +196,7 @@ public: // Optimized verson of intersectRay function for rays with vertical directions template - void intersectZAllignedRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist) + void intersectZAllignedRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist) { Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y); if (!cell.isValid()) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 9e6735efc26..184450ef8d6 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1920,10 +1920,10 @@ bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, floa bool Map::getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) { - Vector3 startPos = Vector3(x1, y1, z1); - Vector3 dstPos = Vector3(x2, y2, z2); + G3D::Vector3 startPos(x1, y1, z1); + G3D::Vector3 dstPos(x2, y2, z2); - Vector3 resultPos; + G3D::Vector3 resultPos; bool result = _dynamicTree.getObjectHitPos(phasemask, startPos, dstPos, resultPos, modifyDist); rx = resultPos.x; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 7133fc50e9f..801219b2a5a 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 92a414e9b3b..b502e203656 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008-2013 TrinityCore * Copyright (C) 2005-2011 MaNGOS * * This program is free software; you can redistribute it and/or modify diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index a42cd2b9bc6..3a87da3d4f1 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -674,14 +674,14 @@ namespace MMAP // transform data float scale = instance.iScale; G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f); - Vector3 position = instance.iPos; + G3D::Vector3 position = instance.iPos; position.x -= 32*GRID_SIZE; position.y -= 32*GRID_SIZE; for (std::vector::iterator it = groupModels.begin(); it != groupModels.end(); ++it) { - std::vector tempVertices; - std::vector transformedVertices; + std::vector tempVertices; + std::vector transformedVertices; std::vector tempTriangles; WmoLiquid* liquid = NULL; @@ -698,10 +698,10 @@ namespace MMAP // now handle liquid data if (liquid) { - std::vector liqVerts; + std::vector liqVerts; std::vector liqTris; uint32 tilesX, tilesY, vertsX, vertsY; - Vector3 corner; + G3D::Vector3 corner; liquid->getPosInfo(tilesX, tilesY, corner); vertsX = tilesX + 1; vertsY = tilesY + 1; @@ -730,11 +730,11 @@ namespace MMAP // tile = x*tilesY+y // flag = y*tilesY+x - Vector3 vert; + G3D::Vector3 vert; for (uint32 x = 0; x < vertsX; ++x) for (uint32 y = 0; y < vertsY; ++y) { - vert = Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); + vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]); vert = vert * rotation * scale + position; vert.x *= -1.f; vert.y *= -1.f; @@ -785,12 +785,12 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, Vector3 &position) + void TerrainBuilder::transform(std::vector &source, std::vector &transformedVertices, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position) { - for (std::vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { // apply tranform, then mirror along the horizontal axes - Vector3 v((*it) * rotation * scale + position); + G3D::Vector3 v((*it) * rotation * scale + position); v.x *= -1.f; v.y *= -1.f; transformedVertices.push_back(v); @@ -798,9 +798,9 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) + void TerrainBuilder::copyVertices(std::vector &source, G3D::Array &dest) { - for (std::vector::iterator it = source.begin(); it != source.end(); ++it) + for (std::vector::iterator it = source.begin(); it != source.end(); ++it) { dest.push_back((*it).y); dest.push_back((*it).z); diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp index 972f222bba6..08929e5259d 100644 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ b/src/tools/mmaps_generator/VMapExtensions.cpp @@ -47,7 +47,7 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) + void GroupModel::getMeshData(std::vector &vertices, std::vector &triangles, WmoLiquid* &liquid) { vertices = this->vertices; triangles = this->triangles; @@ -61,7 +61,7 @@ namespace VMAP } // declared in src/shared/vmap/WorldModel.h - void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, Vector3 &corner) const + void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const { tilesX = iTilesX; tilesY = iTilesY; -- cgit v1.2.3 From 8cd408ae6cb2a7f9eb84c9e2a57fc65a15ce6faf Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 30 Jan 2013 10:34:18 +0100 Subject: Core/Misc: Some changes to minimize differences with 4.3.4 branch --- src/server/game/Chat/Channels/Channel.h | 4 +- src/server/game/Conditions/ConditionMgr.cpp | 2 +- src/server/game/DungeonFinding/LFGMgr.cpp | 2 +- .../game/Entities/Item/ItemEnchantmentMgr.cpp | 2 +- src/server/game/Entities/Transport/Transport.cpp | 6 +- src/server/game/Entities/Unit/StatSystem.cpp | 7 +- src/server/game/Entities/Vehicle/Vehicle.cpp | 2 +- src/server/game/Events/GameEventMgr.cpp | 3 +- src/server/game/Globals/ObjectMgr.cpp | 81 +++----- src/server/game/Handlers/LootHandler.cpp | 4 +- src/server/game/Loot/LootMgr.cpp | 26 +-- src/server/game/Miscellaneous/Formulas.h | 7 +- src/server/game/Miscellaneous/SharedDefines.h | 226 ++++++++++----------- .../game/Movement/Waypoints/WaypointManager.cpp | 4 +- src/server/game/Skills/SkillDiscovery.cpp | 4 +- src/server/game/Skills/SkillExtraItems.cpp | 12 +- src/server/game/Warden/WardenCheckMgr.cpp | 14 +- src/server/game/Weather/WeatherMgr.cpp | 4 +- .../scripts/EasternKingdoms/ZulAman/zulaman.cpp | 2 +- src/server/shared/Common.h | 2 +- 20 files changed, 186 insertions(+), 228 deletions(-) (limited to 'src') diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 0b3b84088a5..295c8d5394d 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -49,8 +49,8 @@ enum ChatNotify CHAT_MODE_CHANGE_NOTICE = 0x0C, //? CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s."; CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s."; - // CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s."; - // CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s."; + CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s."; + CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s."; CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak."; CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s."; CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are bannedStore from that channel."; diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 5e1a05669ed..a5494f689fb 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -777,7 +777,7 @@ void ConditionMgr::LoadConditions(bool isReload) if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 conditions. DB table `conditions` is empty!"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 conditions. DB table `conditions` is empty!"); return; } diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index a931d61f740..0f23925cc2b 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -282,7 +282,7 @@ void LFGMgr::LoadLFGDungeons(bool reload /* = false */) if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!"); return; } diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 2b887672ec4..6a530a771f6 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -74,7 +74,7 @@ void LoadRandomEnchantmentsTable() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u Item Enchantment definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty."); } uint32 GetItemEnchantMod(int32 entry) diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 3ce23a973ca..c2c01331b4d 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -680,9 +680,9 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, void Transport::UpdatePosition(MovementInfo* mi) { - float transport_o = mi->pos.m_orientation - mi->t_pos.m_orientation; - float transport_x = mi->pos.m_positionX - (mi->t_pos.m_positionX * std::cos(transport_o) - mi->t_pos.m_positionY* std::sin(transport_o)); - float transport_y = mi->pos.m_positionY - (mi->t_pos.m_positionY * std::cos(transport_o) + mi->t_pos.m_positionX* std::sin(transport_o)); + float transport_o = mi->pos.GetOrientation() - mi->t_pos.GetOrientation(); + float transport_x = mi->pos.m_positionX - (mi->t_pos.m_positionX * std::cos(transport_o) - mi->t_pos.m_positionY * std::sin(transport_o)); + float transport_y = mi->pos.m_positionY - (mi->t_pos.m_positionY * std::cos(transport_o) + mi->t_pos.m_positionX * std::sin(transport_o)); float transport_z = mi->pos.m_positionZ - mi->t_pos.m_positionZ; Relocate(transport_x, transport_y, transport_z, transport_o); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 5cf0550905c..0024d726060 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -229,8 +229,7 @@ void Player::UpdateArmor() float Player::GetHealthBonusFromStamina() { float stamina = GetStat(STAT_STAMINA); - - float baseStam = stamina < 20 ? stamina : 20; + float baseStam = std::min(20.0f, stamina); float moreStam = stamina - baseStam; return baseStam + (moreStam*10.0f); @@ -240,10 +239,10 @@ float Player::GetManaBonusFromIntellect() { float intellect = GetStat(STAT_INTELLECT); - float baseInt = intellect < 20 ? intellect : 20; + float baseInt = std::min(20.0f, intellect); float moreInt = intellect - baseInt; - return baseInt + (moreInt*15.0f); + return baseInt + (moreInt * 15.0f); } void Player::UpdateMaxHealth() diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 8f040ab6a5e..96f2b6d73dd 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -380,7 +380,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) if (_me->IsInWorld()) { unit->SendClearTarget(); // SMSG_BREAK_TARGET - unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) + unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT Movement::MoveSplineInit init(unit); init.DisableTransportPathTransformations(); diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index a499347356b..de3038cef1e 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -210,8 +210,7 @@ void GameEventMgr::LoadFromDB() if (!result) { mGameEvent.clear(); - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 game events. DB table `game_event` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 game events. DB table `game_event` is empty."); return; } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 891bc9b253a..a3a5c865a48 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1189,8 +1189,7 @@ void ObjectMgr::LoadLinkedRespawn() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty."); return; } @@ -1420,8 +1419,7 @@ void ObjectMgr::LoadCreatures() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 creatures. DB table `creature` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 creatures. DB table `creature` is empty."); return; } @@ -1729,7 +1727,7 @@ void ObjectMgr::LoadGameobjects() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 gameobjects. DB table `gameobject` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 gameobjects. DB table `gameobject` is empty."); return; } @@ -2754,8 +2752,7 @@ void ObjectMgr::LoadVehicleTemplateAccessories() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty."); return; } @@ -2849,8 +2846,7 @@ void ObjectMgr::LoadPetLevelInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty."); return; } @@ -2988,8 +2984,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty."); exit(1); } else @@ -3146,8 +3141,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 player create spells. DB table `%s` is empty.", sWorld->getBoolConfig(CONFIG_START_ALL_SPELLS) ? "playercreateinfo_spell_custom" : "playercreateinfo_spell"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 player create spells. DB table `%s` is empty.", sWorld->getBoolConfig(CONFIG_START_ALL_SPELLS) ? "playercreateinfo_spell_custom" : "playercreateinfo_spell"); } else { @@ -3208,8 +3202,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty."); } else { @@ -3254,7 +3247,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 level health/mana definitions. DB table `game_event_condition` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 level health/mana definitions. DB table `game_event_condition` is empty."); exit(1); } @@ -3336,8 +3329,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 level stats definitions. DB table `player_levelstats` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 level stats definitions. DB table `player_levelstats` is empty."); exit(1); } @@ -3449,8 +3441,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty."); exit(1); } @@ -3647,7 +3638,7 @@ void ObjectMgr::LoadQuests() " FROM quest_template"); if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 quests definitions. DB table `quest_template` is empty."); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 quests definitions. DB table `quest_template` is empty."); return; } @@ -4999,8 +4990,7 @@ void ObjectMgr::LoadInstanceEncounters() QueryResult result = WorldDatabase.Query("SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters"); if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 instance encounters, table is empty!"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 instance encounters, table is empty!"); return; } @@ -6453,8 +6443,7 @@ void ObjectMgr::LoadExplorationBaseXP() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty."); return; } @@ -6601,7 +6590,7 @@ void ObjectMgr::LoadReputationRewardRate() QueryResult result = WorldDatabase.Query("SELECT faction, quest_rate, quest_daily_rate, quest_weekly_rate, quest_monthly_rate, creature_rate, spell_rate FROM reputation_reward_rate"); if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded `reputation_reward_rate`, table is empty!"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded `reputation_reward_rate`, table is empty!"); return; } @@ -6689,8 +6678,7 @@ void ObjectMgr::LoadReputationOnKill() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty."); return; } @@ -6868,8 +6856,7 @@ void ObjectMgr::LoadPointsOfInterest() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty."); return; } @@ -6914,8 +6901,7 @@ void ObjectMgr::LoadQuestPOI() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty."); return; } @@ -6982,8 +6968,7 @@ void ObjectMgr::LoadNPCSpellClickSpells() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty."); return; } @@ -7085,7 +7070,7 @@ void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map, std::string const& if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 quest relations from `%s`, table is empty.", table.c_str()); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 quest relations from `%s`, table is empty.", table.c_str()); return; } @@ -7460,7 +7445,7 @@ bool ObjectMgr::LoadTrinityStrings(const char* table, int32 min_value, int32 max if (!result) { if (min_value == MIN_TRINITY_STRING_ID) // error only in case internal strings - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue.", table); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue.", table); else sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 string templates. DB table `%s` is empty.", table); @@ -7536,8 +7521,7 @@ void ObjectMgr::LoadFishingBaseSkillLevel() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty."); return; } @@ -7665,8 +7649,7 @@ void ObjectMgr::LoadGameTele() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!"); return; } @@ -7805,8 +7788,7 @@ void ObjectMgr::LoadMailLevelRewards() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty."); return; } @@ -8072,8 +8054,7 @@ void ObjectMgr::LoadGossipMenu() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!"); return; } @@ -8118,8 +8099,7 @@ void ObjectMgr::LoadGossipMenuItems() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 gossip_menu_option entries. DB table `gossip_menu_option` is empty!"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 gossip_menu_option entries. DB table `gossip_menu_option` is empty!"); return; } @@ -8326,8 +8306,7 @@ void ObjectMgr::LoadScriptNames() if (!result) { - - sLog->outError(LOG_FILTER_SQL, ">> Loaded empty set of Script Names!"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded empty set of Script Names!"); return; } @@ -8503,8 +8482,7 @@ void ObjectMgr::LoadFactionChangeAchievements() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty."); return; } @@ -8574,8 +8552,7 @@ void ObjectMgr::LoadFactionChangeSpells() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty."); return; } diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 74fd18b31ed..b9a615052bb 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -99,7 +99,7 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData) player->GetSession()->DoLootRelease(lguid); } -void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY"); @@ -188,7 +188,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recvData*/) WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); - data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." + data << uint8(playersNear.size() <= 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->GetSession()->SendPacket(&data); } } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index a64e8117ce9..fa94232d5b4 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1206,14 +1206,10 @@ void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint { float chance = RawTotalChance(); if (chance > 101.0f) // TODO: replace with 100% when DBs will be ready - { sLog->outError(LOG_FILTER_SQL, "Table '%s' entry %u group %d has total chance > 100%% (%f)", lootstore.GetName(), id, group_id, chance); - } if (chance >= 100.0f && !EqualChanced.empty()) - { sLog->outError(LOG_FILTER_SQL, "Table '%s' entry %u group %d has items with chance=0%% but group total chance >= 100%% (%f)", lootstore.GetName(), id, group_id, chance); - } } void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, LootIdSet* ref_set) const @@ -1521,7 +1517,7 @@ void LoadLootTemplates_Creature() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u creature loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty"); } void LoadLootTemplates_Disenchant() @@ -1554,7 +1550,7 @@ void LoadLootTemplates_Disenchant() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u disenchanting loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty"); } void LoadLootTemplates_Fishing() @@ -1578,7 +1574,7 @@ void LoadLootTemplates_Fishing() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u fishing loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty"); } void LoadLootTemplates_Gameobject() @@ -1612,7 +1608,7 @@ void LoadLootTemplates_Gameobject() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u gameobject loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty"); } void LoadLootTemplates_Item() @@ -1636,7 +1632,7 @@ void LoadLootTemplates_Item() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u item loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 item loot templates. DB table `item_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 item loot templates. DB table `item_loot_template` is empty"); } void LoadLootTemplates_Milling() @@ -1665,7 +1661,7 @@ void LoadLootTemplates_Milling() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u milling loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty"); } void LoadLootTemplates_Pickpocketing() @@ -1699,7 +1695,7 @@ void LoadLootTemplates_Pickpocketing() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u pickpocketing loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty"); } void LoadLootTemplates_Prospecting() @@ -1728,7 +1724,7 @@ void LoadLootTemplates_Prospecting() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u prospecting loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty"); } void LoadLootTemplates_Mail() @@ -1752,7 +1748,7 @@ void LoadLootTemplates_Mail() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u mail loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty"); } void LoadLootTemplates_Skinning() @@ -1786,7 +1782,7 @@ void LoadLootTemplates_Skinning() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u skinning loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty"); } void LoadLootTemplates_Spell() @@ -1828,7 +1824,7 @@ void LoadLootTemplates_Spell() if (count) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); else - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty"); + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty"); } void LoadLootTemplates_Reference() diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index b0a461d7760..6579485a56f 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -39,7 +39,8 @@ namespace Trinity { return uint32(ceil(hk_honor_at_level_f(level, multiplier))); } - } + } // namespace Trinity::Honor + namespace XP { inline uint8 GetGrayLevel(uint8 pl_level) @@ -219,7 +220,7 @@ namespace Trinity sScriptMgr->OnGroupRateCalculation(rate, count, isRaid); return rate; } - } -} + } // namespace Trinity::XP +} // namespace Trinity #endif diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 3d8ad37c92d..9ad1c104e1c 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3162,119 +3162,119 @@ enum EventId enum ResponseCodes { - RESPONSE_SUCCESS = 0x00, - RESPONSE_FAILURE = 0x01, - RESPONSE_CANCELLED = 0x02, - RESPONSE_DISCONNECTED = 0x03, - RESPONSE_FAILED_TO_CONNECT = 0x04, - RESPONSE_CONNECTED = 0x05, - RESPONSE_VERSION_MISMATCH = 0x06, - - CSTATUS_CONNECTING = 0x07, - CSTATUS_NEGOTIATING_SECURITY = 0x08, - CSTATUS_NEGOTIATION_COMPLETE = 0x09, - CSTATUS_NEGOTIATION_FAILED = 0x0A, - CSTATUS_AUTHENTICATING = 0x0B, - - AUTH_OK = 0x0C, - AUTH_FAILED = 0x0D, - AUTH_REJECT = 0x0E, - AUTH_BAD_SERVER_PROOF = 0x0F, - AUTH_UNAVAILABLE = 0x10, - AUTH_SYSTEM_ERROR = 0x11, - AUTH_BILLING_ERROR = 0x12, - AUTH_BILLING_EXPIRED = 0x13, - AUTH_VERSION_MISMATCH = 0x14, - AUTH_UNKNOWN_ACCOUNT = 0x15, - AUTH_INCORRECT_PASSWORD = 0x16, - AUTH_SESSION_EXPIRED = 0x17, - AUTH_SERVER_SHUTTING_DOWN = 0x18, - AUTH_ALREADY_LOGGING_IN = 0x19, - AUTH_LOGIN_SERVER_NOT_FOUND = 0x1A, - AUTH_WAIT_QUEUE = 0x1B, - AUTH_BANNED = 0x1C, - AUTH_ALREADY_ONLINE = 0x1D, - AUTH_NO_TIME = 0x1E, - AUTH_DB_BUSY = 0x1F, - AUTH_SUSPENDED = 0x20, - AUTH_PARENTAL_CONTROL = 0x21, - AUTH_LOCKED_ENFORCED = 0x22, - - REALM_LIST_IN_PROGRESS = 0x23, - REALM_LIST_SUCCESS = 0x24, - REALM_LIST_FAILED = 0x25, - REALM_LIST_INVALID = 0x26, - REALM_LIST_REALM_NOT_FOUND = 0x27, - - ACCOUNT_CREATE_IN_PROGRESS = 0x28, - ACCOUNT_CREATE_SUCCESS = 0x29, - ACCOUNT_CREATE_FAILED = 0x2A, - - CHAR_LIST_RETRIEVING = 0x2B, - CHAR_LIST_RETRIEVED = 0x2C, - CHAR_LIST_FAILED = 0x2D, - - CHAR_CREATE_IN_PROGRESS = 0x2E, - CHAR_CREATE_SUCCESS = 0x2F, - CHAR_CREATE_ERROR = 0x30, - CHAR_CREATE_FAILED = 0x31, - CHAR_CREATE_NAME_IN_USE = 0x32, - CHAR_CREATE_DISABLED = 0x33, - CHAR_CREATE_PVP_TEAMS_VIOLATION = 0x34, - CHAR_CREATE_SERVER_LIMIT = 0x35, - CHAR_CREATE_ACCOUNT_LIMIT = 0x36, - CHAR_CREATE_SERVER_QUEUE = 0x37, - CHAR_CREATE_ONLY_EXISTING = 0x38, - CHAR_CREATE_EXPANSION = 0x39, - CHAR_CREATE_EXPANSION_CLASS = 0x3A, - CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B, - CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C, - CHAR_CREATE_CHARACTER_IN_GUILD = 0x3D, - CHAR_CREATE_RESTRICTED_RACECLASS = 0x3E, - CHAR_CREATE_CHARACTER_CHOOSE_RACE = 0x3F, - CHAR_CREATE_CHARACTER_ARENA_LEADER = 0x40, - CHAR_CREATE_CHARACTER_DELETE_MAIL = 0x41, - CHAR_CREATE_CHARACTER_SWAP_FACTION = 0x42, - CHAR_CREATE_CHARACTER_RACE_ONLY = 0x43, - CHAR_CREATE_CHARACTER_GOLD_LIMIT = 0x44, - CHAR_CREATE_FORCE_LOGIN = 0x45, - - CHAR_DELETE_IN_PROGRESS = 0x46, - CHAR_DELETE_SUCCESS = 0x47, - CHAR_DELETE_FAILED = 0x48, - CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x49, - CHAR_DELETE_FAILED_GUILD_LEADER = 0x4A, - CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x4B, - - CHAR_LOGIN_IN_PROGRESS = 0x4C, - CHAR_LOGIN_SUCCESS = 0x4D, - CHAR_LOGIN_NO_WORLD = 0x4E, - CHAR_LOGIN_DUPLICATE_CHARACTER = 0x4F, - CHAR_LOGIN_NO_INSTANCES = 0x50, - CHAR_LOGIN_FAILED = 0x51, - CHAR_LOGIN_DISABLED = 0x52, - CHAR_LOGIN_NO_CHARACTER = 0x53, - CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x54, - CHAR_LOGIN_LOCKED_BY_BILLING = 0x55, - CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 0x56, - - CHAR_NAME_SUCCESS = 0x57, - CHAR_NAME_FAILURE = 0x58, - CHAR_NAME_NO_NAME = 0x59, - CHAR_NAME_TOO_SHORT = 0x5A, - CHAR_NAME_TOO_LONG = 0x5B, - CHAR_NAME_INVALID_CHARACTER = 0x5C, - CHAR_NAME_MIXED_LANGUAGES = 0x5D, - CHAR_NAME_PROFANE = 0x5E, - CHAR_NAME_RESERVED = 0x5F, - CHAR_NAME_INVALID_APOSTROPHE = 0x60, - CHAR_NAME_MULTIPLE_APOSTROPHES = 0x61, - CHAR_NAME_THREE_CONSECUTIVE = 0x62, - CHAR_NAME_INVALID_SPACE = 0x63, - CHAR_NAME_CONSECUTIVE_SPACES = 0x64, - CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x65, - CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x66, - CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x67 + RESPONSE_SUCCESS = 0, + RESPONSE_FAILURE = 1, + RESPONSE_CANCELLED = 2, + RESPONSE_DISCONNECTED = 3, + RESPONSE_FAILED_TO_CONNECT = 4, + RESPONSE_CONNECTED = 5, + RESPONSE_VERSION_MISMATCH = 6, + + CSTATUS_CONNECTING = 7, + CSTATUS_NEGOTIATING_SECURITY = 8, + CSTATUS_NEGOTIATION_COMPLETE = 9, + CSTATUS_NEGOTIATION_FAILED = 10, + CSTATUS_AUTHENTICATING = 11, + + AUTH_OK = 12, + AUTH_FAILED = 13, + AUTH_REJECT = 14, + AUTH_BAD_SERVER_PROOF = 15, + AUTH_UNAVAILABLE = 16, + AUTH_SYSTEM_ERROR = 17, + AUTH_BILLING_ERROR = 18, + AUTH_BILLING_EXPIRED = 19, + AUTH_VERSION_MISMATCH = 20, + AUTH_UNKNOWN_ACCOUNT = 21, + AUTH_INCORRECT_PASSWORD = 22, + AUTH_SESSION_EXPIRED = 23, + AUTH_SERVER_SHUTTING_DOWN = 24, + AUTH_ALREADY_LOGGING_IN = 25, + AUTH_LOGIN_SERVER_NOT_FOUND = 26, + AUTH_WAIT_QUEUE = 27, + AUTH_BANNED = 28, + AUTH_ALREADY_ONLINE = 29, + AUTH_NO_TIME = 30, + AUTH_DB_BUSY = 31, + AUTH_SUSPENDED = 32, + AUTH_PARENTAL_CONTROL = 33, + AUTH_LOCKED_ENFORCED = 34, + + REALM_LIST_IN_PROGRESS = 35, + REALM_LIST_SUCCESS = 36, + REALM_LIST_FAILED = 37, + REALM_LIST_INVALID = 38, + REALM_LIST_REALM_NOT_FOUND = 39, + + ACCOUNT_CREATE_IN_PROGRESS = 40, + ACCOUNT_CREATE_SUCCESS = 41, + ACCOUNT_CREATE_FAILED = 42, + + CHAR_LIST_RETRIEVING = 43, + CHAR_LIST_RETRIEVED = 44, + CHAR_LIST_FAILED = 45, + + CHAR_CREATE_IN_PROGRESS = 46, + CHAR_CREATE_SUCCESS = 47, + CHAR_CREATE_ERROR = 48, + CHAR_CREATE_FAILED = 49, + CHAR_CREATE_NAME_IN_USE = 50, + CHAR_CREATE_DISABLED = 51, + CHAR_CREATE_PVP_TEAMS_VIOLATION = 52, + CHAR_CREATE_SERVER_LIMIT = 53, + CHAR_CREATE_ACCOUNT_LIMIT = 54, + CHAR_CREATE_SERVER_QUEUE = 55, + CHAR_CREATE_ONLY_EXISTING = 56, + CHAR_CREATE_EXPANSION = 57, + CHAR_CREATE_EXPANSION_CLASS = 58, + CHAR_CREATE_LEVEL_REQUIREMENT = 59, + CHAR_CREATE_UNIQUE_CLASS_LIMIT = 60, + CHAR_CREATE_CHARACTER_IN_GUILD = 61, + CHAR_CREATE_RESTRICTED_RACECLASS = 62, + CHAR_CREATE_CHARACTER_CHOOSE_RACE = 63, + CHAR_CREATE_CHARACTER_ARENA_LEADER = 64, + CHAR_CREATE_CHARACTER_DELETE_MAIL = 65, + CHAR_CREATE_CHARACTER_SWAP_FACTION = 66, + CHAR_CREATE_CHARACTER_RACE_ONLY = 67, + CHAR_CREATE_CHARACTER_GOLD_LIMIT = 68, + CHAR_CREATE_FORCE_LOGIN = 69, + + CHAR_DELETE_IN_PROGRESS = 70, + CHAR_DELETE_SUCCESS = 71, + CHAR_DELETE_FAILED = 72, + CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 73, + CHAR_DELETE_FAILED_GUILD_LEADER = 74, + CHAR_DELETE_FAILED_ARENA_CAPTAIN = 75, + + CHAR_LOGIN_IN_PROGRESS = 76, + CHAR_LOGIN_SUCCESS = 77, + CHAR_LOGIN_NO_WORLD = 78, + CHAR_LOGIN_DUPLICATE_CHARACTER = 79, + CHAR_LOGIN_NO_INSTANCES = 80, + CHAR_LOGIN_FAILED = 81, + CHAR_LOGIN_DISABLED = 82, + CHAR_LOGIN_NO_CHARACTER = 83, + CHAR_LOGIN_LOCKED_FOR_TRANSFER = 84, + CHAR_LOGIN_LOCKED_BY_BILLING = 85, + CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 86, + + CHAR_NAME_SUCCESS = 87, + CHAR_NAME_FAILURE = 88, + CHAR_NAME_NO_NAME = 89, + CHAR_NAME_TOO_SHORT = 90, + CHAR_NAME_TOO_LONG = 91, + CHAR_NAME_INVALID_CHARACTER = 92, + CHAR_NAME_MIXED_LANGUAGES = 93, + CHAR_NAME_PROFANE = 94, + CHAR_NAME_RESERVED = 95, + CHAR_NAME_INVALID_APOSTROPHE = 96, + CHAR_NAME_MULTIPLE_APOSTROPHES = 97, + CHAR_NAME_THREE_CONSECUTIVE = 98, + CHAR_NAME_INVALID_SPACE = 99, + CHAR_NAME_CONSECUTIVE_SPACES = 100, + CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 101, + CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 102, + CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 103 }; /// Ban function modes diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp index 6f9da3931af..6fba8308077 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.cpp +++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp @@ -48,8 +48,7 @@ void WaypointMgr::Load() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 waypoints. DB table `waypoint_data` is empty!"); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 waypoints. DB table `waypoint_data` is empty!"); return; } @@ -87,7 +86,6 @@ void WaypointMgr::Load() while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u waypoints in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } void WaypointMgr::ReloadPath(uint32 id) diff --git a/src/server/game/Skills/SkillDiscovery.cpp b/src/server/game/Skills/SkillDiscovery.cpp index 8b5ae4863d0..e6ba28d5f1c 100644 --- a/src/server/game/Skills/SkillDiscovery.cpp +++ b/src/server/game/Skills/SkillDiscovery.cpp @@ -55,8 +55,7 @@ void LoadSkillDiscoveryTable() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty."); return; } @@ -154,7 +153,6 @@ void LoadSkillDiscoveryTable() } sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u skill discovery definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player) diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp index 090e2e8205a..5c3b69e48d2 100644 --- a/src/server/game/Skills/SkillExtraItems.cpp +++ b/src/server/game/Skills/SkillExtraItems.cpp @@ -60,8 +60,7 @@ void LoadSkillExtraItemTable() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 spell specialization definitions. DB table `skill_extra_item_template` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell specialization definitions. DB table `skill_extra_item_template` is empty."); return; } @@ -75,28 +74,28 @@ void LoadSkillExtraItemTable() if (!sSpellMgr->GetSpellInfo(spellId)) { - sLog->outError(LOG_FILTER_GENERAL, "Skill specialization %u has non-existent spell id in `skill_extra_item_template`!", spellId); + sLog->outError(LOG_FILTER_SQL, "Skill specialization %u has non-existent spell id in `skill_extra_item_template`!", spellId); continue; } uint32 requiredSpecialization = fields[1].GetUInt32(); if (!sSpellMgr->GetSpellInfo(requiredSpecialization)) { - sLog->outError(LOG_FILTER_GENERAL, "Skill specialization %u have not existed required specialization spell id %u in `skill_extra_item_template`!", spellId, requiredSpecialization); + sLog->outError(LOG_FILTER_SQL, "Skill specialization %u have not existed required specialization spell id %u in `skill_extra_item_template`!", spellId, requiredSpecialization); continue; } float additionalCreateChance = fields[2].GetFloat(); if (additionalCreateChance <= 0.0f) { - sLog->outError(LOG_FILTER_GENERAL, "Skill specialization %u has too low additional create chance in `skill_extra_item_template`!", spellId); + sLog->outError(LOG_FILTER_SQL, "Skill specialization %u has too low additional create chance in `skill_extra_item_template`!", spellId); continue; } uint8 additionalMaxNum = fields[3].GetUInt8(); if (!additionalMaxNum) { - sLog->outError(LOG_FILTER_GENERAL, "Skill specialization %u has 0 max number of extra items in `skill_extra_item_template`!", spellId); + sLog->outError(LOG_FILTER_SQL, "Skill specialization %u has 0 max number of extra items in `skill_extra_item_template`!", spellId); continue; } @@ -111,7 +110,6 @@ void LoadSkillExtraItemTable() while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell specialization definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } bool canCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax) diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index b96cb1156c2..ec271192450 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -44,7 +44,6 @@ void WardenCheckMgr::LoadWardenChecks() if (!sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) { sLog->outInfo(LOG_FILTER_WARDEN, ">> Warden disabled, loading checks skipped."); - return; } @@ -52,8 +51,7 @@ void WardenCheckMgr::LoadWardenChecks() if (!result) { - sLog->outInfo(LOG_FILTER_WARDEN, ">> Loaded 0 Warden checks. DB table `warden_checks` is empty!"); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 Warden checks. DB table `warden_checks` is empty!"); return; } @@ -145,8 +143,7 @@ void WardenCheckMgr::LoadWardenChecks() } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_WARDEN, ">> Loaded %u warden checks.", count); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u warden checks.", count); } void WardenCheckMgr::LoadWardenOverrides() @@ -155,7 +152,6 @@ void WardenCheckMgr::LoadWardenOverrides() if (!sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) { sLog->outInfo(LOG_FILTER_WARDEN, ">> Warden disabled, loading check overrides skipped."); - return; } @@ -164,8 +160,7 @@ void WardenCheckMgr::LoadWardenOverrides() if (!result) { - sLog->outInfo(LOG_FILTER_WARDEN, ">> Loaded 0 Warden action overrides. DB table `warden_action` is empty!"); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 Warden action overrides. DB table `warden_action` is empty!"); return; } @@ -194,8 +189,7 @@ void WardenCheckMgr::LoadWardenOverrides() } while (result->NextRow()); - sLog->outInfo(LOG_FILTER_WARDEN, ">> Loaded %u warden action overrides.", count); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u warden action overrides.", count); } WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id) diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 802cdb8209f..769e40b4dff 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -96,8 +96,7 @@ void LoadWeatherData() if (!result) { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 weather definitions. DB table `game_weather` is empty."); - + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 weather definitions. DB table `game_weather` is empty."); return; } @@ -141,7 +140,6 @@ void LoadWeatherData() while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u weather definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } void SendFineWeatherUpdateToPlayer(Player* player) diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index 44fa0f87177..d0eefd67392 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -314,7 +314,7 @@ class npc_harrison_jones : public CreatureScript me->SetEntry(NPC_HARRISON_JONES_2); me->SetDisplayId(MODEL_HARRISON_JONES_2); me->SetTarget(0); - me->SetByteValue(UNIT_FIELD_BYTES_1, 0,UNIT_STAND_STATE_DEAD); + me->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_DEAD); me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); if (instance) instance->SetData(DATA_GONGEVENT, DONE); diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index d0c3490bc2d..f4e4ce7fe06 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -116,7 +116,7 @@ #define I32FMT "%08I32X" #define I64FMT "%016I64X" #define snprintf _snprintf -#define atoll __atoi64 +#define atoll _atoi64 #define vsnprintf _vsnprintf #define finite(X) _finite(X) #define llabs _abs64 -- cgit v1.2.3 From 760d62e934f8289cdd9950c04a4dbf588eddd742 Mon Sep 17 00:00:00 2001 From: Bezo Date: Wed, 30 Jan 2013 13:09:41 +0200 Subject: Add Mute reason and mute by to the db so you can get this info from the db with the pinfo command when player get muted. old LOGIN_UPD_MUTE_TIME change to LOGIN_UPD_MUTE_TIME_LOGIN due the use of it when character login to world. --- sql/base/auth_database.sql | 2 ++ sql/updates/auth/2013_xx_xx_00_auth_account.sql | 3 +++ .../world/2013_xx_xx_00_world_trinity_string.sql | 4 ++++ src/server/game/Server/WorldSocket.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 21 +++++++++++++++++---- .../Database/Implementation/LoginDatabase.cpp | 5 +++-- .../shared/Database/Implementation/LoginDatabase.h | 1 + 7 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 sql/updates/auth/2013_xx_xx_00_auth_account.sql create mode 100644 sql/updates/world/2013_xx_xx_00_world_trinity_string.sql (limited to 'src') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 5050906b008..e5ba6356da9 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -38,6 +38,8 @@ CREATE TABLE `account` ( `online` tinyint(3) unsigned NOT NULL DEFAULT '0', `expansion` tinyint(3) unsigned NOT NULL DEFAULT '2', `mutetime` bigint(20) NOT NULL DEFAULT '0', + `mutereason` VARCHAR(255) NOT NULL DEFAULT '', + `muteby` VARCHAR(50) NOT NULL DEFAULT '', `locale` tinyint(3) unsigned NOT NULL DEFAULT '0', `os` varchar(3) NOT NULL DEFAULT '', `recruiter` int(10) unsigned NOT NULL DEFAULT '0', diff --git a/sql/updates/auth/2013_xx_xx_00_auth_account.sql b/sql/updates/auth/2013_xx_xx_00_auth_account.sql new file mode 100644 index 00000000000..fa893915716 --- /dev/null +++ b/sql/updates/auth/2013_xx_xx_00_auth_account.sql @@ -0,0 +1,3 @@ +ALTER TABLE `account` + ADD COLUMN `mutereason` VARCHAR(255) NOT NULL DEFAULT '' AFTER `mutetime`, + ADD COLUMN `muteby` VARCHAR(50) NOT NULL DEFAULT '' AFTER `mutereason`; \ No newline at end of file diff --git a/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql new file mode 100644 index 00000000000..5c531a0895d --- /dev/null +++ b/sql/updates/world/2013_xx_xx_00_world_trinity_string.sql @@ -0,0 +1,4 @@ +DELETE FROM `trinity_string` WHERE entry IN (300,550); +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES +('300','Your chat has been disabled for %u minutes. By: %s ,Reason: %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +('550','Mute time remaining: %s, By: %s, Reason: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); \ No newline at end of file diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index c80d25be139..74c2dceadf0 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -837,7 +837,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { mutetime = time(NULL) + llabs(mutetime); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); stmt->setUInt32(1, id); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 367591080d2..973d466bab5 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1550,6 +1550,8 @@ public: std::string userName = handler->GetTrinityString(LANG_ERROR); std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string muteReason = ""; + std::string muteBy = ""; std::string lastIp = handler->GetTrinityString(LANG_ERROR); uint32 security = 0; std::string lastLogin = handler->GetTrinityString(LANG_ERROR); @@ -1566,6 +1568,8 @@ public: security = fields[1].GetUInt8(); eMail = fields[2].GetString(); muteTime = fields[5].GetUInt64(); + muteReason = fields[6].GetString(); + muteBy = fields[7].GetString(); if (eMail.empty()) eMail = "-"; @@ -1627,7 +1631,7 @@ public: } if (muteTime > 0) - handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str(), muteBy.c_str(), muteReason.c_str()); if (banTime >= 0) handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); @@ -1826,6 +1830,11 @@ public: return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + std::string muteBy = ""; + if (handler->GetSession()) + muteBy = handler->GetSession()->GetPlayerName(); + else + muteBy = "Console"; if (target) { @@ -1833,7 +1842,7 @@ public: int64 muteTime = time(NULL) + notSpeakTime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); } else { @@ -1842,7 +1851,9 @@ public: stmt->setInt64(0, muteTime); } - stmt->setUInt32(1, accountId); + stmt->setString(1, muteReasonStr.c_str()); + stmt->setString(2, muteBy.c_str()); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); @@ -1885,7 +1896,9 @@ public: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); - stmt->setUInt32(1, accountId); + stmt->setString(1, ""); + stmt->setString(2, ""); + stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); if (target) diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 227680b2d6b..4e1d448a21f 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -62,7 +62,8 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_MUTE_TIME_LOGIN, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_LAST_IP, "UPDATE account SET last_ip = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_ONLINE, "UPDATE account SET online = 1 WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_UPTIME_PLAYERS, "UPDATE uptime SET uptime = ?, maxplayers = ? WHERE realmid = ? AND starttime = ?", CONNECTION_ASYNC); @@ -76,7 +77,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 798016d553d..4199bd5556a 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -83,6 +83,7 @@ enum LoginDatabaseStatements LOGIN_UPD_USERNAME, LOGIN_UPD_PASSWORD, LOGIN_UPD_MUTE_TIME, + LOGIN_UPD_MUTE_TIME_LOGIN, LOGIN_UPD_LAST_IP, LOGIN_UPD_ACCOUNT_ONLINE, LOGIN_UPD_UPTIME_PLAYERS, -- cgit v1.2.3 From 8814d8c136439bd2b94fe7d55011114dba55a9b0 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 30 Jan 2013 18:06:19 +0100 Subject: Script/ToCr: Fix crash for lord jaraxxus Mistress Kiss + cleanup --- .../EasternKingdoms/ScarletEnclave/chapter2.cpp | 4 +- .../TrialOfTheCrusader/boss_lord_jaraxxus.cpp | 55 ++++++++++------------ 2 files changed, 28 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp index a4c11209e52..f508266434b 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp @@ -339,14 +339,14 @@ public: waveTimer -= uiDiff; } } - + private: uint8 wave; uint32 waveTimer; uint64 valrothGUID; }; - + CreatureAI* GetAI(Creature* creature) const { return new npc_koltira_deathweaverAI(creature); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 82cff5ff01f..f3947bdd7a0 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -69,7 +69,6 @@ enum BossSpells SPELL_FEL_INFERNO = 67047, SPELL_FEL_STREAK = 66494, SPELL_LORD_HITTIN = 66326, // special effect preventing more specific spells be cast on the same player within 10 seconds - SPELL_MISTRESS_KISS_DEBUFF = 66334, SPELL_MISTRESS_KISS_DAMAGE_SILENCE = 66359 }; @@ -533,6 +532,21 @@ class spell_mistress_kiss : public SpellScriptLoader } }; +class MistressKissTargetSelector +{ + public: + MistressKissTargetSelector() { } + + bool operator()(WorldObject* unit) const + { + if (unit->GetTypeId() == TYPEID_PLAYER) + if (unit->ToPlayer()->getPowerType() == POWER_MANA) + return false; + + return true; + } +}; + class spell_mistress_kiss_area : public SpellScriptLoader { public: @@ -542,44 +556,27 @@ class spell_mistress_kiss_area : public SpellScriptLoader { PrepareSpellScript(spell_mistress_kiss_area_SpellScript) - bool Load() + void FilterTargets(std::list& targets) { - if (GetCaster()) - if (sSpellMgr->GetSpellIdForDifficulty(SPELL_MISTRESS_KISS_DEBUFF, GetCaster())) - return true; - return false; - } + // get a list of players with mana + targets.remove_if(MistressKissTargetSelector()); + if (targets.empty()) + return; - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - if (caster && target) - caster->CastSpell(target, SPELL_MISTRESS_KISS_DEBUFF, true); + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); } - void FilterTargets(std::list& targets) + void HandleScript(SpellEffIndex /*effIndex*/) { - // get a list of players with mana - std::list _targets; - for (std::list::iterator itr = targets.begin(); itr != targets.end(); ++itr) - if ((*itr)->ToUnit()->getPowerType() == POWER_MANA) - _targets.push_back(*itr); - - // pick a random target and kiss him - if (WorldObject* _target = Trinity::Containers::SelectRandomContainerElement(_targets)) - { - // correctly fill "targets" for the visual effect - targets.clear(); - targets.push_back(_target); - if (Unit* caster = GetCaster()) - caster->CastSpell(_target->ToUnit(), SPELL_MISTRESS_KISS_DEBUFF, true); - } + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); } void Register() { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mistress_kiss_area_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mistress_kiss_area_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; -- cgit v1.2.3 From 5a74336c5ed82b4691923947d7f75fcd72e1f1be Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 30 Jan 2013 18:24:29 +0100 Subject: Core: Fix non pch build --- .../CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index f3947bdd7a0..073ebb0a35f 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -18,8 +18,9 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "trial_of_the_crusader.h" #include "SpellScript.h" +#include "Player.h" +#include "trial_of_the_crusader.h" enum Yells { -- cgit v1.2.3 From dbecf05e39204ff46621ce46bf5dd181e6450eeb Mon Sep 17 00:00:00 2001 From: Gacko Date: Wed, 23 Jan 2013 19:43:51 +0100 Subject: Core: Logical fixes and improvements in EventMap --- src/server/game/AI/CreatureAIImpl.h | 39 ++++++++++++++++++---- .../EasternKingdoms/ZulGurub/boss_thekal.cpp | 2 +- .../RubySanctum/boss_baltharus_the_warborn.cpp | 11 +++--- .../ChamberOfAspects/RubySanctum/boss_halion.cpp | 21 +++++------- .../TrialOfTheCrusader/boss_anubarak_trial.cpp | 8 ++--- .../TrialOfTheCrusader/boss_northrend_beasts.cpp | 9 ++--- .../FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp | 2 +- .../PitOfSaron/boss_forgemaster_garfrost.cpp | 22 +++++------- .../PitOfSaron/boss_scourgelord_tyrannus.cpp | 8 ++--- .../IcecrownCitadel/boss_deathbringer_saurfang.cpp | 10 +++--- .../IcecrownCitadel/boss_lady_deathwhisper.cpp | 13 +++----- .../IcecrownCitadel/boss_professor_putricide.cpp | 13 +++----- .../IcecrownCitadel/boss_the_lich_king.cpp | 34 +++++++------------ .../Ulduar/Ulduar/boss_algalon_the_observer.cpp | 11 +++--- .../UtgardeKeep/boss_ingvar_the_plunderer.cpp | 4 +-- 15 files changed, 99 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 559240c4a3f..2b182901c8a 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -336,21 +336,35 @@ class EventMap // Sets event phase, must be in range 1 - 8 void SetPhase(uint32 phase) { - if (phase && phase < 8) - _phase = (1 << (phase + 24)); + if (phase && phase <= 8) + _phase = (1 << (phase + 23)); else if (!phase) _phase = 0; } + // Activates event phase, must be in range 1 - 8 + void AddPhase(uint32 phase) + { + if (phase && phase <= 8) + _phase |= (1 << (phase + 23)); + } + + // Deactivates event phase, must be in range 1 - 8 + void RemovePhase(uint32 phase) + { + if (phase && phase <= 8) + _phase &= ~(1 << (phase + 23)); + } + // Creates new event entry in map with given id, time, group if given (1 - 8) and phase if given (1 - 8) // 0 for group/phase means it belongs to no group or runs in all phases void ScheduleEvent(uint32 eventId, uint32 time, uint32 groupId = 0, uint32 phase = 0) { time += _time; if (groupId && groupId < 9) - eventId |= (1 << (groupId + 16)); + eventId |= (1 << (groupId + 15)); if (phase && phase < 8) - eventId |= (1 << (phase + 24)); + eventId |= (1 << (phase + 23)); StorageType::const_iterator itr = _eventMap.find(time); while (itr != _eventMap.end()) { @@ -443,8 +457,12 @@ class EventMap // Delay all events having the specified Group void DelayEvents(uint32 delay, uint32 groupId) { + if (!groupId || groupId > 8) + return; + uint32 nextTime = _time + delay; - uint32 groupMask = (1 << (groupId + 16)); + uint32 groupMask = (1 << (groupId + 15)); + for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end() && itr->first < nextTime;) { if (itr->second & groupMask) @@ -476,7 +494,10 @@ class EventMap // Cancel events belonging to specified group void CancelEventGroup(uint32 groupId) { - uint32 groupMask = (1 << (groupId + 16)); + if (!groupId || groupId > 8) + return; + + uint32 groupMask = (1 << (groupId + 15)); for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { @@ -501,6 +522,12 @@ class EventMap return 0; } + // Returns wether the eventmap is in the given phase or not. + bool IsInPhase(uint32 phase) + { + return phase <= 8 && (!phase || _phase & (1 << phase + 23)); + } + private: uint32 _time; uint32 _phase; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp index 61eb695719a..26322be76ca 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp @@ -232,7 +232,7 @@ class boss_thekal : public CreatureScript if (me->IsFullHealth() && WasDead) WasDead = false; - if ((events.GetPhaseMask() == PHASE_ONE) && !WasDead && !HealthAbovePct(5)) + if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5)) { me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp index 205a0b10d69..70c1141b6e6 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp @@ -61,9 +61,7 @@ enum Phases { PHASE_ALL = 0, PHASE_INTRO = 1, - PHASE_COMBAT = 2, - - PHASE_INTRO_MASK = 1 << PHASE_INTRO, + PHASE_COMBAT = 2 }; class boss_baltharus_the_warborn : public CreatureScript @@ -166,15 +164,16 @@ class boss_baltharus_the_warborn : public CreatureScript void UpdateAI(uint32 const diff) { - if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) + bool introPhase = events.IsInPhase(PHASE_INTRO); + if (!UpdateVictim() && !introPhase) return; - if (!(events.GetPhaseMask() & PHASE_INTRO_MASK)) + if (!introPhase) me->SetHealth(instance->GetData(DATA_BALTHARUS_SHARED_HEALTH)); events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) + if (me->HasUnitState(UNIT_STATE_CASTING) && !introPhase) return; while (uint32 eventId = events.ExecuteEvent()) diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 6039e01b901..d31c2ead82d 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -165,12 +165,7 @@ enum Phases PHASE_INTRO = 1, PHASE_ONE = 2, PHASE_TWO = 3, - PHASE_THREE = 4, - - PHASE_INTRO_MASK = 1 << PHASE_INTRO, - PHASE_ONE_MASK = 1 << PHASE_ONE, - PHASE_TWO_MASK = 1 << PHASE_TWO, - PHASE_THREE_MASK = 1 << PHASE_THREE + PHASE_THREE = 4 }; enum Misc @@ -325,7 +320,7 @@ class boss_halion : public CreatureScript void EnterEvadeMode() { // Phase 1: We always can evade. Phase 2 & 3: We can evade if and only if the controller tells us to. - if ((events.GetPhaseMask() & PHASE_ONE_MASK) || _canEvade) + if (events.IsInPhase(PHASE_ONE) || _canEvade) generic_halionAI::EnterEvadeMode(); } @@ -369,7 +364,7 @@ class boss_halion : public CreatureScript void DamageTaken(Unit* attacker, uint32& damage) { - if (me->HealthBelowPctDamaged(75, damage) && (events.GetPhaseMask() & PHASE_ONE_MASK)) + if (me->HealthBelowPctDamaged(75, damage) && events.IsInPhase(PHASE_ONE)) { events.SetPhase(PHASE_TWO); Talk(SAY_PHASE_TWO); @@ -383,7 +378,7 @@ class boss_halion : public CreatureScript return; } - if (events.GetPhaseMask() & PHASE_THREE_MASK) + if (events.IsInPhase(PHASE_THREE)) { // Don't consider copied damage. if (!me->InSamePhase(attacker)) @@ -396,7 +391,7 @@ class boss_halion : public CreatureScript void UpdateAI(uint32 const diff) { - if (events.GetPhaseMask() & PHASE_TWO_MASK) + if (events.IsInPhase(PHASE_TWO)) return; generic_halionAI::UpdateAI(diff); @@ -528,7 +523,7 @@ class boss_twilight_halion : public CreatureScript void DamageTaken(Unit* attacker, uint32& damage) { - if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_TWO_MASK)) + if (me->HealthBelowPctDamaged(50, damage) && events.IsInPhase(PHASE_TWO)) { events.SetPhase(PHASE_THREE); me->CastStop(); @@ -537,7 +532,7 @@ class boss_twilight_halion : public CreatureScript return; } - if (events.GetPhaseMask() & PHASE_THREE_MASK) + if (events.IsInPhase(PHASE_THREE)) { // Don't consider copied damage. if (!me->InSamePhase(attacker)) @@ -693,7 +688,7 @@ class npc_halion_controller : public CreatureScript // The isInCombat() check is needed because that check should be false when Halion is // not engaged, while it would return true without as UpdateVictim() checks for // combat state. - if (!(_events.GetPhaseMask() & PHASE_INTRO_MASK) && me->isInCombat() && !UpdateVictim()) + if (!(_events.IsInPhase(PHASE_INTRO)) && me->isInCombat() && !UpdateVictim()) { EnterEvadeMode(); return; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index e44f5fba1b8..17b804ca31e 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -154,9 +154,7 @@ enum Phases { // Anub'arak PHASE_MELEE = 1, - PHASE_SUBMERGED = 2, - - PHASE_MASK_MELEE = 1 << PHASE_MELEE + PHASE_SUBMERGED = 2 }; class boss_anubarak_trial : public CreatureScript @@ -403,7 +401,7 @@ class boss_anubarak_trial : public CreatureScript } - if (HealthBelowPct(30) && events.GetPhaseMask() & PHASE_MASK_MELEE && !_reachedPhase3) + if (HealthBelowPct(30) && events.IsInPhase(PHASE_MELEE) && !_reachedPhase3) { _reachedPhase3 = true; DoCastAOE(SPELL_LEECHING_SWARM); @@ -411,7 +409,7 @@ class boss_anubarak_trial : public CreatureScript Talk(SAY_LEECHING_SWARM); } - if (events.GetPhaseMask() & PHASE_MASK_MELEE) + if (events.IsInPhase(PHASE_MELEE)) DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index 03a305356c4..95f59903141 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -146,10 +146,7 @@ enum Phases { PHASE_MOBILE = 1, PHASE_STATIONARY = 2, - PHASE_SUBMERGED = 3, - - PHASE_MASK_MOBILE = 1 << PHASE_MOBILE, - PHASE_MASK_STATIONARY = 1 << PHASE_STATIONARY + PHASE_SUBMERGED = 3 }; class boss_gormok : public CreatureScript @@ -624,9 +621,9 @@ struct boss_jormungarAI : public BossAI return; } } - if (events.GetPhaseMask() & PHASE_MASK_MOBILE) + if (events.IsInPhase(PHASE_MOBILE)) DoMeleeAttackIfReady(); - if (events.GetPhaseMask() & PHASE_MASK_STATIONARY) + if (events.IsInPhase(PHASE_STATIONARY)) DoSpellAttackIfReady(SpitSpell); } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 261eb854aa3..5d261fd3804 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -118,7 +118,7 @@ class boss_bronjahm : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - if (events.GetPhaseMask() & (1 << PHASE_1) && !HealthAbovePct(30)) + if (events.IsInPhase(PHASE_1) && !HealthAbovePct(30)) { events.SetPhase(PHASE_2); DoCast(me, SPELL_TELEPORT); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp index 160d45f5140..cc25e450340 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp @@ -52,11 +52,7 @@ enum Phases { PHASE_ONE = 1, PHASE_TWO = 2, - PHASE_THREE = 3, - - PHASE_ONE_MASK = 1 << PHASE_ONE, - PHASE_TWO_MASK = 1 << PHASE_TWO, - PHASE_THREE_MASK = 1 << PHASE_THREE, + PHASE_THREE = 3 }; enum MiscData @@ -136,7 +132,7 @@ enum Events void DamageTaken(Unit* /*attacker*/, uint32& /*uiDamage*/) { - if (events.GetPhaseMask() & PHASE_ONE_MASK && !HealthAbovePct(66)) + if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(66)) { events.SetPhase(PHASE_TWO); Talk(SAY_PHASE2); @@ -146,7 +142,7 @@ enum Events return; } - if (events.GetPhaseMask() & PHASE_TWO_MASK && !HealthAbovePct(33)) + if (events.IsInPhase(PHASE_TWO) && !HealthAbovePct(33)) { events.SetPhase(PHASE_THREE); Talk(SAY_PHASE3); @@ -162,12 +158,12 @@ enum Events if (type != EFFECT_MOTION_TYPE || id != POINT_FORGE) return; - if (events.GetPhaseMask() & PHASE_TWO_MASK) + if (events.IsInPhase(PHASE_TWO)) { DoCast(me, SPELL_FORGE_BLADE); SetEquipmentSlots(false, EQUIP_ID_SWORD); } - if (events.GetPhaseMask() & PHASE_THREE_MASK) + if (events.IsInPhase(PHASE_THREE)) { me->RemoveAurasDueToSpell(SPELL_FORGE_BLADE_HELPER); DoCast(me, SPELL_FORGE_MACE); @@ -226,15 +222,15 @@ enum Events break; case EVENT_JUMP: me->AttackStop(); - if (events.GetPhaseMask() & PHASE_TWO_MASK) + if (events.IsInPhase(PHASE_TWO)) me->GetMotionMaster()->MoveJump(northForgePos.GetPositionX(), northForgePos.GetPositionY(), northForgePos.GetPositionZ(), 25.0f, 15.0f); - else if (events.GetPhaseMask() & PHASE_THREE_MASK) + else if (events.IsInPhase(PHASE_THREE)) me->GetMotionMaster()->MoveJump(southForgePos.GetPositionX(), southForgePos.GetPositionY(), southForgePos.GetPositionZ(), 25.0f, 15.0f); break; case EVENT_RESUME_ATTACK: - if (events.GetPhaseMask() & PHASE_TWO_MASK) + if (events.IsInPhase(PHASE_THREE)) events.ScheduleEvent(EVENT_CHILLING_WAVE, 5000, 0, PHASE_TWO); - else if (events.GetPhaseMask() & PHASE_THREE_MASK) + else if (events.IsInPhase(PHASE_THREE)) events.ScheduleEvent(EVENT_DEEP_FREEZE, 10000, 0, PHASE_THREE); AttackStart(me->getVictim()); break; diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index 783cc266509..165cd8d647a 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -94,7 +94,7 @@ enum Phases PHASE_NONE = 0, PHASE_INTRO = 1, PHASE_COMBAT = 2, - PHASE_OUTRO = 3, + PHASE_OUTRO = 3 }; enum Actions @@ -168,7 +168,7 @@ class boss_tyrannus : public CreatureScript if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; - if (victim && me->Attack(victim, true) && !(events.GetPhaseMask() & (1 << PHASE_INTRO))) + if (victim && me->Attack(victim, true) && !events.IsInPhase(PHASE_INTRO)) me->GetMotionMaster()->MoveChase(victim); } @@ -217,7 +217,7 @@ class boss_tyrannus : public CreatureScript void UpdateAI(const uint32 diff) { - if (!UpdateVictim() && !(events.GetPhaseMask() & (1 << PHASE_INTRO))) + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) return; events.Update(diff); @@ -337,7 +337,7 @@ class boss_rimefang : public CreatureScript void UpdateAI(const uint32 diff) { - if (!UpdateVictim() && !(_events.GetPhaseMask() & (1 << PHASE_COMBAT))) + if (!UpdateVictim() && !_events.IsInPhase(PHASE_COMBAT)) return; _events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index af727348719..12956c75595 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -185,9 +185,7 @@ enum Phases { PHASE_INTRO_A = 1, PHASE_INTRO_H = 2, - PHASE_COMBAT = 3, - - PHASE_INTRO_MASK = (1 << PHASE_INTRO_A) | (1 << PHASE_INTRO_H), + PHASE_COMBAT = 3 }; enum Actions @@ -424,7 +422,7 @@ class boss_deathbringer_saurfang : public CreatureScript void UpdateAI(uint32 const diff) { - if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) + if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO_A)) || events.IsInPhase(PHASE_INTRO_H)) return; events.Update(diff); @@ -612,7 +610,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript case ACTION_START_EVENT: { // Prevent crashes - if (_events.GetPhaseMask() & PHASE_INTRO_MASK) + if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H)) return; GetCreatureListWithEntryInGrid(_guardList, me, NPC_SE_KOR_KRON_REAVER, 20.0f); @@ -821,7 +819,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript case ACTION_START_EVENT: { // Prevent crashes - if (_events.GetPhaseMask() & PHASE_INTRO_MASK) + if (_events.IsInPhase(PHASE_INTRO_A) || _events.IsInPhase(PHASE_INTRO_H)) return; _events.SetPhase(PHASE_INTRO_A); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 4e677bf5b0e..f8d00f01713 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -160,10 +160,7 @@ enum Phases PHASE_ALL = 0, PHASE_INTRO = 1, PHASE_ONE = 2, - PHASE_TWO = 3, - - PHASE_INTRO_MASK = 1 << PHASE_INTRO, - PHASE_ONE_MASK = 1 << PHASE_ONE, + PHASE_TWO = 3 }; enum DeprogrammingData @@ -259,7 +256,7 @@ class boss_lady_deathwhisper : public CreatureScript if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) return; - if (victim && me->Attack(victim, true) && !(events.GetPhaseMask() & PHASE_ONE_MASK)) + if (victim && me->Attack(victim, true) && !events.IsInPhase(PHASE_ONE)) me->GetMotionMaster()->MoveChase(victim); } @@ -358,7 +355,7 @@ class boss_lady_deathwhisper : public CreatureScript void DamageTaken(Unit* /*damageDealer*/, uint32& damage) { // phase transition - if (events.GetPhaseMask() & PHASE_ONE_MASK && damage > me->GetPower(POWER_MANA)) + if (events.IsInPhase(PHASE_ONE) && damage > me->GetPower(POWER_MANA)) { Talk(SAY_PHASE_2); Talk(EMOTE_PHASE_2); @@ -406,12 +403,12 @@ class boss_lady_deathwhisper : public CreatureScript void UpdateAI(uint32 const diff) { - if ((!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) || !CheckInRoom()) + if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) || !CheckInRoom()) return; events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) + if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO)) return; while (uint32 eventId = events.ExecuteEvent()) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 05bf7b9794a..103c72e947d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -145,10 +145,7 @@ enum Phases PHASE_ROTFACE = 2, PHASE_COMBAT_1 = 4, PHASE_COMBAT_2 = 5, - PHASE_COMBAT_3 = 6, - - PHASE_MASK_COMBAT = (1 << PHASE_COMBAT_1) | (1 << PHASE_COMBAT_2) | (1 << PHASE_COMBAT_3), - PHASE_MASK_NOT_SELF = (1 << PHASE_FESTERGUT) | (1 << PHASE_ROTFACE) + PHASE_COMBAT_3 = 6 }; enum Points @@ -233,7 +230,7 @@ class boss_professor_putricide : public CreatureScript void Reset() { - if (!(events.GetPhaseMask() & PHASE_MASK_NOT_SELF)) + if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT))) instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, NOT_STARTED); instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(true)); @@ -252,7 +249,7 @@ class boss_professor_putricide : public CreatureScript void EnterCombat(Unit* who) { - if (events.GetPhaseMask() & PHASE_MASK_NOT_SELF) + if (events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) return; if (!instance->CheckRequiredBosses(DATA_PROFESSOR_PUTRICIDE, who->ToPlayer())) @@ -282,7 +279,7 @@ class boss_professor_putricide : public CreatureScript { _JustReachedHome(); me->SetWalk(false); - if (events.GetPhaseMask() & PHASE_MASK_COMBAT) + if (events.IsInPhase(PHASE_COMBAT_1) || events.IsInPhase(PHASE_COMBAT_2) || events.IsInPhase(PHASE_COMBAT_3)) instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL); } @@ -568,7 +565,7 @@ class boss_professor_putricide : public CreatureScript void UpdateAI(uint32 const diff) { - if ((!(events.GetPhaseMask() & PHASE_MASK_NOT_SELF) && !UpdateVictim()) || !CheckInRoom()) + if ((!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()) || !CheckInRoom()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 3bd313fa148..e2fd79b6fd2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -279,20 +279,10 @@ enum Phases PHASE_THREE = 4, PHASE_TRANSITION = 5, PHASE_FROSTMOURNE = 6, // only set on heroic mode when all players are sent into frostmourne - PHASE_OUTRO = 7, - - PHASE_MASK_INTRO = 1 << PHASE_INTRO, - PHASE_MASK_ONE = 1 << PHASE_ONE, - PHASE_MASK_TWO = 1 << PHASE_TWO, - PHASE_MASK_THREE = 1 << PHASE_THREE, - PHASE_MASK_TRANSITION = 1 << PHASE_TRANSITION, - PHASE_MASK_NO_CAST_CHECK = (1 << PHASE_TRANSITION) | (1 << PHASE_FROSTMOURNE) | (1 << PHASE_OUTRO), - PHASE_MASK_FROSTMOURNE = 1 << PHASE_FROSTMOURNE, - PHASE_MASK_OUTRO = 1 << PHASE_OUTRO, - PHASE_MASK_NO_VICTIM = (1 << PHASE_INTRO) | (1 << PHASE_OUTRO) | (1 << PHASE_FROSTMOURNE), + PHASE_OUTRO = 7 }; -#define PHASE_TWO_THREE (events.GetPhaseMask() & PHASE_MASK_TWO ? PHASE_TWO : PHASE_THREE) +#define PHASE_TWO_THREE (events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE) Position const CenterPosition = {503.6282f, -2124.655f, 840.8569f, 0.0f}; Position const TirionIntro = {489.2970f, -2124.840f, 840.8569f, 0.0f}; @@ -589,7 +579,7 @@ class boss_the_lich_king : public CreatureScript void KilledUnit(Unit* victim) { - if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !(events.GetPhaseMask() & PHASE_MASK_OUTRO)) + if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !events.IsInPhase(PHASE_OUTRO)) Talk(SAY_LK_KILL); } @@ -669,7 +659,7 @@ class boss_the_lich_king : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70)) + if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(70)) { events.SetPhase(PHASE_TRANSITION); me->SetReactState(REACT_PASSIVE); @@ -678,7 +668,7 @@ class boss_the_lich_king : public CreatureScript return; } - if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40)) + if (events.IsInPhase(PHASE_TWO) && !HealthAbovePct(40)) { events.SetPhase(PHASE_TRANSITION); me->SetReactState(REACT_PASSIVE); @@ -687,7 +677,7 @@ class boss_the_lich_king : public CreatureScript return; } - if (events.GetPhaseMask() & PHASE_MASK_THREE && !HealthAbovePct(10)) + if (events.IsInPhase(PHASE_THREE) && !HealthAbovePct(10)) { me->SetReactState(REACT_PASSIVE); me->AttackStop(); @@ -758,7 +748,7 @@ class boss_the_lich_king : public CreatureScript summon->SetReactState(REACT_PASSIVE); summon->SetSpeed(MOVE_FLIGHT, 0.5f); summon->GetMotionMaster()->MoveRandom(10.0f); - if (!(events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)) + if (!events.IsInPhase(PHASE_FROSTMOURNE)) summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000)); return; } @@ -873,14 +863,14 @@ class boss_the_lich_king : public CreatureScript void UpdateAI(uint32 const diff) { // check phase first to prevent updating victim and entering evade mode when not wanted - if (!(events.GetPhaseMask() & PHASE_MASK_NO_VICTIM)) + if (!(events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_INTRO) || events.IsInPhase(PHASE_FROSTMOURNE))) if (!UpdateVictim()) return; events.Update(diff); // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells - if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK)) + if ((me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_TRANSITION)) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)) return; while (uint32 eventId = events.ExecuteEvent()) @@ -936,7 +926,7 @@ class boss_the_lich_king : public CreatureScript break; case EVENT_INFEST: DoCast(me, SPELL_INFEST); - events.ScheduleEvent(EVENT_INFEST, urand(21000, 24000), 0, (events.GetPhaseMask() & PHASE_MASK_ONE) ? PHASE_ONE : PHASE_TWO); + events.ScheduleEvent(EVENT_INFEST, urand(21000, 24000), 0, events.IsInPhase(PHASE_ONE) ? PHASE_ONE : PHASE_TWO); break; case EVENT_NECROTIC_PLAGUE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, NecroticPlagueTargetCheck(me, NECROTIC_PLAGUE_LK, NECROTIC_PLAGUE_PLR))) @@ -1005,7 +995,7 @@ class boss_the_lich_king : public CreatureScript break; case EVENT_START_ATTACK: me->SetReactState(REACT_AGGRESSIVE); - if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE) + if (events.IsInPhase(PHASE_FROSTMOURNE)) events.SetPhase(PHASE_THREE); break; case EVENT_VILE_SPIRITS: @@ -1253,7 +1243,7 @@ class npc_tirion_fordring_tft : public CreatureScript void UpdateAI(uint32 const diff) { - if (!UpdateVictim() && !(_events.GetPhaseMask() & (PHASE_MASK_INTRO | PHASE_MASK_OUTRO))) + if (!UpdateVictim() && !(_events.IsInPhase(PHASE_OUTRO) || _events.IsInPhase(PHASE_INTRO))) return; _events.Update(diff); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 13a4fe23690..e5ab119e3dc 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -176,10 +176,7 @@ enum EncounterPhases { PHASE_NORMAL = 0, PHASE_ROLE_PLAY = 1, - PHASE_BIG_BANG = 2, - - PHASE_MASK_NO_UPDATE = (1 << PHASE_ROLE_PLAY) | (1 << PHASE_BIG_BANG), - PHASE_MASK_NO_CAST_CHECK = 1 << PHASE_ROLE_PLAY, + PHASE_BIG_BANG = 2 }; enum AchievmentInfo @@ -542,12 +539,12 @@ class boss_algalon_the_observer : public CreatureScript void UpdateAI(uint32 const diff) { - if ((!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) || !CheckInRoom()) + if ((!(events.IsInPhase(PHASE_ROLE_PLAY) || events.IsInPhase(PHASE_BIG_BANG)) && !UpdateVictim()) || !CheckInRoom()) return; events.Update(diff); - if (!(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK)) + if (!events.IsInPhase(PHASE_ROLE_PLAY)) if (me->HasUnitState(UNIT_STATE_CASTING)) return; @@ -772,7 +769,7 @@ class npc_living_constellation : public CreatureScript void UpdateAI(uint32 const diff) { - if (!(_events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) + if (!(_events.IsInPhase(PHASE_ROLE_PLAY) || _events.IsInPhase(PHASE_BIG_BANG)) && !UpdateVictim()) return; _events.Update(diff); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index f579fb2b93c..dbf2058546f 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -154,7 +154,7 @@ public: Talk(YELL_DEAD_1); } - if (events.GetPhaseMask() & (1 << PHASE_EVENT)) + if (events.IsInPhase(PHASE_EVENT)) damage = 0; } @@ -206,7 +206,7 @@ public: void UpdateAI(const uint32 diff) { - if (!UpdateVictim() && !(events.GetPhaseMask() & (1 << PHASE_EVENT))) + if (!UpdateVictim() && !events.IsInPhase(PHASE_EVENT)) return; events.Update(diff); -- cgit v1.2.3 From 716c2db403384fd81961f0829ec9c1c85a1a2256 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 30 Jan 2013 19:09:09 +0100 Subject: Core: Fix warnings --- src/server/game/AI/CreatureAIImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 2b182901c8a..bf5ab9703e0 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -525,7 +525,7 @@ class EventMap // Returns wether the eventmap is in the given phase or not. bool IsInPhase(uint32 phase) { - return phase <= 8 && (!phase || _phase & (1 << phase + 23)); + return phase <= 8 && (!phase || _phase & (1 << (phase + 23))); } private: -- cgit v1.2.3 From 754418a8de569c2cb4d28e9dde5cf257490b73b9 Mon Sep 17 00:00:00 2001 From: Gacko Date: Wed, 30 Jan 2013 19:34:59 +0100 Subject: Script/ICC: Fix phase check in Saurfang script Related to changes in dbecf05e39204ff46621ce46bf5dd181e6450eeb --- .../scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 12956c75595..ccbecbe4290 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -422,7 +422,7 @@ class boss_deathbringer_saurfang : public CreatureScript void UpdateAI(uint32 const diff) { - if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO_A)) || events.IsInPhase(PHASE_INTRO_H)) + if (!UpdateVictim() && (!events.IsInPhase(PHASE_INTRO_A) || events.IsInPhase(PHASE_INTRO_H))) return; events.Update(diff); -- cgit v1.2.3 From 15e42ac797099361fe7d85436cdc90ddbc5d1a67 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 30 Jan 2013 20:40:02 +0100 Subject: Core/Players: Improvements to currency handling. --- src/server/game/Entities/Player/Player.cpp | 220 ++++++++++++++--------------- src/server/game/Entities/Player/Player.h | 22 +-- src/server/game/Handlers/ItemHandler.cpp | 4 +- 3 files changed, 118 insertions(+), 128 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fb8891893da..67dc948ed99 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -859,7 +859,6 @@ Player::Player(WorldSession* session): Unit(true), phaseMgr(this) _activeCheats = CHEAT_NONE; _maxPersonalArenaRate = 0; - _ConquestCurrencyTotalWeekCap = 0; memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); memset(_CUFProfiles, 0, MAX_CUF_PROFILES * sizeof(CUFProfile*)); @@ -7205,14 +7204,6 @@ void Player::_LoadCurrency(PreparedQueryResult result) _currencyStorage.insert(PlayerCurrenciesMap::value_type(currencyID, cur)); - // load total conquest cap. should be after insert. - if (currency->Category == CURRENCY_CATEGORY_META_CONQUEST) - { - uint32 cap = _GetCurrencyWeekCap(currency); - if (cap > _ConquestCurrencyTotalWeekCap) - _ConquestCurrencyTotalWeekCap = cap; - } - } while (result->NextRow()); } @@ -7267,7 +7258,7 @@ void Player::SendNewCurrency(uint32 id) const uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; uint32 weekCount = itr->second.weekCount / precision; - uint32 weekCap = _GetCurrencyWeekCap(entry) / precision; + uint32 weekCap = GetCurrencyWeekCap(entry) / precision; packet.WriteBit(weekCount); packet.WriteBits(0, 4); // some flags @@ -7279,7 +7270,7 @@ void Player::SendNewCurrency(uint32 id) const currencyData << uint32(weekCap); //if (seasonTotal) - // currencyData << uint32(seasonTotal); + // currencyData << uint32(seasonTotal / precision); currencyData << uint32(entry->ID); if (weekCount) @@ -7308,7 +7299,7 @@ void Player::SendCurrencies() const uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; uint32 weekCount = itr->second.weekCount / precision; - uint32 weekCap = _GetCurrencyWeekCap(entry) / precision; + uint32 weekCap = GetCurrencyWeekCap(entry) / precision; packet.WriteBit(weekCount); packet.WriteBits(0, 4); // some flags @@ -7320,7 +7311,7 @@ void Player::SendCurrencies() const currencyData << uint32(weekCap); //if (seasonTotal) - // currencyData << uint32(seasonTotal); + // currencyData << uint32(seasonTotal / precision); currencyData << uint32(entry->ID); if (weekCount) @@ -7348,36 +7339,28 @@ void Player::SendPvpRewards() const GetSession()->SendPacket(&packet); } -uint32 Player::GetCurrency(uint32 id, bool precision) const +uint32 Player::GetCurrency(uint32 id, bool usePrecision) const { PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id); if (itr == _currencyStorage.end()) return 0; - if (!precision) - return itr->second.totalCount; - CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id); - ASSERT(currency); + uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - int32 mod = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? 100 : 1; - return itr->second.totalCount / mod; + return itr->second.totalCount / precision; } -uint32 Player::GetCurrencyOnWeek(uint32 id, bool precision) const +uint32 Player::GetCurrencyOnWeek(uint32 id, bool usePrecision) const { PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id); if (itr == _currencyStorage.end()) return 0; - if (!precision) - return itr->second.weekCount; - CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id); - ASSERT(currency); + uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - int32 mod = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? 100 : 1; - return itr->second.weekCount / mod; + return itr->second.weekCount / precision; } bool Player::HasCurrency(uint32 id, uint32 count) const @@ -7417,12 +7400,12 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo } // count can't be more then weekCap if used (weekCap > 0) - uint32 weekCap = _GetCurrencyWeekCap(currency); + uint32 weekCap = GetCurrencyWeekCap(currency); if (weekCap && count > int32(weekCap)) count = weekCap; // count can't be more then totalCap if used (totalCap > 0) - uint32 totalCap = _GetCurrencyTotalCap(currency); + uint32 totalCap = GetCurrencyTotalCap(currency); if (totalCap && count > int32(totalCap)) count = totalCap; @@ -7457,44 +7440,30 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bo itr->second.totalCount = newTotalCount; itr->second.weekCount = newWeekCount; - // probably excessive checks - if (IsInWorld() && !GetSession()->PlayerLoading()) - { - if (count > 0) - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count); + if (count > 0) + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count); - if (currency->Category == CURRENCY_CATEGORY_META_CONQUEST) - { - //original conquest cap is highest of bg/arena conquest cap. - if (weekCap > _ConquestCurrencyTotalWeekCap) - _ConquestCurrencyTotalWeekCap = weekCap; - // count was changed to week limit, now we can modify original points. - ModifyCurrency(CURRENCY_TYPE_CONQUEST_POINTS, count, printLog ); - return; - } - - // on new case just set init. - if (itr->second.state == PLAYERCURRENCY_NEW) - { - SendNewCurrency(id); - return; - } + if (currency->Category == CURRENCY_CATEGORY_META_CONQUEST) + { + // count was changed to week limit, now we can modify original points. + ModifyCurrency(CURRENCY_TYPE_CONQUEST_POINTS, count, printLog); + return; + } - WorldPacket packet(SMSG_UPDATE_CURRENCY, 12); + WorldPacket packet(SMSG_UPDATE_CURRENCY, 12); - packet.WriteBit(weekCap != 0); - packet.WriteBit(0); // hasSeasonCount - packet.WriteBit(printLog); // print in log + packet.WriteBit(weekCap != 0); + packet.WriteBit(0); // hasSeasonCount + packet.WriteBit(!printLog); // print in log - // if hasSeasonCount packet << uint32(seasontotalearned); TODO: save this in character DB and use it + // if hasSeasonCount packet << uint32(seasontotalearned); TODO: save this in character DB and use it - packet << uint32(newTotalCount / precision); - packet << uint32(id); - if (weekCap) - packet << uint32(newWeekCount / precision); + packet << uint32(newTotalCount / precision); + packet << uint32(id); + if (weekCap) + packet << uint32(newWeekCount / precision); - GetSession()->SendPacket(&packet); - } + GetSession()->SendPacket(&packet); } } @@ -7517,11 +7486,9 @@ uint32 Player::GetCurrencyWeekCap(uint32 id, bool usePrecision) const if (!entry) return 0; - uint32 cap = _GetCurrencyWeekCap(entry); - if (usePrecision && entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) - cap /= 100; + uint32 precision = (usePrecision && entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - return cap; + return GetCurrencyWeekCap(entry) / precision; } void Player::ResetCurrencyWeekCap() @@ -7547,15 +7514,13 @@ void Player::ResetCurrencyWeekCap() SendDirectMessage(&data); } -uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const +uint32 Player::GetCurrencyWeekCap(CurrencyTypesEntry const* currency) const { - uint32 cap = currency->WeekCap; - switch (currency->ID) { //original conquest not have week cap case CURRENCY_TYPE_CONQUEST_POINTS: - return _ConquestCurrencyTotalWeekCap; + return std::max(GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA, false), GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, false)); case CURRENCY_TYPE_CONQUEST_META_ARENA: // should add precision mod = 100 return Trinity::Currency::ConquestRatingCalculator(_maxPersonalArenaRate) * CURRENCY_PRECISION; @@ -7564,18 +7529,10 @@ uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const return Trinity::Currency::BgConquestRatingCalculator(GetRBGPersonalRating()) * CURRENCY_PRECISION; } - if (cap != currency->WeekCap && IsInWorld() && !GetSession()->PlayerLoading()) - { - WorldPacket packet(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, 8); - packet << uint32(cap / ((currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1)); - packet << uint32(currency->ID); - GetSession()->SendPacket(&packet); - } - - return cap; + return currency->WeekCap; } -uint32 Player::_GetCurrencyTotalCap(const CurrencyTypesEntry* currency) const +uint32 Player::GetCurrencyTotalCap(CurrencyTypesEntry const* currency) const { uint32 cap = currency->TotalCap; @@ -7600,6 +7557,26 @@ uint32 Player::_GetCurrencyTotalCap(const CurrencyTypesEntry* currency) const return cap; } +void Player::UpdateConquestCurrencyCap(uint32 currency) +{ + uint32 currenciesToUpdate[2] = { currency, CURRENCY_TYPE_CONQUEST_POINTS }; + + for (uint32 i = 0; i < 2; ++i) + { + CurrencyTypesEntry const* currencyEntry = sCurrencyTypesStore.LookupEntry(currenciesToUpdate[i]); + if (!currencyEntry) + continue; + + uint32 precision = (currencyEntry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1; + uint32 cap = GetCurrencyWeekCap(currencyEntry); + + WorldPacket packet(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, 8); + packet << uint32(cap / precision); + packet << uint32(currenciesToUpdate[i]); + GetSession()->SendPacket(&packet); + } +} + void Player::SetInGuild(uint32 guildId) { if (guildId) @@ -7635,7 +7612,10 @@ void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 v { SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value); if (type == ARENA_TEAM_PERSONAL_RATING && value > _maxPersonalArenaRate) + { _maxPersonalArenaRate = value; + UpdateConquestCurrencyCap(CURRENCY_TYPE_CONQUEST_META_ARENA); + } } uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) @@ -20946,11 +20926,6 @@ void Player::LeaveAllArenaTeams(uint64 guid) while (result->NextRow()); } -uint32 Player::GetRBGPersonalRating() const -{ - return 0; -} - void Player::SetRestBonus(float rest_bonus_new) { // Prevent resting on max level @@ -21354,6 +21329,7 @@ void Player::InitDisplayIds() inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore) { + uint32 stacks = count / pProto->BuyCount; ItemPosCountVec vDest; uint16 uiDest = 0; InventoryResult msg = bStore ? @@ -21373,13 +21349,13 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { if (iece->RequiredItem[i]) - DestroyItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i], true); + DestroyItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks, true); } for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { if (iece->RequiredCurrency[i]) - ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i]), true, true); + ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i] * stacks), true, true); } } @@ -21416,8 +21392,6 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count) { - vendorSlot += 1; - // cheating attempt if (count < 1) count = 1; @@ -21460,9 +21434,17 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin return false; } + if (count % crItem->maxcount) + { + SendEquipError(EQUIP_ERR_CANT_BUY_QUANTITY, NULL, NULL); + return false; + } + + uint32 stacks = count / crItem->maxcount; + ItemExtendedCostEntry const* iece = NULL; if (crItem->ExtendedCost) { - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); + iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); if (!iece) { sLog->outError(LOG_FILTER_PLAYER, "Currency %u have wrong ExtendedCost field value %u", currency, crItem->ExtendedCost); @@ -21471,7 +21453,7 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) { - if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * count))) + if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * stacks))) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; @@ -21490,9 +21472,7 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin return false; } - uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - - if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * count) / precision)) + if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * stacks))) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error return false; @@ -21513,7 +21493,25 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin return false; } - ModifyCurrency(currency, crItem->maxcount, true, true); + ModifyCurrency(currency, count, true, true); + if (iece) + { + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) + { + if (!iece->RequiredItem[i]) + continue; + + DestroyItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks, true); + } + + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) + { + if (!iece->RequiredCurrency[i]) + continue; + + ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i]) * stacks, false, true); + } + } return true; } @@ -21586,12 +21584,13 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 if (crItem->ExtendedCost) { // Can only buy full stacks for extended cost - if (pProto->BuyCount != count) + if (count % pProto->BuyCount) { SendEquipError(EQUIP_ERR_CANT_BUY_QUANTITY, NULL, NULL); return false; } + uint32 stacks = count / pProto->BuyCount; ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); if (!iece) { @@ -21601,7 +21600,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) { - if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * count))) + if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks)) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; @@ -21620,9 +21619,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 return false; } - uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - - if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * count) / precision)) + if (!HasCurrency(iece->RequiredCurrency[i], iece->RequiredCurrencyCount[i] * stacks)) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; @@ -25963,8 +25960,6 @@ void Player::DeleteRefundReference(uint32 it) void Player::SendRefundInfo(Item* item) { - const CurrencyTypesEntry* currencyType; - uint32 divisor; // This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours. item->UpdatePlayedTime(this); @@ -25999,6 +25994,7 @@ void Player::SendRefundInfo(Item* item) data.WriteBit(guid[0]); data.WriteBit(guid[1]); data.FlushBits(); + data.WriteByteSeq(guid[7]); data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data @@ -26013,12 +26009,10 @@ void Player::SendRefundInfo(Item* item) data.WriteByteSeq(guid[2]); for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data { - currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]); - if (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) - divisor = 100; - else - divisor = 1; - data << uint32(iece->RequiredCurrencyCount[i] / divisor); + CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]); + uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; + + data << uint32(iece->RequiredCurrencyCount[i] / precision); data << uint32(iece->RequiredCurrency[i]); } @@ -26057,8 +26051,6 @@ void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, { ObjectGuid guid = item->GetGUID(); WorldPacket data(SMSG_ITEM_REFUND_RESULT, 1 + 1 + 8 + 4*8 + 4 + 4*8 + 1); - const CurrencyTypesEntry* currencyType; - uint32 divisor; data.WriteBit(guid[4]); data.WriteBit(guid[5]); data.WriteBit(guid[1]); @@ -26074,12 +26066,10 @@ void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, { for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { - currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]); - if (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) - divisor = 100; - else - divisor = 1; - data << uint32(iece->RequiredCurrencyCount[i] / divisor); + CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]); + uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; + + data << uint32(iece->RequiredCurrencyCount[i] / precision); data << uint32(iece->RequiredCurrency[i]); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 979dfc42040..6f5c5b71369 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1431,9 +1431,9 @@ class Player : public Unit, public GridObject /// send conquest currency points and their cap week/arena void SendPvpRewards() const; /// return count of currency witch has plr - uint32 GetCurrency(uint32 id, bool precision) const; + uint32 GetCurrency(uint32 id, bool usePrecision) const; /// return count of currency gaind on current week - uint32 GetCurrencyOnWeek(uint32 id, bool precision) const; + uint32 GetCurrencyOnWeek(uint32 id, bool usePrecision) const; /// return week cap by currency id uint32 GetCurrencyWeekCap(uint32 id, bool usePrecision) const; /// return presence related currency @@ -2049,7 +2049,7 @@ class Player : public Unit, public GridObject uint32 GetArenaPersonalRating(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); } void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; } uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } - uint32 GetRBGPersonalRating() const; + uint32 GetRBGPersonalRating() const { return 0; } Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; } Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; } @@ -2887,20 +2887,23 @@ class Player : public Unit, public GridObject PlayerCurrenciesMap _currencyStorage; /** - * @name _GetCurrencyWeekCap + * @name GetCurrencyWeekCap * @brief return week cap for selected currency - * @param currency CurrencyTypesEntry witch should get week cap + * @param CurrencyTypesEntry for which to retrieve weekly cap */ - uint32 _GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const; + uint32 GetCurrencyWeekCap(CurrencyTypesEntry const* currency) const; /* - * @name _GetCurrencyTotalCap + * @name GetCurrencyTotalCap * @brief return total cap for selected currency - * @param currency CurrencyTypesEntry witch should get week cap + * @param CurrencyTypesEntry for which to retrieve total cap */ - uint32 _GetCurrencyTotalCap(const CurrencyTypesEntry* currency) const; + uint32 GetCurrencyTotalCap(CurrencyTypesEntry const* currency) const; + + /// Updates weekly conquest point cap (dynamic cap) + void UpdateConquestCurrencyCap(uint32 currency); VoidStorageItem* _voidStorageItems[VOID_STORAGE_MAX_SLOT]; @@ -3104,7 +3107,6 @@ class Player : public Unit, public GridObject uint32 _activeCheats; uint32 _maxPersonalArenaRate; - uint32 _ConquestCurrencyTotalWeekCap; PhaseMgr phaseMgr; }; diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 617270ac119..4887bfee38b 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -816,8 +816,6 @@ void WorldSession::SendListInventory(uint64 vendorGuid) if (vendorItem->ExtendedCost == 0) continue; // there's no price defined for currencies, only extendedcost is used - uint32 precision = (currencyTemplate->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1; - ++count; itemsData << uint32(slot + 1); // client expects counting to start at 1 itemsData << uint32(0); // max durability @@ -838,7 +836,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid) itemsData << uint32(0); // displayId // if (!unk "enabler") data << uint32(something); itemsData << int32(-1); - itemsData << uint32(vendorItem->maxcount * precision); + itemsData << uint32(vendorItem->maxcount); } // else error } -- cgit v1.2.3 From 71a0cc1706298281028434123e1ac016c082e486 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 31 Jan 2013 00:18:27 +0100 Subject: Core/Spells: Add missing break in f5fd7bad69c04352f5e367b8aca2035e0eff57d9 Thx Nayd --- src/server/game/Entities/Unit/Unit.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bd2674a5af6..32ade87fef4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5955,6 +5955,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere break; } } + break; } case SPELLFAMILY_PALADIN: { -- cgit v1.2.3 From a4b1f1c45fc8a1e28b76ffbbd0e73e6452c0785b Mon Sep 17 00:00:00 2001 From: Warpten Date: Thu, 31 Jan 2013 00:20:54 +0100 Subject: Spells/Warlock: Fixed Conflagrate, Demon Soul and Immolate. --- .../2013_01_31_00_world_spell_script_names_434.sql | 6 + src/server/scripts/Spells/spell_warlock.cpp | 150 +++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 sql/updates/world/2013_01_31_00_world_spell_script_names_434.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_31_00_world_spell_script_names_434.sql b/sql/updates/world/2013_01_31_00_world_spell_script_names_434.sql new file mode 100644 index 00000000000..14bf9f1832a --- /dev/null +++ b/sql/updates/world/2013_01_31_00_world_spell_script_names_434.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_warl_demon_soul', 'spell_warl_conflagrate', 'spell_warl_fel_flame'); +DELETE FROM `spell_script_names` WHERE `spell_id`=77799 OR ScriptName="spell_warlock_fel_flame"; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(17962, 'spell_warl_conflagrate'); +(77799, 'spell_warl_fel_flame'); +(77801, 'spell_warl_demon_soul'); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index df415a7bb08..92d8e940a22 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -25,6 +25,7 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "SpellAuras.h" enum WarlockSpells { @@ -38,10 +39,16 @@ enum WarlockSpells SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443, + SPELL_WARLOCK_DEMON_SOUL_IMP = 79459, + SPELL_WARLOCK_DEMON_SOUL_FELHUNTER = 79460, + SPELL_WARLOCK_DEMON_SOUL_FELGUARD = 79452, + SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS = 79453, + SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER = 79454, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, SPELL_WARLOCK_HAUNT = 48181, SPELL_WARLOCK_HAUNT_HEAL = 48210, + SPELL_WARLOCK_IMMOLATE = 348, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692, SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693, SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955, @@ -52,6 +59,7 @@ enum WarlockSpells SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_UNSTABLE_AFFLICTION = 30108, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -116,6 +124,41 @@ class spell_warl_banish : public SpellScriptLoader } }; +// 17962 - Conflagrate - Updated to 4.3.4 +class spell_warl_conflagrate : public SpellScriptLoader +{ + public: + spell_warl_conflagrate() : SpellScriptLoader("spell_warl_conflagrate") { } + + class spell_warl_conflagrate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_conflagrate_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMMOLATE)) + return false; + return true; + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_WARLOCK_IMMOLATE, EFFECT_2, GetCaster()->GetGUID())) + SetHitDamage(CalculatePct(aurEff->GetAmount(), GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster()))); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warl_conflagrate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_conflagrate_SpellScript(); + } +}; + // 6201 - Create Healthstone class spell_warl_create_healthstone : public SpellScriptLoader { @@ -336,6 +379,73 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader } }; +// 77801 - Demon Soul - Updated to 4.3.4 +class spell_warl_demon_soul : public SpellScriptLoader +{ + public: + spell_warl_demon_soul() : SpellScriptLoader("spell_warl_demon_soul") { } + + class spell_warl_demon_soul_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_demon_soul_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_IMP)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELHUNTER)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELGUARD)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER)) + return false; + return true; + } + + void OnHitTarget(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Creature* targetCreature = GetHitCreature()) + { + if (targetCreature->isPet()) + { + CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry()); + switch (ci->family) + { + case CREATURE_FAMILY_SUCCUBUS: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS); + break; + case CREATURE_FAMILY_VOIDWALKER: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER); + break; + case CREATURE_FAMILY_FELGUARD: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELGUARD); + break; + case CREATURE_FAMILY_FELHUNTER: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELHUNTER); + break; + case CREATURE_FAMILY_IMP: + caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_IMP); + break; + } + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warl_demon_soul_SpellScript::OnHitTarget, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_demon_soul_SpellScript; + } +}; + // 47193 - Demonic Empowerment /// Updated 4.3.4 class spell_warl_demonic_empowerment : public SpellScriptLoader @@ -430,6 +540,43 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader } }; +// 77799 - Fel Flame - Updated to 4.3.4 +class spell_warl_fel_flame : public SpellScriptLoader +{ + public: + spell_warl_fel_flame() : SpellScriptLoader("spell_warl_fel_flame") { } + + class spell_warl_fel_flame_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_fel_flame_SpellScript); + + void OnHitTarget(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + Aura* aura = target->GetAura(SPELL_WARLOCK_UNSTABLE_AFFLICTION, caster->GetGUID()); + if (!aura) + aura = target->GetAura(SPELL_WARLOCK_IMMOLATE, caster->GetGUID()); + + if (!aura) + return; + + int32 newDuration = aura->GetDuration() + GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 1000; + aura->SetDuration(std::min(newDuration, aura->GetMaxDuration())); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warl_fel_flame_SpellScript::OnHitTarget, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warl_fel_flame_SpellScript; + } +}; + // -47230 - Fel Synergy class spell_warl_fel_synergy : public SpellScriptLoader { @@ -874,11 +1021,14 @@ void AddSC_warlock_spell_scripts() { new spell_warl_bane_of_doom(); new spell_warl_banish(); + new spell_warl_conflagrate(); new spell_warl_create_healthstone(); new spell_warl_demonic_circle_summon(); new spell_warl_demonic_circle_teleport(); new spell_warl_demonic_empowerment(); + new spell_warl_demon_soul(); new spell_warl_everlasting_affliction(); + new spell_warl_fel_flame(); new spell_warl_fel_synergy(); new spell_warl_haunt(); new spell_warl_health_funnel(); -- cgit v1.2.3 From 9a0525757adc6ddf59d7e942cddfdd0185a896d8 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 31 Jan 2013 00:35:33 +0100 Subject: Core: Fix some warnings --- src/server/game/Guilds/Guild.cpp | 2 +- src/server/game/Handlers/ChatHandler.cpp | 6 +++--- src/server/game/Spells/SpellInfo.cpp | 2 +- src/server/scripts/Spells/spell_mage.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index cef21863b60..04169bb7b7d 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2520,7 +2520,7 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPacket data; - ChatHandler::FillMessageData(&data, session, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, CHAT_MSG_ADDON, NULL, 0, msg.c_str(), NULL, prefix.c_str()); + ChatHandler::FillMessageData(&data, session, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, uint32(CHAT_MSG_ADDON), NULL, 0, msg.c_str(), NULL, prefix.c_str()); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 1105886813a..eef049fdb66 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -600,7 +600,7 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) return; // Weird way to log stuff... - sScriptMgr->OnPlayerChat(sender, CHAT_MSG_ADDON, LANG_ADDON, message); + sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), uint32(LANG_ADDON), message); } // Disabled addon channel? @@ -616,7 +616,7 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) return; WorldPacket data; - ChatHandler::FillMessageData(&data, this, type, LANG_ADDON, "", 0, message.c_str(), NULL); + ChatHandler::FillMessageData(&data, this, type, uint32(LANG_ADDON), "", 0, message.c_str(), NULL); group->BroadcastAddonMessagePacket(&data, prefix, false); break; } @@ -649,7 +649,7 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) break; WorldPacket data; - ChatHandler::FillMessageData(&data, this, type, LANG_ADDON, "", 0, message.c_str(), NULL, prefix.c_str()); + ChatHandler::FillMessageData(&data, this, type, uint32(LANG_ADDON), "", 0, message.c_str(), NULL, prefix.c_str()); group->BroadcastAddonMessagePacket(&data, prefix, true, -1, group->GetMemberGroup(sender->GetGUID())); break; } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index e85d0e2bfe6..c5c8156d38b 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -386,7 +386,7 @@ bool SpellEffectInfo::IsAura() const bool SpellEffectInfo::IsAura(AuraType aura) const { - return IsAura() && AuraType(ApplyAuraName) == uint32(aura); + return IsAura() && ApplyAuraName == uint32(aura); } bool SpellEffectInfo::IsTargetingArea() const diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index ddd65b26496..cd3673c17de 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -909,8 +909,8 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader if (Player* player = caster->ToPlayer()) if (Guardian* elemental = player->GetGuardianPet()) // Check if the pet we are going to unsummon is the mage's water elemental - if (elemental->GetEntry() == sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY)->Effects[EFFECT_0].MiscValue || - elemental->GetEntry() == sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT)->Effects[EFFECT_0].MiscValue) + if (elemental->GetEntry() == uint32(sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY)->Effects[EFFECT_0].MiscValue) || + elemental->GetEntry() == uint32(sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT)->Effects[EFFECT_0].MiscValue)) elemental->UnSummon(); // Glyph of Eternal Water -- cgit v1.2.3 From 0a9fbc6588b037c4fed593836b1ea6efaa360647 Mon Sep 17 00:00:00 2001 From: Gacko Date: Thu, 31 Jan 2013 08:45:47 +0100 Subject: Script/ICC: Fix phase check in Saurfang script ... typos - typos everywhere. me->request(glasses); --- .../scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index ccbecbe4290..c92f10e8b95 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -422,7 +422,7 @@ class boss_deathbringer_saurfang : public CreatureScript void UpdateAI(uint32 const diff) { - if (!UpdateVictim() && (!events.IsInPhase(PHASE_INTRO_A) || events.IsInPhase(PHASE_INTRO_H))) + if (!UpdateVictim() && !(events.IsInPhase(PHASE_INTRO_A) || events.IsInPhase(PHASE_INTRO_H))) return; events.Update(diff); -- cgit v1.2.3 From 67d46ae1aebef5189ba6efe0990dc85e41a591c8 Mon Sep 17 00:00:00 2001 From: Spp Date: Thu, 31 Jan 2013 09:16:45 +0100 Subject: Scripts/Commands: Show correct guild Rank when using .pinfo command (Corrections to 1b551cc1) --- src/server/scripts/Commands/cs_misc.cpp | 20 +++++++------------- .../Database/Implementation/CharacterDatabase.cpp | 4 +++- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 367591080d2..ce9d5088317 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1740,19 +1740,13 @@ public: result = CharacterDatabase.Query(stmt); if (result) { - uint32 guildId = 0; - std::string guildName = ""; - std::string guildRank = ""; - std::string note = ""; - std::string officeNote = ""; - - Field* fields = result->Fetch(); - guildId = fields[0].GetUInt32(); - guildName = fields[1].GetString(); - //rankId = fields[2].GetUInt8(); - guildRank = fields[3].GetString(); - note = fields[4].GetString(); - officeNote = fields[5].GetString(); + Field* fields = result->Fetch(); + + uint32 guildId = fields[0].GetUInt32(); + std::string guildName = fields[1].GetString(); + std::string guildRank = fields[2].GetString(); + std::string note = fields[3].GetString(); + std::string officeNote = fields[4].GetString(); handler->PSendSysMessage(LANG_PINFO_GUILD_INFO, guildName.c_str(), guildId, guildRank.c_str(), note.c_str(), officeNote.c_str()); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index b3d818c7565..52845231490 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -101,7 +101,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gm.rank, gr.rname, gm.pnote, gm.offnote FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid JOIN guild_rank gr ON g.guildid = gr.guildid WHERE gm.guid = ?", CONNECTION_BOTH); + PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gr.rname, gm.pnote, gm.offnote " + "FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid " + "JOIN guild_rank gr ON g.guildid = gr.guildid AND gm.rank = gr.rid WHERE gm.guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, " -- cgit v1.2.3 From 8e7806379dbf757c92ece45736c0947eb958c4cd Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 31 Jan 2013 19:59:44 +0100 Subject: Core/Spells: Fix Gas Cloud Tracking stacking with other tracking spells --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 10 ++++++++-- src/server/game/Spells/SpellInfo.cpp | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 05119af2582..918e4f3bfc3 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2375,7 +2375,10 @@ void AuraEffect::HandleAuraTrackCreatures(AuraApplication const* aurApp, uint8 m if (target->GetTypeId() != TYPEID_PLAYER) return; - target->SetUInt32Value(PLAYER_TRACK_CREATURES, (apply) ? ((uint32)1)<<(GetMiscValue()-1) : 0); + if (apply) + target->SetFlag(PLAYER_TRACK_CREATURES, uint32(1) << (GetMiscValue() - 1)); + else + target->RemoveFlag(PLAYER_TRACK_CREATURES, uint32(1) << (GetMiscValue() - 1)); } void AuraEffect::HandleAuraTrackResources(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -2388,7 +2391,10 @@ void AuraEffect::HandleAuraTrackResources(AuraApplication const* aurApp, uint8 m if (target->GetTypeId() != TYPEID_PLAYER) return; - target->SetUInt32Value(PLAYER_TRACK_RESOURCES, (apply) ? ((uint32)1)<<(GetMiscValue()-1): 0); + if (apply) + target->SetFlag(PLAYER_TRACK_RESOURCES, uint32(1) << (GetMiscValue() - 1)); + else + target->RemoveFlag(PLAYER_TRACK_RESOURCES, uint32(1) << (GetMiscValue() - 1)); } void AuraEffect::HandleAuraTrackStealthed(AuraApplication const* aurApp, uint8 mode, bool apply) const diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 0c298efd83e..6323d2ea638 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1922,6 +1922,9 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const case SPELL_AURA_AOE_CHARM: return SPELL_SPECIFIC_CHARM; case SPELL_AURA_TRACK_CREATURES: + /// @workaround For non-stacking tracking spells (We need generic solution) + if (Id == 30645) // Gas Cloud Tracking + return SPELL_SPECIFIC_NORMAL; case SPELL_AURA_TRACK_RESOURCES: case SPELL_AURA_TRACK_STEALTHED: return SPELL_SPECIFIC_TRACKER; -- cgit v1.2.3 From f5264e3fbb542c57056079e946f259baa586df0f Mon Sep 17 00:00:00 2001 From: Gacko Date: Thu, 31 Jan 2013 22:00:32 +0100 Subject: Script/ICC: Fix phase check and warning --- src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index e2fd79b6fd2..fb1415aa60b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -870,7 +870,7 @@ class boss_the_lich_king : public CreatureScript events.Update(diff); // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells - if ((me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_TRANSITION)) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)) + if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE))) return; while (uint32 eventId = events.ExecuteEvent()) @@ -2837,8 +2837,6 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); } - - Unit* _target; }; SpellScript* GetSpellScript() const -- cgit v1.2.3 From 0e945613d0a4bf120b6242106adb26ed1e288228 Mon Sep 17 00:00:00 2001 From: Nay Date: Fri, 1 Feb 2013 04:52:06 +0000 Subject: Core/Spells: Correct a check in IsLootCrafting, allows Prismatic Black Diamond to be fixed (a very peculiar spell...) The following conversation led to this fix: http://paste2.org/p/2816385 (for reference) --- src/server/game/Spells/SpellInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 6323d2ea638..91bff331160 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -849,7 +849,7 @@ bool SpellInfo::IsLootCrafting() const return (Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || // different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item (Effects[0].Effect == SPELL_EFFECT_CREATE_ITEM_2 && - (TotemCategory[0] != 0 || Effects[0].ItemType == 0))); + ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || Effects[0].ItemType == 0))); } bool SpellInfo::IsQuestTame() const -- cgit v1.2.3 From 0bf29d45d112130ee4b03fbb66d888964edadc6a Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 1 Feb 2013 11:38:55 +0100 Subject: Core/Players: Prevent trading, taking gold from mail and withdrawing from guild bank if it would put the player over gold cap. Closes #4015 --- src/server/game/Entities/Player/Player.cpp | 24 +++++++++++++----------- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Guilds/Guild.cpp | 14 +++++++++----- src/server/game/Handlers/MailHandler.cpp | 9 +++++++-- src/server/game/Handlers/TradeHandler.cpp | 15 +++++++++++++++ src/server/scripts/Commands/cs_modify.cpp | 9 ++++++--- 6 files changed, 51 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 82a1164b423..59f9e1e3efb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -22049,26 +22049,28 @@ void Player::InitPrimaryProfessions() SetFreePrimaryProfessions(sWorld->getIntConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL)); } -void Player::ModifyMoney(int32 d) +bool Player::ModifyMoney(int32 amount, bool sendError /*= true*/) { - sScriptMgr->OnPlayerMoneyChanged(this, d); + if (!amount) + return true; + + sScriptMgr->OnPlayerMoneyChanged(this, amount); - if (d < 0) - SetMoney (GetMoney() > uint32(-d) ? GetMoney() + d : 0); + if (amount < 0) + SetMoney (GetMoney() > uint32(-amount) ? GetMoney() + amount : 0); else { - uint32 newAmount = 0; - if (GetMoney() < uint32(MAX_MONEY_AMOUNT - d)) - newAmount = GetMoney() + d; + if (GetMoney() < uint32(MAX_MONEY_AMOUNT - amount)) + SetMoney(GetMoney() + amount); else { - // "At Gold Limit" - newAmount = MAX_MONEY_AMOUNT; - if (d) + if (sendError) SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + return false; } - SetMoney (newAmount); } + + return true; } Unit* Player::GetSelectedUnit() const diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a69f8c44715..64980b9551e 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1546,7 +1546,7 @@ class Player : public Unit, public GridObject void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} uint32 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); } - void ModifyMoney(int32 d); + bool ModifyMoney(int32 amount, bool sendError = true); bool HasEnoughMoney(uint32 amount) const { return (GetMoney() >= amount); } bool HasEnoughMoney(int32 amount) const { diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 376ee011638..c424e5d3ffe 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1755,16 +1755,20 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool sScriptMgr->OnGuildMemberWitdrawMoney(this, player, amount, repair); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - // Update remaining money amount - member->UpdateBankWithdrawValue(trans, GUILD_BANK_MAX_TABS, amount); - // Remove money from bank - _ModifyBankMoney(trans, amount, false); // Add money to player (if required) if (!repair) { - player->ModifyMoney(amount); + if (!player->ModifyMoney(amount)) + return false; + player->SaveGoldToDB(trans); } + + // Update remaining money amount + member->UpdateBankWithdrawValue(trans, GUILD_BANK_MAX_TABS, amount); + // Remove money from bank + _ModifyBankMoney(trans, amount, false); + // Log guild bank event _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUIDLow(), amount); CharacterDatabase.CommitTransaction(trans); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 5aeb59e7383..14b6df23061 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -532,13 +532,18 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData) return; } - player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK); + if (!player->ModifyMoney(m->money, false)) + { + player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_TOO_MUCH_GOLD); + return; + } - player->ModifyMoney(m->money); m->money = 0; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; + player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK); + // save money and mail to prevent cheating SQLTransaction trans = CharacterDatabase.BeginTransaction(); player->SaveGoldToDB(trans); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 2f9db8687c3..bb31b5c1dc8 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -292,6 +292,20 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) return; } + if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney()) + { + _player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + my_trade->SetAccepted(false, true); + return; + } + + if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney()) + { + trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + his_trade->SetAccepted(false, true); + return; + } + // not accept if some items now can't be trade (cheating) for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { @@ -302,6 +316,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); return; } + if (item->IsBindedNotWith(trader)) { SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE); diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 01648f25cff..eaed64db579 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1046,9 +1046,12 @@ public: ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), moneyToAdd); if (moneyToAdd >= MAX_MONEY_AMOUNT) - target->SetMoney(MAX_MONEY_AMOUNT); - else - target->ModifyMoney(moneyToAdd); + moneyToAdd = MAX_MONEY_AMOUNT; + + if (targetMoney >= uint32(MAX_MONEY_AMOUNT) - moneyToAdd) + moneyToAdd -= targetMoney; + + target->ModifyMoney(moneyToAdd); } sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_NEW_MONEY), targetMoney, moneyToAdd, target->GetMoney()); -- cgit v1.2.3 From 957375c7ff760742fcfa4d141a1e42aa0dd9825b Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 1 Feb 2013 11:40:39 +0100 Subject: Core/Misc: Fixed a few warning found by static analysis tools. --- src/server/game/Achievements/AchievementMgr.cpp | 11 +++++++---- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 19 ++++++++----------- src/server/game/World/World.cpp | 9 ++------- 3 files changed, 17 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 2fd55ac29ef..1de9c785ed2 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -2209,6 +2209,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() return; } + uint32 loaded = 0; for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(entryId); @@ -2220,9 +2221,11 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() if (criteria->timeLimit) m_AchievementCriteriasByTimedType[criteria->timedType].push_back(criteria); + + ++loaded; } - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %lu achievement criteria in %u ms", (unsigned long)m_AchievementCriteriasByType->size(), GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u achievement criteria in %u ms", loaded, GetMSTimeDiffToNow(oldMSTime)); } void AchievementGlobalMgr::LoadAchievementReferenceList() @@ -2284,14 +2287,14 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() } uint32 dataType = fields[1].GetUInt8(); - const char* scriptName = fields[4].GetCString(); + std::string scriptName = fields[4].GetString(); uint32 scriptId = 0; - if (strcmp(scriptName, "")) // not empty + if (scriptName.length()) // not empty { if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT) sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType); else - scriptId = sObjectMgr->GetScriptId(scriptName); + scriptId = sObjectMgr->GetScriptId(scriptName.c_str()); } AchievementCriteriaData data(dataType, fields[2].GetUInt32(), fields[3].GetUInt32(), scriptId); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 918e4f3bfc3..52e8523a72a 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3345,22 +3345,19 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const* aurApp, uint Unit* target = aurApp->GetTarget(); - target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, GetMiscValue(), apply); + target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, GetMiscValue(), apply); // when removing flag aura, handle flag drop - if (!apply && target->GetTypeId() == TYPEID_PLAYER - && (GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION)) + Player* player = target->ToPlayer(); + if (!apply && player && (GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION)) { - if (target->GetTypeId() == TYPEID_PLAYER) + if (player->InBattleground()) { - if (target->ToPlayer()->InBattleground()) - { - if (Battleground* bg = target->ToPlayer()->GetBattleground()) - bg->EventPlayerDroppedFlag(target->ToPlayer()); - } - else - sOutdoorPvPMgr->HandleDropFlag((Player*)target, GetSpellInfo()->Id); + if (Battleground* bg = player->GetBattleground()) + bg->EventPlayerDroppedFlag(player); } + else + sOutdoorPvPMgr->HandleDropFlag(player, GetSpellInfo()->Id); } } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index c43cbbd417e..b656783cf99 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2858,8 +2858,6 @@ void World::ResetMonthlyQuests() if (itr->second->GetPlayer()) itr->second->GetPlayer()->ResetMonthlyQuestStatus(); - time_t mostRecentQuestTime = 0; - // generate time time_t curTime = time(NULL); tm localTm = *localtime(&curTime); @@ -2889,11 +2887,8 @@ void World::ResetMonthlyQuests() // last reset time before current moment time_t resetTime = (curTime < nextMonthResetTime) ? nextMonthResetTime - MONTH : nextMonthResetTime; - // need reset (if we have quest time before last reset time (not processed by some reason) - if (mostRecentQuestTime && mostRecentQuestTime <= resetTime) - m_NextMonthlyQuestReset = mostRecentQuestTime; - else // plan next reset time - m_NextMonthlyQuestReset = (curTime >= nextMonthResetTime) ? nextMonthResetTime + MONTH : nextMonthResetTime; + // plan next reset time + m_NextMonthlyQuestReset = (curTime >= nextMonthResetTime) ? nextMonthResetTime + MONTH : nextMonthResetTime; sWorld->setWorldState(WS_MONTHLY_QUEST_RESET_TIME, uint64(m_NextMonthlyQuestReset)); } -- cgit v1.2.3 From 817f5b36483a6e8fe895ec8c2dc68179b8b450da Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 1 Feb 2013 18:06:51 +0100 Subject: Scripts/Icecrown Citadel: * Fixed Coldflame dealing double damage * Targets hit by Bone Slice will now be immune to Bone Spike Graveyard * Fixed healing players on Bone Spike Closes #1091 Closes #4473 Closes #5854 Closes #7060 --- .../2013_02_01_02_world_spell_script_names.sql | 4 + src/server/game/Spells/SpellEffects.cpp | 18 -- src/server/game/Spells/SpellMgr.cpp | 6 +- .../IcecrownCitadel/boss_lord_marrowgar.cpp | 204 ++++++++++++++++++--- 4 files changed, 182 insertions(+), 50 deletions(-) create mode 100644 sql/updates/world/2013_02_01_02_world_spell_script_names.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_01_02_world_spell_script_names.sql b/sql/updates/world/2013_02_01_02_world_spell_script_names.sql new file mode 100644 index 00000000000..33b7b1fab6e --- /dev/null +++ b/sql/updates/world/2013_02_01_02_world_spell_script_names.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_marrowgar_bone_slice'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(69055,'spell_marrowgar_bone_slice'), +(70814,'spell_marrowgar_bone_slice'); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ba7c87ba10a..8b440b665ad 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3212,24 +3212,6 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) switch (m_spellInfo->SpellFamilyName) { - case SPELLFAMILY_GENERIC: - { - switch (m_spellInfo->Id) - { - case 69055: // Saber Lash - case 70814: // Saber Lash - { - uint32 count = 0; - for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - if (ihit->effectMask & (1 << effIndex)) - ++count; - - totalDamagePercentMod /= count; - break; - } - } - break; - } case SPELLFAMILY_WARRIOR: { // Devastate (player ones) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index b258f01ccd5..dbd4e3904ea 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3397,9 +3397,9 @@ void SpellMgr::LoadDbcDataCorrections() case 70861: // Sindragosa's Lair Teleport spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DB; break; - case 69055: // Saber Lash (Lord Marrowgar) - case 70814: // Saber Lash (Lord Marrowgar) - spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_5_YARDS; // 5yd + case 69055: // Bone Slice (Lord Marrowgar) + case 70814: // Bone Slice (Lord Marrowgar) + spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_8_YARDS; // 5yd break; case 69075: // Bone Storm (Lord Marrowgar) case 70834: // Bone Storm (Lord Marrowgar) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 4763896cf72..5a669bc2a0b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -20,8 +20,9 @@ #include "ScriptedCreature.h" #include "SpellAuras.h" #include "MapManager.h" -#include "icecrown_citadel.h" +#include "MoveSplineInit.h" #include "Player.h" +#include "icecrown_citadel.h" enum ScriptTexts { @@ -78,7 +79,46 @@ enum MovementPoints POINT_TARGET_COLDFLAME = 36672631, }; -#define DATA_COLDFLAME_GUID 0 +enum MiscInfo +{ + DATA_COLDFLAME_GUID = 0, + + // Manual marking for targets hit by Bone Slice as no aura exists for this purpose + // These units are the tanks in this encounter + // and should be immune to Bone Spike Graveyard + DATA_SPIKE_IMMUNE = 1, + //DATA_SPIKE_IMMUNE_1, = 2, // Reserved & used + //DATA_SPIKE_IMMUNE_2, = 3, // Reserved & used + + ACTION_CLEAR_SPIKE_IMMUNITIES = 1, + + MAX_BONE_SPIKE_IMMUNE = 3, +}; + +class BoneSpikeTargetSelector : public std::unary_function +{ + public: + BoneSpikeTargetSelector(UnitAI* ai) : _ai(ai) { } + + bool operator()(Unit* unit) const + { + if (unit->GetTypeId() != TYPEID_PLAYER) + return false; + + if (unit->HasAura(SPELL_IMPALED)) + return false; + + // Check if it is one of the tanks soaking Bone Slice + for (uint32 i = 0; i < MAX_BONE_SPIKE_IMMUNE; ++i) + if (unit->GetGUID() == _ai->GetGUID(DATA_SPIKE_IMMUNE + i)) + return false; + + return true; + } + + private: + UnitAI* _ai; +}; class boss_lord_marrowgar : public CreatureScript { @@ -108,6 +148,7 @@ class boss_lord_marrowgar : public CreatureScript events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000)); events.ScheduleEvent(EVENT_ENRAGE, 600000); _boneSlice = false; + _boneSpikeImmune.clear(); } void EnterCombat(Unit* /*who*/) @@ -205,7 +246,7 @@ class boss_lord_marrowgar : public CreatureScript case EVENT_BONE_STORM_END: if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); - DoStartMovement(me->getVictim()); + me->GetMotionMaster()->MoveChase(me->getVictim()); me->SetSpeed(MOVE_RUN, _baseSpeed, true); events.CancelEvent(EVENT_BONE_STORM_MOVE); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); @@ -239,7 +280,7 @@ class boss_lord_marrowgar : public CreatureScript return; // lock movement - DoStartNoMovement(me->getVictim()); + me->GetMotionMaster()->MoveIdle(); } Position const* GetLastColdflamePosition() const @@ -247,23 +288,51 @@ class boss_lord_marrowgar : public CreatureScript return &_coldflameLastPos; } - uint64 GetGUID(int32 type/* = 0 */) const + uint64 GetGUID(int32 type /*= 0 */) const { - if (type == DATA_COLDFLAME_GUID) - return _coldflameTarget; + switch (type) + { + case DATA_COLDFLAME_GUID: + return _coldflameTarget; + case DATA_SPIKE_IMMUNE + 0: + case DATA_SPIKE_IMMUNE + 1: + case DATA_SPIKE_IMMUNE + 2: + { + int32 index = type - DATA_SPIKE_IMMUNE; + if (index < _boneSpikeImmune.size()) + return _boneSpikeImmune[index]; + + break; + } + } + return 0LL; } - void SetGUID(uint64 guid, int32 type/* = 0 */) + void SetGUID(uint64 guid, int32 type /*= 0 */) + { + switch (type) + { + case DATA_COLDFLAME_GUID: + _coldflameTarget = guid; + break; + case DATA_SPIKE_IMMUNE: + _boneSpikeImmune.push_back(guid); + break; + } + } + + void DoAction(int32 const action) { - if (type != DATA_COLDFLAME_GUID) + if (action != ACTION_CLEAR_SPIKE_IMMUNITIES) return; - _coldflameTarget = guid; + _boneSpikeImmune.clear(); } private: Position _coldflameLastPos; + std::vector _boneSpikeImmune; uint64 _coldflameTarget; uint32 _boneStormDuration; float _baseSpeed; @@ -323,7 +392,7 @@ class npc_coldflame : public CreatureScript } me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 450); + _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 500); } void UpdateAI(uint32 const diff) @@ -333,10 +402,10 @@ class npc_coldflame : public CreatureScript if (_events.ExecuteEvent() == EVENT_COLDFLAME_TRIGGER) { Position newPos; - me->GetNearPosition(newPos, 5.5f, 0.0f); + me->GetNearPosition(newPos, 5.0f, 0.0f); me->NearTeleportTo(newPos.GetPositionX(), newPos.GetPositionY(), me->GetPositionZ(), me->GetOrientation()); DoCast(SPELL_COLDFLAME_SUMMON); - _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 450); + _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 500); } } @@ -385,6 +454,24 @@ class npc_bone_spike : public CreatureScript _hasTrappedUnit = true; } + void PassengerBoarded(Unit* passenger, int8 /*seat*/, bool apply) + { + if (!apply) + return; + + /// @HACK - Change passenger offset to the one taken directly from sniffs + /// Remove this when proper calculations are implemented. + /// This fixes healing spiked people + Movement::MoveSplineInit init(passenger); + init.DisableTransportPathTransformations(); + init.MoveTo(-0.02206125f, -0.02132235f, 5.514783f, false); + init.Launch(); + + /// @WORKAROUND - Clear ON VEHICLE state to allow healing (Invalid target errors) + /// Current rule for applying this state is questionable (seatFlags & VEHICLE_SEAT_FLAG_ALLOW_TURNING ???) + passenger->ClearUnitState(UNIT_STATE_ONVEHICLE); + } + void UpdateAI(uint32 const diff) { if (!_hasTrappedUnit) @@ -487,16 +574,24 @@ class spell_marrowgar_coldflame_damage : public SpellScriptLoader { PrepareAuraScript(spell_marrowgar_coldflame_damage_AuraScript); - void OnPeriodic(AuraEffect const* /*aurEff*/) + bool CanBeAppliedOn(Unit* target) { - if (DynamicObject* owner = GetDynobjOwner()) - if (GetTarget()->GetExactDist2d(owner) >= owner->GetRadius() || GetTarget()->HasAura(SPELL_IMPALED)) - PreventDefaultAction(); + if (target->HasAura(SPELL_IMPALED)) + return false; + + if (target->GetExactDist2d(GetOwner()) > GetSpellInfo()->Effects[EFFECT_0].CalcRadius()) + return false; + + if (Aura* aur = target->GetAura(GetId())) + if (aur->GetOwner() != GetOwner()) + return false; + + return true; } void Register() { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_marrowgar_coldflame_damage_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_marrowgar_coldflame_damage_AuraScript::CanBeAppliedOn); } }; @@ -531,7 +626,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader SpellCastResult CheckCast() { - return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 0.0f, true, -SPELL_IMPALED) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS; + return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, BoneSpikeTargetSelector(GetCaster()->GetAI())) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS; } void HandleSpikes(SpellEffIndex effIndex) @@ -539,22 +634,22 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader PreventHitDefaultEffect(effIndex); if (Creature* marrowgar = GetCaster()->ToCreature()) { - bool didHit = false; CreatureAI* marrowgarAI = marrowgar->AI(); uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1); - for (uint8 i = 0; i < boneSpikeCount; ++i) - { - // select any unit but not the tank - Unit* target = marrowgarAI->SelectTarget(SELECT_TARGET_RANDOM, 1, 150.0f, true, -SPELL_IMPALED); - if (!target) - break; - didHit = true; + std::list targets; + marrowgarAI->SelectTargetList(targets, BoneSpikeTargetSelector(marrowgarAI), boneSpikeCount, SELECT_TARGET_RANDOM); + if (targets.empty()) + return; + + uint32 i = 0; + for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr, ++i) + { + Unit* target = *itr; target->CastCustomSpell(BoneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); } - if (didHit) - marrowgarAI->Talk(SAY_BONESPIKE); + marrowgarAI->Talk(SAY_BONESPIKE); } } @@ -597,6 +692,56 @@ class spell_marrowgar_bone_storm : public SpellScriptLoader } }; +class spell_marrowgar_bone_slice : public SpellScriptLoader +{ + public: + spell_marrowgar_bone_slice() : SpellScriptLoader("spell_marrowgar_bone_slice") { } + + class spell_marrowgar_bone_slice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_marrowgar_bone_slice_SpellScript); + + bool Load() + { + _targetCount = 0; + return true; + } + + void ClearSpikeImmunities() + { + GetCaster()->GetAI()->DoAction(ACTION_CLEAR_SPIKE_IMMUNITIES); + } + + void CountTarget(SpellEffIndex /*effIndex*/) + { + ++_targetCount; + GetCaster()->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_SPIKE_IMMUNE); + } + + void SplitDamage() + { + if (!_targetCount) + return; // why would there be an unit not hit by effect hook and hit by this? + + SetHitDamage(GetHitDamage() / _targetCount); + } + + void Register() + { + BeforeCast += SpellCastFn(spell_marrowgar_bone_slice_SpellScript::ClearSpikeImmunities); + OnEffectLaunchTarget += SpellEffectFn(spell_marrowgar_bone_slice_SpellScript::CountTarget, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); + OnHit += SpellHitFn(spell_marrowgar_bone_slice_SpellScript::SplitDamage); + } + + uint32 _targetCount; + }; + + SpellScript* GetSpellScript() const + { + return new spell_marrowgar_bone_slice_SpellScript(); + } +}; + void AddSC_boss_lord_marrowgar() { new boss_lord_marrowgar(); @@ -607,4 +752,5 @@ void AddSC_boss_lord_marrowgar() new spell_marrowgar_coldflame_damage(); new spell_marrowgar_bone_spike_graveyard(); new spell_marrowgar_bone_storm(); + new spell_marrowgar_bone_slice(); } -- cgit v1.2.3 From 0b72a91e7667943dd128ca28f5bb71d8457d3ec9 Mon Sep 17 00:00:00 2001 From: Warpten Date: Fri, 1 Feb 2013 19:55:23 +0100 Subject: Core/Hunters: Fixed focus power for pets. Closes #8553. --- src/server/game/Entities/Player/Player.cpp | 8 ++++---- src/server/game/Entities/Unit/Unit.cpp | 25 +++++++++++++++++++------ src/server/game/Entities/Unit/Unit.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 67dc948ed99..41142e2de27 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2525,7 +2525,7 @@ void Player::Regenerate(Powers power) return; // Skip regeneration for power type we cannot have - uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + uint32 powerIndex = GetPowerIndex(power); if (powerIndex == MAX_POWERS) return; @@ -17343,7 +17343,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) uint32 loadedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) { - if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + if (GetPowerIndex(i) != MAX_POWERS) { uint32 savedPower = fields[47+loadedPowers].GetUInt32(); uint32 maxPower = GetUInt32Value(UNIT_FIELD_MAXPOWER1 + loadedPowers); @@ -18937,7 +18937,7 @@ void Player::SaveToDB(bool create /*=false*/) uint32 storedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) { - if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + if (GetPowerIndex(i) != MAX_POWERS) { stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers)); if (++storedPowers >= MAX_POWERS_PER_CLASS) @@ -19057,7 +19057,7 @@ void Player::SaveToDB(bool create /*=false*/) uint32 storedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) { - if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + if (GetPowerIndex(i) != MAX_POWERS) { stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers)); if (++storedPowers >= MAX_POWERS_PER_CLASS) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 32ade87fef4..2db63040e83 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9224,7 +9224,7 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) DoneAdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus(); // Check if we are ever using mana - PaperDollFrame.lua - if (GetPowerIndexByClass(POWER_MANA, getClass()) != MAX_POWERS) + if (GetPowerIndex(POWER_MANA) != MAX_POWERS) DoneAdvertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect // Damage bonus from stats @@ -9747,7 +9747,7 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) AdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus(); // Check if we are ever using mana - PaperDollFrame.lua - if (GetPowerIndexByClass(POWER_MANA, getClass()) != MAX_POWERS) + if (GetPowerIndex(POWER_MANA) != MAX_POWERS) AdvertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect // Healing bonus from stats @@ -12364,7 +12364,7 @@ void Unit::SetMaxHealth(uint32 val) int32 Unit::GetPower(Powers power) const { - uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + uint32 powerIndex = GetPowerIndex(power); if (powerIndex == MAX_POWERS) return 0; @@ -12373,7 +12373,7 @@ int32 Unit::GetPower(Powers power) const int32 Unit::GetMaxPower(Powers power) const { - uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + uint32 powerIndex = GetPowerIndex(power); if (powerIndex == MAX_POWERS) return 0; @@ -12382,7 +12382,7 @@ int32 Unit::GetMaxPower(Powers power) const void Unit::SetPower(Powers power, int32 val) { - uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + uint32 powerIndex = GetPowerIndex(power); if (powerIndex == MAX_POWERS) return; @@ -12421,7 +12421,7 @@ void Unit::SetPower(Powers power, int32 val) void Unit::SetMaxPower(Powers power, int32 val) { - uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + uint32 powerIndex = GetPowerIndex(power); if (powerIndex == MAX_POWERS) return; @@ -12448,6 +12448,19 @@ void Unit::SetMaxPower(Powers power, int32 val) SetPower(power, val); } +uint32 Unit::GetPowerIndex(uint32 powerType) const +{ + /// This is here because hunter pets are of the warrior class. + /// With the current implementation, the core only gives them + /// POWER_RAGE, so we enforce the class to hunter so that they + /// effectively get focus power. + uint32 classId = getClass(); + if (ToPet() && ToPet()->getPetType() == HUNTER_PET) + classId = CLASS_HUNTER; + + return GetPowerIndexByClass(powerType, classId); +} + int32 Unit::GetCreatePowers(Powers power) const { switch (power) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b723be7bee7..a8e088b2dd3 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1877,6 +1877,7 @@ class Unit : public WorldObject uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); } uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); } + uint32 GetPowerIndex(uint32 powerType) const; int32 GetCreatePowers(Powers power) const; float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); } float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } -- cgit v1.2.3 From b47cb65b03adc28513b3b888b0ed65599101b654 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 2 Feb 2013 16:45:57 +0100 Subject: Core/Scripts: Allow persistent area auras to use DoCheckAreaTarget hook. --- src/server/game/Spells/SpellScript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 89ed223545f..6229a30a5f0 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -612,7 +612,7 @@ SpellValue const* SpellScript::GetSpellValue() bool AuraScript::_Validate(SpellInfo const* entry) { for (std::list::iterator itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr) - if (!entry->HasAreaAuraEffect()) + if (!entry->HasAreaAuraEffect() && !entry->HasEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA)) sLog->outError(LOG_FILTER_TSCR, "Spell `%u` of script `%s` does not have area aura effect - handler bound to hook `DoCheckAreaTarget` of AuraScript won't be executed", entry->Id, m_scriptName->c_str()); for (std::list::iterator itr = OnDispel.begin(); itr != OnDispel.end(); ++itr) -- cgit v1.2.3 From f410bf97555419a707137b3b35d44596fc9d8b49 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 2 Feb 2013 16:46:14 +0100 Subject: Core/World: Fixed a warning --- src/server/game/World/World.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index b656783cf99..f28b9548e5f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2884,9 +2884,6 @@ void World::ResetMonthlyQuests() time_t nextMonthResetTime = mktime(&localTm); - // last reset time before current moment - time_t resetTime = (curTime < nextMonthResetTime) ? nextMonthResetTime - MONTH : nextMonthResetTime; - // plan next reset time m_NextMonthlyQuestReset = (curTime >= nextMonthResetTime) ? nextMonthResetTime + MONTH : nextMonthResetTime; -- cgit v1.2.3 From 73d2f315af9f45dacc20a9d6789e0cc86338e7a0 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 2 Feb 2013 16:48:09 +0100 Subject: Scripts/Icecrown Citadel * Fixed rare weird coldflame positioning * Fixed Bone Slice * Changed Bone Spike Graveyard timing (first has to happen after Lord Marrowgar starts using Bone Slice) --- .../IcecrownCitadel/boss_lord_marrowgar.cpp | 42 +++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 5a669bc2a0b..aa65cfda97e 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -143,7 +143,7 @@ class boss_lord_marrowgar : public CreatureScript me->RemoveAurasDueToSpell(SPELL_BONE_STORM); me->RemoveAurasDueToSpell(SPELL_BERSERK); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); - events.ScheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, urand(10000, 15000), EVENT_GROUP_SPECIAL); + events.ScheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, 15000, EVENT_GROUP_SPECIAL); events.ScheduleEvent(EVENT_COLDFLAME, 5000, EVENT_GROUP_SPECIAL); events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000)); events.ScheduleEvent(EVENT_ENRAGE, 600000); @@ -240,7 +240,7 @@ class boss_lord_marrowgar : public CreatureScript if (!unit) unit = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); if (unit) - me->GetMotionMaster()->MovePoint(POINT_TARGET_BONESTORM_PLAYER, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ()); + me->GetMotionMaster()->MovePoint(POINT_TARGET_BONESTORM_PLAYER, *unit); break; } case EVENT_BONE_STORM_END: @@ -251,7 +251,7 @@ class boss_lord_marrowgar : public CreatureScript events.CancelEvent(EVENT_BONE_STORM_MOVE); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); if (!IsHeroic()) - events.RescheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, urand(15000, 20000), EVENT_GROUP_SPECIAL); + events.RescheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, 15000, EVENT_GROUP_SPECIAL); break; case EVENT_ENABLE_BONE_SLICE: _boneSlice = true; @@ -364,19 +364,17 @@ class npc_coldflame : public CreatureScript if (owner->GetTypeId() != TYPEID_UNIT) return; - Creature* creOwner = owner->ToCreature(); Position pos; - // random target case + if (MarrowgarAI* marrowgarAI = CAST_AI(MarrowgarAI, owner->GetAI())) + pos.Relocate(marrowgarAI->GetLastColdflamePosition()); + else + pos.Relocate(owner); + if (owner->HasAura(SPELL_BONE_STORM)) { - if (MarrowgarAI* marrowgarAI = CAST_AI(MarrowgarAI, creOwner->AI())) - { - Position const* ownerPos = marrowgarAI->GetLastColdflamePosition(); - float ang = me->GetAngle(ownerPos) - static_cast(M_PI); - MapManager::NormalizeOrientation(ang); - me->SetOrientation(ang); - owner->GetNearPosition(pos, 2.5f, 0.0f); - } + float ang = MapManager::NormalizeOrientation(pos.GetAngle(me)); + me->SetOrientation(ang); + owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 5.0f - owner->GetObjectSize(), ang); } else { @@ -387,11 +385,13 @@ class npc_coldflame : public CreatureScript return; } - me->SetOrientation(owner->GetAngle(target)); - owner->GetNearPosition(pos, owner->GetObjectSize() / 2.0f, 0.0f); + float ang = MapManager::NormalizeOrientation(pos.GetAngle(target)); + me->SetOrientation(ang); + owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 15.0f - owner->GetObjectSize(), ang); } me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + DoCast(SPELL_COLDFLAME_SUMMON); _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 500); } @@ -712,16 +712,18 @@ class spell_marrowgar_bone_slice : public SpellScriptLoader GetCaster()->GetAI()->DoAction(ACTION_CLEAR_SPIKE_IMMUNITIES); } - void CountTarget(SpellEffIndex /*effIndex*/) + void CountTargets(std::list& targets) { - ++_targetCount; - GetCaster()->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_SPIKE_IMMUNE); + _targetCount = std::min(targets.size(), GetSpellInfo()->MaxAffectedTargets); } void SplitDamage() { + // Mark the unit as hit, even if the spell missed or was dodged/parried + GetCaster()->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_SPIKE_IMMUNE); + if (!_targetCount) - return; // why would there be an unit not hit by effect hook and hit by this? + return; // This spell can miss all targets SetHitDamage(GetHitDamage() / _targetCount); } @@ -729,7 +731,7 @@ class spell_marrowgar_bone_slice : public SpellScriptLoader void Register() { BeforeCast += SpellCastFn(spell_marrowgar_bone_slice_SpellScript::ClearSpikeImmunities); - OnEffectLaunchTarget += SpellEffectFn(spell_marrowgar_bone_slice_SpellScript::CountTarget, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_bone_slice_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); OnHit += SpellHitFn(spell_marrowgar_bone_slice_SpellScript::SplitDamage); } -- cgit v1.2.3 From 9d7d68395c3d091f27bbb2e2d50f5052627f5e81 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 2 Feb 2013 18:18:27 +0100 Subject: Core/SmartAI: Implement SMART_ACTION_SET_ROOT (103) --- src/server/game/AI/SmartScripts/SmartScript.cpp | 6 ++++ src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 1 + src/server/game/AI/SmartScripts/SmartScriptMgr.h | 8 ++++- src/server/game/Entities/Unit/Unit.cpp | 35 ++++++++++++++++------ 4 files changed, 40 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 86d86739bc9..23f6fbbb414 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1996,6 +1996,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u me->setRegeneratingHealth(e.action.setHealthRegen.regenHealth ? true : false); break; } + case SMART_ACTION_SET_ROOT: + { + if (me) + me->SetControlled(e.action.setRoot.root ? true : false, UNIT_STATE_ROOT); + break; + } default: sLog->outError(LOG_FILTER_SQL, "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index a49ae031e63..90534de327a 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -906,6 +906,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_SEND_TARGET_TO_TARGET: case SMART_ACTION_SET_HOME_POS: case SMART_ACTION_SET_HEALTH_REGEN: + case SMART_ACTION_SET_ROOT: break; default: sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index c88ef206b00..88f9ce4f6f4 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -486,8 +486,9 @@ enum SMART_ACTION SMART_ACTION_SEND_TARGET_TO_TARGET = 100, // id SMART_ACTION_SET_HOME_POS = 101, // none SMART_ACTION_SET_HEALTH_REGEN = 102, // 0/1 + SMART_ACTION_SET_ROOT = 103, // off/on - SMART_ACTION_END = 103 + SMART_ACTION_END = 104 }; struct SmartAction @@ -919,6 +920,11 @@ struct SmartAction uint32 regenHealth; } setHealthRegen; + struct + { + uint32 root; + } setRoot; + //! Note for any new future actions //! All parameters must have type uint32 diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 948b88d4702..1e64fc234b9 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15296,15 +15296,32 @@ void Unit::SetControlled(bool apply, UnitState state) { switch (state) { - case UNIT_STATE_STUNNED: if (HasAuraType(SPELL_AURA_MOD_STUN)) return; - else SetStunned(false); break; - case UNIT_STATE_ROOT: if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle()) return; - else SetRooted(false); break; - case UNIT_STATE_CONFUSED:if (HasAuraType(SPELL_AURA_MOD_CONFUSE)) return; - else SetConfused(false); break; - case UNIT_STATE_FLEEING: if (HasAuraType(SPELL_AURA_MOD_FEAR)) return; - else SetFeared(false); break; - default: return; + case UNIT_STATE_STUNNED: + if (HasAuraType(SPELL_AURA_MOD_STUN)) + return; + else + SetStunned(false); + break; + case UNIT_STATE_ROOT: + if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle()) + return; + else + SetRooted(false); + break; + case UNIT_STATE_CONFUSED: + if (HasAuraType(SPELL_AURA_MOD_CONFUSE)) + return; + else + SetConfused(false); + break; + case UNIT_STATE_FLEEING: + if (HasAuraType(SPELL_AURA_MOD_FEAR)) + return; + else + SetFeared(false); + break; + default: + return; } ClearUnitState(state); -- cgit v1.2.3 From 2c2fe7d464a819821a8b8eb58af7cc02380ebbd2 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sat, 2 Feb 2013 19:06:47 +0100 Subject: Core/Misc: Small code optimisations --- src/server/game/AI/SmartScripts/SmartScript.cpp | 56 ++++++++++++++++++------- src/server/game/Entities/Unit/Unit.cpp | 16 +++---- 2 files changed, 49 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 23f6fbbb414..0536d8c7317 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1893,12 +1893,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_JUMP_TO_POS: { - if (!me) + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + { + (*itr)->ToCreature()->GetMotionMaster()->Clear(); + (*itr)->ToCreature()->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); + } // TODO: Resume path when reached jump location + + delete targets; break; } case SMART_ACTION_GO_SET_LOOT_STATE: @@ -1977,29 +1984,48 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_SET_HOME_POS: { - if (!me) + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - if (e.GetTargetType() == SMART_TARGET_SELF) - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - else if (e.GetTargetType() == SMART_TARGET_POSITION) - me->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); - else - sLog->outError(LOG_FILTER_SQL, "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is not using SMART_TARGET_SELF or SMART_TARGET_POSITION, skipping"); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + { + if (e.GetTargetType() == SMART_TARGET_SELF) + (*itr)->ToCreature()->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + else if (e.GetTargetType() == SMART_TARGET_POSITION) + (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + else + sLog->outError(LOG_FILTER_SQL, "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is not using SMART_TARGET_SELF or SMART_TARGET_POSITION, skipping"); + } - break; + delete targets; + break; } case SMART_ACTION_SET_HEALTH_REGEN: { - if (!me || me->GetTypeId() != TYPEID_UNIT) + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - me->setRegeneratingHealth(e.action.setHealthRegen.regenHealth ? true : false); + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth ? true : false); + + delete targets; break; } case SMART_ACTION_SET_ROOT: { - if (me) - me->SetControlled(e.action.setRoot.root ? true : false, UNIT_STATE_ROOT); + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetControlled(e.action.setRoot.root ? true : false, UNIT_STATE_ROOT); + + delete targets; break; } default: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1e64fc234b9..e3a2430f63a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15299,26 +15299,26 @@ void Unit::SetControlled(bool apply, UnitState state) case UNIT_STATE_STUNNED: if (HasAuraType(SPELL_AURA_MOD_STUN)) return; - else - SetStunned(false); + + SetStunned(false); break; case UNIT_STATE_ROOT: if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle()) return; - else - SetRooted(false); + + SetRooted(false); break; case UNIT_STATE_CONFUSED: if (HasAuraType(SPELL_AURA_MOD_CONFUSE)) return; - else - SetConfused(false); + + SetConfused(false); break; case UNIT_STATE_FLEEING: if (HasAuraType(SPELL_AURA_MOD_FEAR)) return; - else - SetFeared(false); + + SetFeared(false); break; default: return; -- cgit v1.2.3 From 847cafc121d1fb2557178e6832225ece486fcadb Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 3 Feb 2013 00:38:34 +0100 Subject: Scripts/Misc: Some code optimisations --- src/server/game/AI/SmartScripts/SmartScript.cpp | 2 +- .../BlackwingLair/boss_broodlord_lashlayer.cpp | 11 ++-- .../EasternKingdoms/BlackwingLair/boss_firemaw.cpp | 14 ++--- .../BlackwingLair/boss_flamegor.cpp | 12 +++-- .../SunwellPlateau/boss_kalecgos.cpp | 5 +- .../EasternKingdoms/ZulAman/boss_akilzon.cpp | 7 ++- .../EasternKingdoms/ZulGurub/boss_grilek.cpp | 8 ++- .../EasternKingdoms/ZulGurub/boss_jeklik.cpp | 14 +++-- .../EasternKingdoms/ZulGurub/boss_jindo.cpp | 11 ++-- .../BattleForMountHyjal/hyjal_trash.cpp | 3 +- .../DarkPortal/boss_chrono_lord_deja.cpp | 4 +- .../Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp | 9 ++-- .../Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp | 4 +- src/server/scripts/Kalimdor/zone_thunder_bluff.cpp | 3 +- .../Ulduar/HallsOfLightning/boss_ionar.cpp | 3 +- .../Ulduar/HallsOfStone/boss_maiden_of_grief.cpp | 4 +- .../scripts/Outland/BlackTemple/boss_bloodboil.cpp | 10 ++-- .../scripts/Outland/BlackTemple/boss_illidan.cpp | 3 +- .../Outland/BlackTemple/boss_teron_gorefiend.cpp | 3 +- .../SerpentShrine/boss_fathomlord_karathress.cpp | 62 ++++++---------------- .../SerpentShrine/boss_hydross_the_unstable.cpp | 3 +- .../SerpentShrine/boss_morogrim_tidewalker.cpp | 7 ++- .../Outland/GruulsLair/boss_high_king_maulgar.cpp | 3 +- .../Outland/TempestKeep/Eye/boss_astromancer.cpp | 10 ++-- 24 files changed, 96 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 0536d8c7317..690e87ae19c 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1898,7 +1898,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) + if (Creature* creature = (*itr)->ToCreature()) { (*itr)->ToCreature()->GetMotionMaster()->Clear(); (*itr)->ToCreature()->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp index 0aeba151385..fa1ab5528ca 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp @@ -101,10 +101,13 @@ public: if (KnockBack_Timer <= diff) { - DoCast(me->getVictim(), SPELL_KNOCKBACK); - //Drop 50% aggro - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(), -50); + if (Unit* target = me->getVictim()) + { + DoCast(target, SPELL_KNOCKBACK); + // Drop 50% aggro + if (DoGetThreat(target)) + DoModifyThreatPercent(target, -50); + } KnockBack_Timer = urand(15000, 30000); } else KnockBack_Timer -= diff; diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp index 7ca74f4ed4f..4c36d78667b 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp @@ -68,24 +68,26 @@ public: //ShadowFlame_Timer if (ShadowFlame_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWFLAME); + DoCastVictim(SPELL_SHADOWFLAME); ShadowFlame_Timer = urand(15000, 18000); } else ShadowFlame_Timer -= diff; //WingBuffet_Timer if (WingBuffet_Timer <= diff) { - DoCast(me->getVictim(), SPELL_WINGBUFFET); - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(), -75); - + if (Unit* target = me->getVictim()) + { + DoCast(target, SPELL_WINGBUFFET); + if (DoGetThreat(target)) + DoModifyThreatPercent(target, -75); + } WingBuffet_Timer = 25000; } else WingBuffet_Timer -= diff; //FlameBuffet_Timer if (FlameBuffet_Timer <= diff) { - DoCast(me->getVictim(), SPELL_FLAMEBUFFET); + DoCastVictim(SPELL_FLAMEBUFFET); FlameBuffet_Timer = 5000; } else FlameBuffet_Timer -= diff; diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp index a1659330a6f..57215e3f43d 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp @@ -76,17 +76,19 @@ public: //ShadowFlame_Timer if (ShadowFlame_Timer <= diff) { - DoCast(me->getVictim(), SPELL_SHADOWFLAME); + DoCastVictim(SPELL_SHADOWFLAME); ShadowFlame_Timer = urand(15000, 22000); } else ShadowFlame_Timer -= diff; //WingBuffet_Timer if (WingBuffet_Timer <= diff) { - DoCast(me->getVictim(), SPELL_WINGBUFFET); - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(), -75); - + if (Unit* target = me->getVictim()) + { + DoCast(target, SPELL_WINGBUFFET); + if (DoGetThreat(target)) + DoModifyThreatPercent(target, -75); + } WingBuffet_Timer = 25000; } else WingBuffet_Timer -= diff; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index a8755c16418..742c80bea39 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -780,8 +780,9 @@ public: if (AgonyCurseTimer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (!target) target = me->getVictim(); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); + if (!target) + target = me->getVictim(); DoCast(target, SPELL_AGONY_CURSE); AgonyCurseTimer = 20000; } else AgonyCurseTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 1b2512ccf63..f1cb7b4116a 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -201,8 +201,11 @@ class boss_akilzon : public CreatureScript //dealdamege for (std::list::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) { - if (!Cloud->IsWithinDist(*i, 6, false)) - Cloud->CastCustomSpell(*i, 43137, &bp0, NULL, NULL, true, 0, 0, me->GetGUID()); + if (Unit* target = (*i)) + { + if (!Cloud->IsWithinDist(target, 6, false)) + Cloud->CastCustomSpell(target, 43137, &bp0, NULL, NULL, true, 0, 0, me->GetGUID()); + } } // visual float x, y, z; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp index f06500694a5..77f6127c76c 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp @@ -80,8 +80,12 @@ class boss_grilek : public CreatureScript // grilek { case EVENT_AVATAR: DoCast(me, SPELL_AVATAR); - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(), -50); + if (Unit* victim = me->getVictim()) + { + if (DoGetThreat(victim)) + DoModifyThreatPercent(victim, -50); + } + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) AttackStart(target); events.ScheduleEvent(EVENT_AVATAR, urand(25000, 35000)); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp index dc02c895327..e686881a672 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp @@ -158,7 +158,7 @@ class boss_jeklik : public CreatureScript //jeklik { if (PhaseTwo) { - if (PhaseTwo && ShadowWordPain_Timer <= diff) + if (ShadowWordPain_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { @@ -189,13 +189,11 @@ class boss_jeklik : public CreatureScript //jeklik if (SpawnFlyingBats_Timer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (!target) - return; - - Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (FlyingBat) - FlyingBat->AI()->AttackStart(target); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + FlyingBat->AI()->AttackStart(target); + } SpawnFlyingBats_Timer = urand(10000, 15000); } else SpawnFlyingBats_Timer -=diff; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp index 005609e88db..3c2b0f54225 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp @@ -110,9 +110,12 @@ class boss_jindo : public CreatureScript events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000)); break; case EVENT_HEX: - DoCastVictim(SPELL_HEX, true); - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(), -80); + if (Unit* target = me->getVictim()) + { + DoCast(target, SPELL_HEX, true); + if (DoGetThreat(target)) + DoModifyThreatPercent(target, -80); + } events.ScheduleEvent(EVENT_HEX, urand(12000, 20000)); break; case EVENT_DELUSIONSOFJINDO: // HACK @@ -161,7 +164,7 @@ class boss_jindo : public CreatureScript SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (SacrificedTroll) SacrificedTroll->AI()->AttackStart(target); - } + } events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000)); break; default: diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 36f6f94b324..2eb1b65fefd 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -1369,8 +1369,7 @@ public: forcemove = false; if (forcemove) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) me->Attack(target, false); } if (MoveTimer <= diff) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp index ea372621026..7ac8d4e783b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp @@ -124,8 +124,8 @@ public: //Arcane Discharge if (ArcaneDischarge_Timer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - DoCast(target, SPELL_ARCANE_DISCHARGE); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_ARCANE_DISCHARGE); ArcaneDischarge_Timer = 20000+rand()%10000; } else ArcaneDischarge_Timer -= diff; diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp index 2a9ea4ba4fc..a16e9cfa89d 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp @@ -274,10 +274,11 @@ public: for (uint8 i = 0; i < 10; ++i) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000); - if (Summoned && target) - Summoned->AI()->AttackStart(target); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000)) + Summoned->AI()->AttackStart(target); + } } } diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp index 80fdc111911..52d59efd0df 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp @@ -137,9 +137,7 @@ public: { if (SpawnHatchlings_Timer <= diff) { - Unit* target = NULL; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target && target->GetTypeId() == TYPEID_PLAYER) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { DoCast(target, SPELL_ROOT); diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp index 0d915dc7c44..dd0d52fb641 100644 --- a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp +++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp @@ -105,8 +105,7 @@ public: if (BerserkerChargeTimer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);) DoCast(target, SPELL_BERSERKER_CHARGE); BerserkerChargeTimer = 25000; } else BerserkerChargeTimer -= diff; diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index 6f017884063..dc0ffcd2c63 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -198,8 +198,7 @@ public: summoned->CastSpell(summoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER, H_SPELL_SPARK_VISUAL_TRIGGER), true); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { summoned->SetInCombatWith(target); summoned->GetMotionMaster()->Clear(); diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp index 7fbf5f3ee79..8accb3182ce 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp @@ -117,9 +117,7 @@ public: { if (PartingSorrowTimer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_PARTING_SORROW); PartingSorrowTimer = urand(30000, 40000); diff --git a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp index 3a56a0bfed2..53d51e1fd6c 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp @@ -187,9 +187,7 @@ public: void RevertThreatOnTarget(uint64 guid) { - Unit* unit = NULL; - unit = Unit::GetUnit(*me, guid); - if (unit) + if (Unit* unit = Unit::GetUnit(*me, guid)) { if (DoGetThreat(unit)) DoModifyThreatPercent(unit, -100); @@ -279,8 +277,7 @@ public: { if (Phase1) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target && target->isAlive()) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Phase1 = false; @@ -308,7 +305,8 @@ public: AcidGeyserTimer = 1000; PhaseChangeTimer = 30000; } - } else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage + } + else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage { if (TargetGUID) RevertThreatOnTarget(TargetGUID); diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index b8003761cc7..fff44baa7bf 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -422,8 +422,7 @@ public: Glaive->InterruptNonMeleeSpells(true); DoCast(me, SPELL_FLAME_ENRAGE, true); DoResetThreat(); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target && target->isAlive()) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->AddThreat(me->getVictim(), 5000000.0f); AttackStart(me->getVictim()); diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 6c28b058cf7..2dc0517dc49 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -468,8 +468,7 @@ public: if (CrushingShadowsTimer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target && target->isAlive()) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_CRUSHING_SHADOWS); CrushingShadowsTimer = urand(10, 26) * 1000; } else CrushingShadowsTimer -= diff; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index d9ad35f9552..5037f1c4964 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -227,9 +227,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); - - if (target) + if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) { AttackStart(target); GetAdvisors(); @@ -360,12 +358,8 @@ public: { if (instance) { - Creature* Karathress = NULL; - Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))); - - if (Karathress) - if (!me->isAlive() && Karathress) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath(); + if (Creature* Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))) + CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath(); } } @@ -383,12 +377,8 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); - - if (target) - { + if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); - } } //Return since we have no target @@ -445,12 +435,13 @@ public: pet_id = CREATURE_FATHOM_SPOREBAT; } //DoCast(me, spell_id, true); - Creature* Pet = DoSpawnCreature(pet_id, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (Pet && target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { - Pet->AI()->AttackStart(target); - SummonedPet = Pet->GetGUID(); + if (Creature* Pet = DoSpawnCreature(pet_id, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + { + Pet->AI()->AttackStart(target); + SummonedPet = Pet->GetGUID(); + } } } else Pet_Timer -= diff; @@ -500,12 +491,8 @@ public: { if (instance) { - Creature* Karathress = NULL; - Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))); - - if (Karathress) - if (!me->isAlive() && Karathress) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath(); + if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))) + CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath(); } } @@ -524,12 +511,8 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); - - if (target) - { + if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); - } } //Return since we have no target @@ -627,12 +610,8 @@ public: { if (instance) { - Creature* Karathress = NULL; - Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))); - - if (Karathress) - if (!me->isAlive() && Karathress) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath(); + if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))) + CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath(); } } @@ -650,12 +629,8 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); - - if (target) - { + if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); - } } //Return since we have no target @@ -697,11 +672,8 @@ public: Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Cyclone->setFaction(me->getFaction()); Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) Cyclone->AI()->AttackStart(target); - } } } else Cyclone_Timer -= diff; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp index b31292c4b00..ec85fe7293d 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp @@ -272,8 +272,7 @@ public: //VileSludge_Timer if (VileSludge_Timer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_VILE_SLUDGE); VileSludge_Timer = 15000; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp index 9476bb28f8e..06ea83881c8 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp @@ -184,10 +184,9 @@ public: for (uint8 i = 0; i < 10; ++i) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (target && Murloc) - Murloc->AI()->AttackStart(target); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + if (Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) + Murloc->AI()->AttackStart(target); } Talk(EMOTE_EARTHQUAKE); Earthquake = false; diff --git a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp index 83596c46936..e2b2425dcfc 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp @@ -519,8 +519,7 @@ public: //GreaterPolymorph_Timer if (GreaterPolymorph_Timer <= diff) { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_GREATER_POLYMORPH); GreaterPolymorph_Timer = urand(15000, 20000); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index 01ca1636c6b..9ec6691839b 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -245,11 +245,13 @@ class boss_high_astromancer_solarian : public CreatureScript } else { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (!me->HasInArc(2.5f, target)) - target = me->getVictim(); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (!me->HasInArc(2.5f, target)) + target = me->getVictim(); + DoCast(target, SPELL_ARCANE_MISSILES); + } } ArcaneMissiles_Timer = 3000; } -- cgit v1.2.3 From 0f53f69e52f91c035f22cd0cfcad6a9a25509b2a Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 3 Feb 2013 01:12:07 +0100 Subject: Core: Fix build --- src/server/game/AI/SmartScripts/SmartScript.cpp | 4 ++-- src/server/scripts/Kalimdor/zone_thunder_bluff.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 690e87ae19c..e37b9e777d8 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1900,8 +1900,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) if (Creature* creature = (*itr)->ToCreature()) { - (*itr)->ToCreature()->GetMotionMaster()->Clear(); - (*itr)->ToCreature()->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); + creature->GetMotionMaster()->Clear(); + creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); } // TODO: Resume path when reached jump location diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp index dd0d52fb641..2787d72ddde 100644 --- a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp +++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp @@ -105,7 +105,7 @@ public: if (BerserkerChargeTimer <= diff) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_BERSERKER_CHARGE); BerserkerChargeTimer = 25000; } else BerserkerChargeTimer -= diff; -- cgit v1.2.3 From b50cda4a1a97679271193b67df951f437e829458 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 01:18:06 +0100 Subject: Core/Loot: Cleanup in LootMgr. * Removed a lot of loot template copying * Improved grouped loot selection when using loot modes * Removed code doing nothing --- src/server/game/Loot/LootMgr.cpp | 387 +++++++++++++++++++-------------------- src/server/game/Loot/LootMgr.h | 14 +- 2 files changed, 203 insertions(+), 198 deletions(-) (limited to 'src') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index fa94232d5b4..d637e45b642 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -26,6 +26,7 @@ #include "SpellInfo.h" #include "Group.h" #include "Player.h" +#include "Containers.h" static Rates const qualityToRate[MAX_ITEM_QUALITY] = { @@ -51,10 +52,26 @@ LootStore LootTemplates_Reference("reference_loot_template", "reference LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true); LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false); +struct NotMatchingLootMode : public std::unary_function +{ + explicit NotMatchingLootMode(uint16 lootMode) : _lootMode(lootMode) { } + + bool operator()(LootStoreItem* item) const + { + return !(item->lootmode & _lootMode); + } + +private: + uint16 _lootMode; +}; + class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed) { public: - void AddEntry(LootStoreItem& item); // Adds an entry to the group (at loading stage) + LootGroup() { } + ~LootGroup(); + + void AddEntry(LootStoreItem* item); // Adds an entry to the group (at loading stage) bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry bool HasQuestDropForPlayer(Player const* player) const; // The same for active quests of the player @@ -72,7 +89,11 @@ class LootTemplate::LootGroup // A set of loot def LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance - LootStoreItem const* Roll() const; // Rolls an item from the group, returns NULL if all miss their chances + LootStoreItem const* Roll(uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances + + // This class must never be copied - storing pointers + LootGroup(LootGroup const&); + LootGroup& operator=(LootGroup const&); }; //Remove all data and free all memory @@ -126,10 +147,13 @@ uint32 LootStore::LoadLootTable() continue; // error already printed to log/console. } - LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, lootmode, group, mincountOrRef, maxcount); + LootStoreItem* storeitem = new LootStoreItem(item, chanceOrQuestChance, lootmode, group, mincountOrRef, maxcount); - if (!storeitem.IsValid(*this, entry)) // Validity checks + if (!storeitem->IsValid(*this, entry)) // Validity checks + { + delete storeitem; continue; + } // Looking for the template of the entry // often entries are put together @@ -139,7 +163,7 @@ uint32 LootStore::LoadLootTable() tab = m_LootTemplates.find(entry); if (tab == m_LootTemplates.end()) { - std::pair< LootTemplateMap::iterator, bool > pr = m_LootTemplates.insert(LootTemplateMap::value_type(entry, new LootTemplate)); + std::pair< LootTemplateMap::iterator, bool > pr = m_LootTemplates.insert(LootTemplateMap::value_type(entry, new LootTemplate())); tab = pr.first; } } @@ -182,7 +206,7 @@ void LootStore::ResetConditions() for (LootTemplateMap::iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr) { ConditionList empty; - (*itr).second->CopyConditions(empty); + itr->second->CopyConditions(empty); } } @@ -1024,34 +1048,56 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) // --------- LootTemplate::LootGroup --------- // +LootTemplate::LootGroup::~LootGroup() +{ + while (!ExplicitlyChanced.empty()) + { + delete ExplicitlyChanced.back(); + ExplicitlyChanced.pop_back(); + } + + while (!EqualChanced.empty()) + { + delete EqualChanced.back(); + EqualChanced.pop_back(); + } +} + // Adds an entry to the group (at loading stage) -void LootTemplate::LootGroup::AddEntry(LootStoreItem& item) +void LootTemplate::LootGroup::AddEntry(LootStoreItem* item) { - if (item.chance != 0) + if (item->chance != 0) ExplicitlyChanced.push_back(item); else EqualChanced.push_back(item); } // Rolls an item from the group, returns NULL if all miss their chances -LootStoreItem const* LootTemplate::LootGroup::Roll() const +LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode) const { - if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked + LootStoreItemList possibleLoot = ExplicitlyChanced; + possibleLoot.remove_if(NotMatchingLootMode(lootMode)); + + if (!possibleLoot.empty()) // First explicitly chanced entries are checked { - float Roll = (float)rand_chance(); + float roll = (float)rand_chance(); - for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i) // check each explicitly chanced entry in the template and modify its chance based on quality. + for (LootStoreItemList::const_iterator itr = possibleLoot.begin(); itr != possibleLoot.end(); ++itr) // check each explicitly chanced entry in the template and modify its chance based on quality. { - if (ExplicitlyChanced[i].chance >= 100.0f) - return &ExplicitlyChanced[i]; + LootStoreItem* item = *itr; + if (item->chance >= 100.0f) + return item; - Roll -= ExplicitlyChanced[i].chance; - if (Roll < 0) - return &ExplicitlyChanced[i]; + roll -= item->chance; + if (roll < 0) + return item; } } - if (!EqualChanced.empty()) // If nothing selected yet - an item is taken from equal-chanced part - return &EqualChanced[irand(0, EqualChanced.size()-1)]; + + possibleLoot = EqualChanced; + possibleLoot.remove_if(NotMatchingLootMode(lootMode)); + if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part + return Trinity::Containers::SelectRandomContainerElement(possibleLoot); return NULL; // Empty drop from the group } @@ -1059,12 +1105,14 @@ LootStoreItem const* LootTemplate::LootGroup::Roll() const // True if group includes at least 1 quest drop entry bool LootTemplate::LootGroup::HasQuestDrop() const { - for (LootStoreItemList::const_iterator i=ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) - if (i->needs_quest) + for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) + if ((*i)->needs_quest) return true; - for (LootStoreItemList::const_iterator i=EqualChanced.begin(); i != EqualChanced.end(); ++i) - if (i->needs_quest) + + for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i) + if ((*i)->needs_quest) return true; + return false; } @@ -1072,111 +1120,30 @@ bool LootTemplate::LootGroup::HasQuestDrop() const bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const* player) const { for (LootStoreItemList::const_iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) - if (player->HasQuestForItem(i->itemid)) + if (player->HasQuestForItem((*i)->itemid)) return true; + for (LootStoreItemList::const_iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i) - if (player->HasQuestForItem(i->itemid)) + if (player->HasQuestForItem((*i)->itemid)) return true; + return false; } void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/) { for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) - { - i->conditions.clear(); - } + (*i)->conditions.clear(); + for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i) - { - i->conditions.clear(); - } + (*i)->conditions.clear(); } // Rolls an item from the group (if any takes its chance) and adds the item to the loot void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const { - // build up list of possible drops - LootStoreItemList EqualPossibleDrops = EqualChanced; - LootStoreItemList ExplicitPossibleDrops = ExplicitlyChanced; - - uint8 uiAttemptCount = 0; - const uint8 uiMaxAttempts = ExplicitlyChanced.size() + EqualChanced.size(); - - while (!ExplicitPossibleDrops.empty() || !EqualPossibleDrops.empty()) - { - if (uiAttemptCount == uiMaxAttempts) // already tried rolling too many times, just abort - return; - - LootStoreItem* item = NULL; - - // begin rolling (normally called via Roll()) - LootStoreItemList::iterator itr; - uint8 itemSource = 0; - if (!ExplicitPossibleDrops.empty()) // First explicitly chanced entries are checked - { - itemSource = 1; - float Roll = (float)rand_chance(); - // check each explicitly chanced entry in the template and modify its chance based on quality - for (itr = ExplicitPossibleDrops.begin(); itr != ExplicitPossibleDrops.end(); itr = ExplicitPossibleDrops.erase(itr)) - { - if (itr->chance >= 100.0f) - { - item = &*itr; - break; - } - - Roll -= itr->chance; - if (Roll < 0) - { - item = &*itr; - break; - } - } - } - if (item == NULL && !EqualPossibleDrops.empty()) // If nothing selected yet - an item is taken from equal-chanced part - { - itemSource = 2; - itr = EqualPossibleDrops.begin(); - std::advance(itr, irand(0, EqualPossibleDrops.size()-1)); - item = &*itr; - } - // finish rolling - - ++uiAttemptCount; - - if (item != NULL && item->lootmode & lootMode) // only add this item if roll succeeds and the mode matches - { - bool duplicate = false; - if (ItemTemplate const* _proto = sObjectMgr->GetItemTemplate(item->itemid)) - { - uint8 _item_counter = 0; - for (LootItemList::const_iterator _item = loot.items.begin(); _item != loot.items.end(); ++_item) - if (_item->itemid == item->itemid) // search through the items that have already dropped - { - ++_item_counter; - if (_proto->InventoryType == 0 && _item_counter == 3) // Non-equippable items are limited to 3 drops - duplicate = true; - else if (_proto->InventoryType != 0 && _item_counter == 1) // Equippable item are limited to 1 drop - duplicate = true; - } - } - if (duplicate) // if item->itemid is a duplicate, remove it - switch (itemSource) - { - case 1: // item came from ExplicitPossibleDrops - ExplicitPossibleDrops.erase(itr); - break; - case 2: // item came from EqualPossibleDrops - EqualPossibleDrops.erase(itr); - break; - } - else // otherwise, add the item and exit the function - { - loot.AddItem(*item); - return; - } - } - } + if (LootStoreItem const* item = Roll(lootMode)) + loot.AddItem(*item); } // Overall chance for the group without equal chanced items @@ -1185,8 +1152,8 @@ float LootTemplate::LootGroup::RawTotalChance() const float result = 0; for (LootStoreItemList::const_iterator i=ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) - if (!i->needs_quest) - result += i->chance; + if (!(*i)->needs_quest) + result += (*i)->chance; return result; } @@ -1214,25 +1181,27 @@ void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, LootIdSet* ref_set) const { - for (LootStoreItemList::const_iterator ieItr=ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr) + for (LootStoreItemList::const_iterator ieItr = ExplicitlyChanced.begin(); ieItr != ExplicitlyChanced.end(); ++ieItr) { - if (ieItr->mincountOrRef < 0) + LootStoreItem* item = *ieItr; + if (item->mincountOrRef < 0) { - if (!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); else if (ref_set) - ref_set->erase(-ieItr->mincountOrRef); + ref_set->erase(-item->mincountOrRef); } } - for (LootStoreItemList::const_iterator ieItr=EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr) + for (LootStoreItemList::const_iterator ieItr = EqualChanced.begin(); ieItr != EqualChanced.end(); ++ieItr) { - if (ieItr->mincountOrRef < 0) + LootStoreItem* item = *ieItr; + if (item->mincountOrRef < 0) { - if (!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); else if (ref_set) - ref_set->erase(-ieItr->mincountOrRef); + ref_set->erase(-item->mincountOrRef); } } } @@ -1241,14 +1210,30 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo // --------- LootTemplate --------- // +LootTemplate::~LootTemplate() +{ + while (!Entries.empty()) + { + delete Entries.back(); + Entries.pop_back(); + } + + for (size_t i = 0; i < Groups.size(); ++i) + delete Groups[i]; + Groups.clear(); +} + // Adds an entry to the group (at loading stage) -void LootTemplate::AddEntry(LootStoreItem& item) +void LootTemplate::AddEntry(LootStoreItem* item) { - if (item.group > 0 && item.mincountOrRef > 0) // Group + if (item->group > 0 && item->mincountOrRef > 0) // Group { - if (item.group >= Groups.size()) - Groups.resize(item.group); // Adds new group the the loot template if needed - Groups[item.group-1].AddEntry(item); // Adds new entry to the group + if (item->group >= Groups.size()) + Groups.resize(item->group, NULL); // Adds new group the the loot template if needed + if (!Groups[item->group - 1]) + Groups[item->group - 1] = new LootGroup(); + + Groups[item->group-1]->AddEntry(item); // Adds new entry to the group } else // Non-grouped entries and references are stored together Entries.push_back(item); @@ -1257,10 +1242,11 @@ void LootTemplate::AddEntry(LootStoreItem& item) void LootTemplate::CopyConditions(ConditionList conditions) { for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i) - i->conditions.clear(); + (*i)->conditions.clear(); for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i) - i->CopyConditions(conditions); + if (LootGroup* group = *i) + group->CopyConditions(conditions); } void LootTemplate::CopyConditions(LootItem* li) const @@ -1268,10 +1254,11 @@ void LootTemplate::CopyConditions(LootItem* li) const // Copies the conditions list from a template item to a LootItem for (LootStoreItemList::const_iterator _iter = Entries.begin(); _iter != Entries.end(); ++_iter) { - if (_iter->itemid != li->itemid) + LootStoreItem* item = *_iter; + if (item->itemid != li->itemid) continue; - li->conditions = _iter->conditions; + li->conditions = item->conditions; break; } } @@ -1284,54 +1271,42 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId if (groupId > Groups.size()) return; // Error message already printed at loading stage - Groups[groupId-1].Process(loot, lootMode); + if (!Groups[groupId - 1]) + return; + + Groups[groupId-1]->Process(loot, lootMode); return; } // Rolling non-grouped items for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { - if (i->lootmode &~ lootMode) // Do not add if mode mismatch + LootStoreItem* item = *i; + if (item->lootmode &~ lootMode) // Do not add if mode mismatch continue; if (!i->Roll(rate)) - continue; // Bad luck for the entry + continue; // Bad luck for the entry - if (ItemTemplate const* _proto = sObjectMgr->GetItemTemplate(i->itemid)) + if (item->mincountOrRef < 0) // References processing { - uint8 _item_counter = 0; - LootItemList::const_iterator _item = loot.items.begin(); - for (; _item != loot.items.end(); ++_item) - if (_item->itemid == i->itemid) // search through the items that have already dropped - { - ++_item_counter; - if (_proto->InventoryType == 0 && _item_counter == 3) // Non-equippable items are limited to 3 drops - continue; - else if (_proto->InventoryType != 0 && _item_counter == 1) // Equippable item are limited to 1 drop - continue; - } - if (_item != loot.items.end()) - continue; - } - - if (i->mincountOrRef < 0) // References processing - { - LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-i->mincountOrRef); + LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-item->mincountOrRef); if (!Referenced) - continue; // Error message already printed at loading stage + continue; // Error message already printed at loading stage - uint32 maxcount = uint32(float(i->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT)); - for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator - Referenced->Process(loot, rate, lootMode, i->group); + uint32 maxcount = uint32(float(item->maxcount) * sWorld->getRate(RATE_DROP_ITEM_REFERENCED_AMOUNT)); + for (uint32 loop = 0; loop < maxcount; ++loop) // Ref multiplicator + Referenced->Process(loot, rate, lootMode, item->group); } - else // Plain entries (not a reference, not grouped) - loot.AddItem(*i); // Chance is already checked, just add + else // Plain entries (not a reference, not grouped) + loot.AddItem(*item); // Chance is already checked, just add } // Now processing groups for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i) - i->Process(loot, lootMode); + if (LootGroup* group = *i) + group->Process(loot, lootMode); } // True if template includes at least 1 quest drop entry @@ -1341,27 +1316,33 @@ bool LootTemplate::HasQuestDrop(LootTemplateMap const& store, uint8 groupId) con { if (groupId > Groups.size()) return false; // Error message [should be] already printed at loading stage - return Groups[groupId-1].HasQuestDrop(); + + if (!Groups[groupId - 1]) + return false; + + return Groups[groupId-1]->HasQuestDrop(); } for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { - if (i->mincountOrRef < 0) // References + LootStoreItem* item = *i; + if (item->mincountOrRef < 0) // References { - LootTemplateMap::const_iterator Referenced = store.find(-i->mincountOrRef); + LootTemplateMap::const_iterator Referenced = store.find(-item->mincountOrRef); if (Referenced == store.end()) continue; // Error message [should be] already printed at loading stage - if (Referenced->second->HasQuestDrop(store, i->group)) + if (Referenced->second->HasQuestDrop(store, item->group)) return true; } - else if (i->needs_quest) + else if (item->needs_quest) return true; // quest drop found } // Now processing groups for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i) - if (i->HasQuestDrop()) - return true; + if (LootGroup* group = *i) + if (group->HasQuestDrop()) + return true; return false; } @@ -1373,28 +1354,34 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co { if (groupId > Groups.size()) return false; // Error message already printed at loading stage - return Groups[groupId-1].HasQuestDropForPlayer(player); + + if (!Groups[groupId - 1]) + return false; + + return Groups[groupId-1]->HasQuestDropForPlayer(player); } // Checking non-grouped entries for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { - if (i->mincountOrRef < 0) // References processing + LootStoreItem* item = *i; + if (item->mincountOrRef < 0) // References processing { - LootTemplateMap::const_iterator Referenced = store.find(-i->mincountOrRef); + LootTemplateMap::const_iterator Referenced = store.find(-item->mincountOrRef); if (Referenced == store.end()) continue; // Error message already printed at loading stage - if (Referenced->second->HasQuestDropForPlayer(store, player, i->group)) + if (Referenced->second->HasQuestDropForPlayer(store, player, item->group)) return true; } - else if (player->HasQuestForItem(i->itemid)) + else if (player->HasQuestForItem(item->itemid)) return true; // active quest drop found } // Now checking groups for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i) - if (i->HasQuestDropForPlayer(player)) - return true; + if (LootGroup* group = *i) + if (group->HasQuestDropForPlayer(player)) + return true; return false; } @@ -1403,8 +1390,9 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co void LootTemplate::Verify(LootStore const& lootstore, uint32 id) const { // Checking group chances - for (uint32 i=0; i < Groups.size(); ++i) - Groups[i].Verify(lootstore, id, i+1); + for (uint32 i = 0; i < Groups.size(); ++i) + if (Groups[i]) + Groups[i]->Verify(lootstore, id, i + 1); // TODO: References validity checks } @@ -1413,18 +1401,21 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se { for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr) { - if (ieItr->mincountOrRef < 0) + LootStoreItem* item = *ieItr; + if (item->mincountOrRef < 0) { - if (!LootTemplates_Reference.GetLootFor(-ieItr->mincountOrRef)) - LootTemplates_Reference.ReportNotExistedId(-ieItr->mincountOrRef); + if (!LootTemplates_Reference.GetLootFor(-item->mincountOrRef)) + LootTemplates_Reference.ReportNotExistedId(-item->mincountOrRef); else if (ref_set) - ref_set->erase(-ieItr->mincountOrRef); + ref_set->erase(-item->mincountOrRef); } } for (LootGroups::const_iterator grItr = Groups.begin(); grItr != Groups.end(); ++grItr) - grItr->CheckLootRefs(store, ref_set); + if (LootGroup* group = *grItr) + group->CheckLootRefs(store, ref_set); } + bool LootTemplate::addConditionItem(Condition* cond) { if (!cond || !cond->isLoaded())//should never happen, checked at loading @@ -1432,41 +1423,48 @@ bool LootTemplate::addConditionItem(Condition* cond) sLog->outError(LOG_FILTER_LOOT, "LootTemplate::addConditionItem: condition is null"); return false; } + if (!Entries.empty()) { for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i) { - if (i->itemid == uint32(cond->SourceEntry)) + if ((*i)->itemid == uint32(cond->SourceEntry)) { - i->conditions.push_back(cond); + (*i)->conditions.push_back(cond); return true; } } } + if (!Groups.empty()) { for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr) { - LootStoreItemList* itemList = (*groupItr).GetExplicitlyChancedItemList(); + LootGroup* group = *groupItr; + if (!group) + continue; + + LootStoreItemList* itemList = group->GetExplicitlyChancedItemList(); if (!itemList->empty()) { for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i) { - if ((*i).itemid == uint32(cond->SourceEntry)) + if ((*i)->itemid == uint32(cond->SourceEntry)) { - (*i).conditions.push_back(cond); + (*i)->conditions.push_back(cond); return true; } } } - itemList = (*groupItr).GetEqualChancedItemList(); + + itemList = group->GetEqualChancedItemList(); if (!itemList->empty()) { for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i) { - if ((*i).itemid == uint32(cond->SourceEntry)) + if ((*i)->itemid == uint32(cond->SourceEntry)) { - (*i).conditions.push_back(cond); + (*i)->conditions.push_back(cond); return true; } } @@ -1479,10 +1477,9 @@ bool LootTemplate::addConditionItem(Condition* cond) bool LootTemplate::isReference(uint32 id) { for (LootStoreItemList::const_iterator ieItr = Entries.begin(); ieItr != Entries.end(); ++ieItr) - { - if (ieItr->itemid == id && ieItr->mincountOrRef < 0) + if ((*ieItr)->itemid == id && (*ieItr)->mincountOrRef < 0) return true; - } + return false;//not found or not reference } diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 759064385a5..df2717ee36e 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -27,6 +27,7 @@ #include #include +#include enum RollType { @@ -174,7 +175,7 @@ class LootTemplate; typedef std::vector QuestItemList; typedef std::vector LootItemList; typedef std::map QuestItemMap; -typedef std::vector LootStoreItemList; +typedef std::list LootStoreItemList; typedef UNORDERED_MAP LootTemplateMap; typedef std::set LootIdSet; @@ -218,11 +219,14 @@ class LootStore class LootTemplate { class LootGroup; // A set of loot definitions for items (refs are not allowed inside) - typedef std::vector LootGroups; + typedef std::vector LootGroups; public: + LootTemplate() { } + ~LootTemplate(); + // Adds an entry to the group (at loading stage) - void AddEntry(LootStoreItem& item); + void AddEntry(LootStoreItem* item); // Rolls for every item in the template and adds the rolled items the the loot void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0) const; void CopyConditions(ConditionList conditions); @@ -242,6 +246,10 @@ class LootTemplate private: LootStoreItemList Entries; // not grouped only LootGroups Groups; // groups have own (optimised) processing, grouped entries go there + + // Objects of this class must never be copied, we are storing pointers in container + LootTemplate(LootTemplate const&); + LootTemplate& operator=(LootTemplate const&); }; //===================================================== -- cgit v1.2.3 From 104682767ebae9a162db9b14cf5f64a78a4fe568 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 01:28:18 +0100 Subject: Build fix --- src/server/game/Loot/LootMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index d637e45b642..59696a47fe0 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1285,7 +1285,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId if (item->lootmode &~ lootMode) // Do not add if mode mismatch continue; - if (!i->Roll(rate)) + if (!item->Roll(rate)) continue; // Bad luck for the entry if (item->mincountOrRef < 0) // References processing -- cgit v1.2.3 From 1cdfc659591fc556852e95a1cfea4d94a0c13d62 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Sun, 3 Feb 2013 01:32:14 +0100 Subject: Script: Fix warning for craping script -.- --- src/server/scripts/Outland/BlackTemple/boss_illidan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index fff44baa7bf..a91d25fa984 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -422,7 +422,7 @@ public: Glaive->InterruptNonMeleeSpells(true); DoCast(me, SPELL_FLAME_ENRAGE, true); DoResetThreat(); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + if (SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->AddThreat(me->getVictim(), 5000000.0f); AttackStart(me->getVictim()); -- cgit v1.2.3 From 68610a60ea268b2ee7b3f5c949ff513ec30ab4d3 Mon Sep 17 00:00:00 2001 From: Manuel Carrasco Date: Sun, 3 Feb 2013 03:01:47 -0200 Subject: Core/AI: Removed needless code --- src/server/game/AI/CoreAI/UnitAI.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 09ba2cc19b1..0d2f623fd9e 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -103,8 +103,7 @@ void UnitAI::DoAddAuraToAllHostilePlayers(uint32 spellid) if (unit->GetTypeId() == TYPEID_PLAYER) me->AddAura(spellid, unit); } - }else - return; + } } void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered) @@ -118,8 +117,7 @@ void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered) if (unit->GetTypeId() == TYPEID_PLAYER) me->CastSpell(unit, spellid, triggered); } - }else - return; + } } void UnitAI::DoCast(uint32 spellId) -- cgit v1.2.3 From 2df1908c2933c88f1442dbde52658b3c5499a849 Mon Sep 17 00:00:00 2001 From: m7nu3l Date: Sun, 3 Feb 2013 02:25:58 -0300 Subject: Core/AI: Inherited AggressorAI, so the wheel is not reinvented. --- src/server/game/AI/CoreAI/ReactorAI.cpp | 29 +++-------------------------- src/server/game/AI/CoreAI/ReactorAI.h | 9 ++++----- 2 files changed, 7 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp index 31b9a82c534..fef465d592c 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.cpp +++ b/src/server/game/AI/CoreAI/ReactorAI.cpp @@ -23,35 +23,12 @@ #include "ObjectAccessor.h" #include "CreatureAIImpl.h" -#define REACTOR_VISIBLE_RANGE (26.46f) +// #define REACTOR_VISIBLE_RANGE (26.46f) - It has not any use at all -int -ReactorAI::Permissible(const Creature* creature) +int ReactorAI::Permissible(const Creature* creature) { if (creature->isCivilian() || creature->IsNeutralToAll()) return PERMIT_BASE_REACTIVE; return PERMIT_BASE_NO; -} - -void -ReactorAI::MoveInLineOfSight(Unit*) -{ -} - -void -ReactorAI::UpdateAI(const uint32 /*time_diff*/) -{ - // update i_victimGuid if me->getVictim() !=0 and changed - if (!UpdateVictim()) - return; - - if (me->isAttackReady()) - { - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } -} +} \ No newline at end of file diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index 39af09c4a9d..6f4d704f755 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -19,19 +19,18 @@ #ifndef TRINITY_REACTORAI_H #define TRINITY_REACTORAI_H -#include "CreatureAI.h" +#include "CombatAI.h" class Unit; -class ReactorAI : public CreatureAI +class ReactorAI : public AggressorAI { public: - explicit ReactorAI(Creature* c) : CreatureAI(c) {} + explicit ReactorAI(Creature* c) : AggressorAI(c) {} - void MoveInLineOfSight(Unit*); + void MoveInLineOfSight(Unit*) {}; - void UpdateAI(const uint32); static int Permissible(const Creature*); }; #endif -- cgit v1.2.3 From a8054311ca4419354b4a55ad2d9626e4f202d697 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 10:49:31 +0100 Subject: Core/AI: Reverted 2df1908c2933c88f1442dbde52658b3c5499a849 - sometimes it is better to copy some code to make its purpose clearer (ReactorAI is an AI class used for neutral creatures, it makes no sense to inherit AggresorAI, which is used for aggressive creatures) --- src/server/game/AI/CoreAI/ReactorAI.cpp | 12 +++++++++--- src/server/game/AI/CoreAI/ReactorAI.h | 7 ++++--- src/server/game/AI/CoreAI/UnitAI.cpp | 5 ++++- 3 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp index fef465d592c..b9c235176bc 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.cpp +++ b/src/server/game/AI/CoreAI/ReactorAI.cpp @@ -23,12 +23,18 @@ #include "ObjectAccessor.h" #include "CreatureAIImpl.h" -// #define REACTOR_VISIBLE_RANGE (26.46f) - It has not any use at all - int ReactorAI::Permissible(const Creature* creature) { if (creature->isCivilian() || creature->IsNeutralToAll()) return PERMIT_BASE_REACTIVE; return PERMIT_BASE_NO; -} \ No newline at end of file +} + +void ReactorAI::UpdateAI(uint32 const /*diff*/) +{ + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); +} diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index 6f4d704f755..e6db46bf38e 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -19,17 +19,18 @@ #ifndef TRINITY_REACTORAI_H #define TRINITY_REACTORAI_H -#include "CombatAI.h" +#include "CreatureAI.h" class Unit; -class ReactorAI : public AggressorAI +class ReactorAI : public CreatureAI { public: explicit ReactorAI(Creature* c) : AggressorAI(c) {} - void MoveInLineOfSight(Unit*) {}; + void MoveInLineOfSight(Unit*) {} + void UpdateAI(uint32 const diff); static int Permissible(const Creature*); }; diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 0d2f623fd9e..7f0d387c2f1 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -238,7 +238,10 @@ void UnitAI::FillAISpellInfo() } //Enable PlayerAI when charmed -void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } +void PlayerAI::OnCharmed(bool apply) +{ + me->IsAIEnabled = apply; +} void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) { -- cgit v1.2.3 From a216ef2ca00b2aa4049114f68f1d9cefb547a059 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 11:05:42 +0100 Subject: And a build fix. Nothing new... move along --- src/server/game/AI/CoreAI/ReactorAI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index e6db46bf38e..f7de3b99565 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -27,7 +27,7 @@ class ReactorAI : public CreatureAI { public: - explicit ReactorAI(Creature* c) : AggressorAI(c) {} + explicit ReactorAI(Creature* c) : CreatureAI(c) {} void MoveInLineOfSight(Unit*) {} void UpdateAI(uint32 const diff); -- cgit v1.2.3 From 653557d335abf1a703ac518ee5df41f104adff63 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 12:16:10 +0100 Subject: Core/Objects: Some optimizations to object updatemask building --- src/server/game/Entities/Object/Object.cpp | 74 +++++++++-------------- src/server/game/Entities/Object/Object.h | 4 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 +-- 3 files changed, 29 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f20d452dc96..70b2618ef6c 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -777,64 +777,56 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); } -void Object::GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const +uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const { - // This function assumes updatefield index is always valid + uint32 visibleFlag = UF_FLAG_PUBLIC; + + if (target == this) + visibleFlag |= UF_FLAG_PRIVATE; + switch (GetTypeId()) { case TYPEID_ITEM: case TYPEID_CONTAINER: flags = ItemUpdateFieldFlags; - isOwner = isItemOwner = ((Item*)this)->GetOwnerGUID() == target->GetGUID(); + if (((Item*)this)->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER; break; case TYPEID_UNIT: case TYPEID_PLAYER: { Player* plr = ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself(); flags = UnitUpdateFieldFlags; - isOwner = ToUnit()->GetOwnerGUID() == target->GetGUID(); - hasSpecialInfo = ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()); - isPartyMember = plr && plr->IsInSameGroupWith(target); + if (ToUnit()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; + + if (ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID())) + visibleFlag |= UF_FLAG_SPECIAL_INFO; + + if (plr && plr->IsInSameGroupWith(target)) + visibleFlag |= UF_FLAG_PARTY_MEMBER; break; } case TYPEID_GAMEOBJECT: flags = GameObjectUpdateFieldFlags; - isOwner = ToGameObject()->GetOwnerGUID() == target->GetGUID(); + if (ToGameObject()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_DYNAMICOBJECT: flags = DynamicObjectUpdateFieldFlags; - isOwner = ((DynamicObject*)this)->GetCasterGUID() == target->GetGUID(); + if (((DynamicObject*)this)->GetCasterGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_CORPSE: flags = CorpseUpdateFieldFlags; - isOwner = ToCorpse()->GetOwnerGUID() == target->GetGUID(); + if (ToCorpse()->GetOwnerGUID() == target->GetGUID()) + visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_OBJECT: break; } -} -bool Object::IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const -{ - if (flags == UF_FLAG_NONE) - return false; - - if (flags & UF_FLAG_PUBLIC) - return true; - - if (flags & UF_FLAG_PRIVATE && isSelf) - return true; - - if (flags & UF_FLAG_OWNER && isOwner) - return true; - - if (flags & UF_FLAG_ITEM_OWNER && isItemOwner) - return true; - - if (flags & UF_FLAG_PARTY_MEMBER && isPartyMember) - return true; - - return false; + return visibleFlag; } void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count) @@ -857,16 +849,10 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const { uint32* flags = NULL; - bool isSelf = target == this; - bool isOwner = false; - bool isItemOwner = false; - bool hasSpecialInfo = false; - bool isPartyMember = false; - - GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); + uint32 visibleFlag = GetUpdateFieldData(target, flags); for (uint16 index = 0; index < m_valuesCount; ++index) - if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (_changesMask.GetBit(index) && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) + if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (_changesMask.GetBit(index) && (flags[index] & visibleFlag))) updateMask->SetBit(index); } @@ -874,16 +860,10 @@ void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const { uint32* value = m_uint32Values; uint32* flags = NULL; - bool isSelf = target == this; - bool isOwner = false; - bool isItemOwner = false; - bool hasSpecialInfo = false; - bool isPartyMember = false; - - GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); + uint32 visibleFlag = GetUpdateFieldData(target, flags); for (uint16 index = 0; index < m_valuesCount; ++index, ++value) - if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*value && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) + if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (*value && (flags[index] & visibleFlag))) updateMask->SetBit(index); } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 641f9afb154..ae3d545b7d7 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -326,9 +326,7 @@ class Object std::string _ConcatFields(uint16 startIndex, uint16 size) const; void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count); - void GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const; - - bool IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const; + uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; void _SetUpdateBits(UpdateMask* updateMask, Player* target) const; void _SetCreateBits(UpdateMask* updateMask, Player* target) const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 52e8523a72a..d6b19e6010a 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5061,10 +5061,6 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bo return; Unit* target = aurApp->GetTarget(); - - if (target->GetTypeId() != TYPEID_UNIT) - return; - if (!apply) { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit @@ -5072,8 +5068,7 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bo return; } - CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(target->GetEntry()); - if (ci && ci->type == CREATURE_TYPE_BEAST) + if (target->GetCreatureType() == CREATURE_TYPE_BEAST) target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply); } -- cgit v1.2.3 From 07442f932ce956d0ef90e543a91b1127532d2cdc Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 12:23:28 +0100 Subject: Core/Object: Fixed a mistake in update mask building - fields marked with UF_FLAG_PARTY_MEMBER should be sent to the entire raid, not only one subgroup --- src/server/game/Entities/Object/Object.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 70b2618ef6c..8f89e58ad5a 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -800,10 +800,11 @@ uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const if (ToUnit()->GetOwnerGUID() == target->GetGUID()) visibleFlag |= UF_FLAG_OWNER; - if (ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID())) - visibleFlag |= UF_FLAG_SPECIAL_INFO; + if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO)) + if (ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID())) + visibleFlag |= UF_FLAG_SPECIAL_INFO; - if (plr && plr->IsInSameGroupWith(target)) + if (plr && plr->IsInSameRaidWith(target)) visibleFlag |= UF_FLAG_PARTY_MEMBER; break; } -- cgit v1.2.3 From 54924f18af20434174a2610a19f0b1946a5b0ac1 Mon Sep 17 00:00:00 2001 From: Gacko Date: Sat, 2 Feb 2013 15:58:37 +0100 Subject: Core/EventMap: Internal changes and doxygen doc See http://www.trinitycore.org/f/topic/7003-doxygen-documentation-and-hacks for details and examples. Thanks to @Shauren for several hints. --- src/server/game/AI/CreatureAIImpl.h | 333 +++++++++++++++++++++++++----------- 1 file changed, 231 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index bf5ab9703e0..03402ce415f 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -313,110 +313,177 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c class EventMap { - typedef std::map StorageType; + /** + * Internal storage type. + * Key: Time as uint32 when the event should occur. + * Value: The event data as uint32. + * + * Structure of event data: + * - Bit 0 - 15: Event Id. + * - Bit 16 - 23: Group + * - Bit 24 - 31: Phase + * - Pattern: 0xPPGGEEEE + */ + typedef std::multimap EventStore; public: EventMap() : _time(0), _phase(0) {} - // Returns current timer value, does not represent real dates/times - uint32 GetTimer() const { return _time; } - - // Removes all events and clears phase + /** + * @name Reset + * @brief Removes all scheduled events and resets time and phase. + */ void Reset() { - _eventMap.clear(); _time = 0; _phase = 0; + _eventMap.clear(); + _time = 0; + _phase = 0; } - void Update(uint32 time) { _time += time; } + /** + * @name Update + * @brief Updates the timer of the event map. + * @param time Value to be added to time. + */ + void Update(uint32 time) + { + _time += time; + } - uint32 GetPhaseMask() const { return (_phase >> 24) & 0xFF; } + /** + * @name GetTimer + * @return Current timer value. + */ + uint32 GetTimer() const + { + return _time; + } - bool Empty() const { return _eventMap.empty(); } + /** + * @name GetPhaseMask + * @return Active phases as mask. + */ + uint8 GetPhaseMask() const + { + return _phase; + } - // Sets event phase, must be in range 1 - 8 - void SetPhase(uint32 phase) + /** + * @name Empty + * @return True, if there are no events scheduled. + */ + bool Empty() const { - if (phase && phase <= 8) - _phase = (1 << (phase + 23)); - else if (!phase) + return _eventMap.empty(); + } + + /** + * @name SetPhase + * @brief Sets the phase of the map (absolute). + * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase. + */ + void SetPhase(uint8 phase) + { + if (!phase) _phase = 0; + else if (phase <= 8) + _phase = (1 << (phase - 1)); } - // Activates event phase, must be in range 1 - 8 - void AddPhase(uint32 phase) + /** + * @name AddPhase + * @brief Activates the given phase (bitwise). + * @param phase Phase which should be activated. Values: 1 - 8 + */ + void AddPhase(uint8 phase) { if (phase && phase <= 8) - _phase |= (1 << (phase + 23)); + _phase |= (1 << (phase - 1)); } - // Deactivates event phase, must be in range 1 - 8 - void RemovePhase(uint32 phase) + /** + * @name RemovePhase + * @brief Deactivates the given phase (bitwise). + * @param phase Phase which should be deactivated. Values: 1 - 8. + */ + void RemovePhase(uint8 phase) { if (phase && phase <= 8) - _phase &= ~(1 << (phase + 23)); + _phase &= ~(1 << (phase - 1)); } - // Creates new event entry in map with given id, time, group if given (1 - 8) and phase if given (1 - 8) - // 0 for group/phase means it belongs to no group or runs in all phases - void ScheduleEvent(uint32 eventId, uint32 time, uint32 groupId = 0, uint32 phase = 0) + /** + * @name ScheduleEvent + * @brief Creates new event entry in map. + * @param eventId The id of the new event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) { - time += _time; - if (groupId && groupId < 9) - eventId |= (1 << (groupId + 15)); - if (phase && phase < 8) + if (group && group <= 8) + eventId |= (1 << (group + 15)); + + if (phase && phase <= 8) eventId |= (1 << (phase + 23)); - StorageType::const_iterator itr = _eventMap.find(time); - while (itr != _eventMap.end()) - { - ++time; - itr = _eventMap.find(time); - } - _eventMap.insert(StorageType::value_type(time, eventId)); + _eventMap.insert(EventStore::value_type(_time + time, eventId)); } - // Removes event with specified id and creates new entry for it - void RescheduleEvent(uint32 eventId, uint32 time, uint32 groupId = 0, uint32 phase = 0) + /** + * @name RescheduleEvent + * @brief Cancels the given event and reschedules it. + * @param eventId The id of the event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) { CancelEvent(eventId); - ScheduleEvent(eventId, time, groupId, phase); + ScheduleEvent(eventId, time, group, phase); } - // Reschedules closest event + /** + * @name RepeatEvent + * @brief Cancels the closest event and reschedules it. + * @param time Time until the event occurs. + */ void RepeatEvent(uint32 time) { - if (_eventMap.empty()) + if (Empty()) return; - + uint32 eventId = _eventMap.begin()->second; _eventMap.erase(_eventMap.begin()); - time += _time; - StorageType::const_iterator itr = _eventMap.find(time); - while (itr != _eventMap.end()) - { - ++time; - itr = _eventMap.find(time); - } - - _eventMap.insert(StorageType::value_type(time, eventId)); + ScheduleEvent(eventId, time); } - // Removes first event + /** + * @name PopEvent + * @brief Remove the first event in the map. + */ void PopEvent() { - if (!_eventMap.empty()) + if (!Empty()) _eventMap.erase(_eventMap.begin()); } - // Gets next event id to execute and removes it from map + /** + * @name ExecuteEvent + * @brief Returns the next event to execute and removes it from map. + * @return Id of the event to execute. + */ uint32 ExecuteEvent() { - while (!_eventMap.empty()) + while (!Empty()) { - StorageType::iterator itr = _eventMap.begin(); + EventStore::iterator itr = _eventMap.begin(); + if (itr->first > _time) return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & _phase)) + else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) _eventMap.erase(itr); else { @@ -425,114 +492,176 @@ class EventMap return eventId; } } + return 0; } - // Gets next event id to execute + /** + * @name GetEvent + * @brief Returns the next event to execute. + * @return Id of the event to execute. + */ uint32 GetEvent() { - while (!_eventMap.empty()) + while (!Empty()) { - StorageType::iterator itr = _eventMap.begin(); + EventStore::iterator itr = _eventMap.begin(); + if (itr->first > _time) return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & _phase)) + else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) _eventMap.erase(itr); else return (itr->second & 0x0000FFFF); } - + return 0; } - // Delay all events + /** + * @name DelayEvents + * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. + * @param delay Amount of delay. + */ void DelayEvents(uint32 delay) { - if (delay < _time) - _time -= delay; - else - _time = 0; + _time = delay < _time ? _time - delay : 0; } - // Delay all events having the specified Group - void DelayEvents(uint32 delay, uint32 groupId) + /** + * @name DelayEvents + * @brief Delay all events of the same group. + * @param delay Amount of delay. + * @param group Group of the events. + */ + void DelayEvents(uint32 delay, uint32 group) { - if (!groupId || groupId > 8) + if (!group || group > 8 || Empty()) return; + + EventStore delayed; - uint32 nextTime = _time + delay; - uint32 groupMask = (1 << (groupId + 15)); - - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end() && itr->first < nextTime;) + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { - if (itr->second & groupMask) + if (itr->second & (1 << (group + 15))) { - ScheduleEvent(itr->second, itr->first - _time + delay); - _eventMap.erase(itr); - itr = _eventMap.begin(); + delayed.insert(EventStore::value_type(itr->first + delay, itr->second)); + _eventMap.erase(itr++); } else ++itr; } + + _eventMap.insert(delayed.begin(), delayed.end()); } - // Cancel events with specified id + /** + * @name CancelEvent + * @brief Cancels all events of the specified id. + * @param eventId Event id to cancel. + */ void CancelEvent(uint32 eventId) { - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + if (Empty()) + return; + + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { if (eventId == (itr->second & 0x0000FFFF)) - { - _eventMap.erase(itr); - itr = _eventMap.begin(); - } + _eventMap.erase(itr++); else ++itr; } } - // Cancel events belonging to specified group - void CancelEventGroup(uint32 groupId) + /** + * @name CancelEventGroup + * @brief Cancel events belonging to specified group. + * @param group Group to cancel. + */ + void CancelEventGroup(uint32 group) { - if (!groupId || groupId > 8) + if (!group || group > 8 || Empty()) return; - uint32 groupMask = (1 << (groupId + 15)); - - for (StorageType::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) { - if (itr->second & groupMask) - { - _eventMap.erase(itr); - itr = _eventMap.begin(); - } + if (itr->second & (1 << (group + 15))) + _eventMap.erase(itr++); else ++itr; } } - // Returns time of next event to execute - // To get how much time remains substract _time + /** + * @name GetNextEventTime + * @brief Returns closest occurence of specified event. + * @param eventId Wanted event id. + * @return Time of found event. + */ uint32 GetNextEventTime(uint32 eventId) const { - for (StorageType::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (Empty()) + return 0; + + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) if (eventId == (itr->second & 0x0000FFFF)) return itr->first; return 0; } + + /** + * @name GetNextEventTime + * @return Time of next event. + */ + uint32 GetNextEventTime() const + { + return Empty() ? 0 : _eventMap.begin()->first; + } - // Returns wether the eventmap is in the given phase or not. - bool IsInPhase(uint32 phase) + /** + * @name IsInPhase + * @brief Returns wether event map is in specified phase or not. + * @param phase Wanted phase. + * @return True, if phase of event map contains specified phase. + */ + bool IsInPhase(uint8 phase) { - return phase <= 8 && (!phase || _phase & (1 << (phase + 23))); + return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); } private: + /** + * @name _time + * @brief Internal timer. + * + * This does not represent the real date/time value. + * It's more like a stop watch: It can run, it can be stopped, + * it can be resetted and so on. Events occur when this timer + * has reached their time value. It's value is changed in the + * Update method. + */ uint32 _time; - uint32 _phase; - - StorageType _eventMap; + + /** + * @name _phase + * @brief Phase mask of the event map. + * + * Contains the phases the event map is in. Multiple + * phases from 1 to 8 can be set with SetPhase or + * AddPhase. RemovePhase deactives a phase. + */ + uint8 _phase; + + /** + * @name _eventMap + * @brief Internal event storage map. Contains the scheduled events. + * + * See typedef at the beginning of the class for more + * details. + */ + EventStore _eventMap; }; enum AITarget -- cgit v1.2.3 From 6d29a62b78d347a9ccaaa39fa61d3ed9af54d2ca Mon Sep 17 00:00:00 2001 From: Regigicas Date: Sun, 3 Feb 2013 14:08:29 +0100 Subject: Update WheatyExceptionReport to print Windows 8 --- src/server/shared/Debugging/WheatyExceptionReport.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index 96a115f8057..2f30ddfcd70 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -202,7 +202,9 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) if (osvi.wProductType == VER_NT_WORKSTATION) #endif // WINVER < 0x0500 { - if (osvi.dwMinorVersion == 1) + if (osvi.dwMinorVersion == 2) + _tcsncat(szVersion, _T("Windows 8 "), cntMax); + else if (osvi.dwMinorVersion == 1) _tcsncat(szVersion, _T("Windows 7 "), cntMax); else _tcsncat(szVersion, _T("Windows Vista "), cntMax); -- cgit v1.2.3 From b346459ca88a4959c579e51607ef0b5eb8d75b98 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 14:11:59 +0100 Subject: Core: Warning fixes --- src/server/collision/Models/GameObjectModel.cpp | 3 +++ src/server/game/Movement/Spline/MovementPacketBuilder.cpp | 2 +- src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp | 2 +- src/tools/mmaps_generator/MapBuilder.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 54283389387..e166a860cd2 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -48,7 +48,10 @@ ModelList model_list; void LoadGameObjectModelList() { +#ifndef NO_CORE_FUNCS uint32 oldMSTime = getMSTime(); +#endif + FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 801219b2a5a..29d1bb50a8f 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -146,7 +146,7 @@ namespace Movement //data.append(&mov.m_float_values[SpeedWalk], SpeedMaxCount); //if (mov.SplineEnabled()) { - MoveSplineFlag splineFlags = move_spline.splineflags; + MoveSplineFlag const& splineFlags = move_spline.splineflags; data << splineFlags.raw(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index aa65cfda97e..1d340e61b61 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -298,7 +298,7 @@ class boss_lord_marrowgar : public CreatureScript case DATA_SPIKE_IMMUNE + 1: case DATA_SPIKE_IMMUNE + 2: { - int32 index = type - DATA_SPIKE_IMMUNE; + uint32 index = uint32(type - DATA_SPIKE_IMMUNE); if (index < _boneSpikeImmune.size()) return _boneSpikeImmune[index]; diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 4a016f267b4..cd85d926125 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -957,7 +957,7 @@ namespace MMAP if (count != 1) return false; - if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != DT_NAVMESH_VERSION) + if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != uint32(DT_NAVMESH_VERSION)) return false; if (header.mmapVersion != MMAP_VERSION) -- cgit v1.2.3 From fe1aa11e08c2f395a0f3b42763165439e11f5c76 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 15:04:12 +0100 Subject: Core/Debugging: Made WheatyExceptionReport::_GetWindowsVersion code more readable and added check for Windows Server 2012 --- .../shared/Debugging/WheatyExceptionReport.cpp | 183 +++++++++------------ 1 file changed, 76 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index 2f30ddfcd70..ea9ab096dcd 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -193,14 +193,19 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) { // Windows NT product family. case VER_PLATFORM_WIN32_NT: + { + #if WINVER < 0x0500 + BYTE suiteMask = osvi.wReserved[0]; + BYTE productType = osvi.wReserved[1]; + #else + WORD suiteMask = osvi.wSuiteMask; + BYTE productType = osvi.wProductType; + #endif // WINVER < 0x0500 + // Test for the specific product family. if (osvi.dwMajorVersion == 6) { - #if WINVER < 0x0500 - if (osvi.wReserved[1] == VER_NT_WORKSTATION) - #else - if (osvi.wProductType == VER_NT_WORKSTATION) - #endif // WINVER < 0x0500 + if (productType == VER_NT_WORKSTATION) { if (osvi.dwMinorVersion == 2) _tcsncat(szVersion, _T("Windows 8 "), cntMax); @@ -209,140 +214,104 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) else _tcsncat(szVersion, _T("Windows Vista "), cntMax); } + else if (osvi.dwMinorVersion == 2) + _tcsncat(szVersion, _T("Windows Server 2012 "), cntMax); else if (osvi.dwMinorVersion == 1) _tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax); else _tcsncat(szVersion, _T("Windows Server 2008 "), cntMax); } - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) _tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax); - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) _tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax); - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) _tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax); - if (osvi.dwMajorVersion <= 4) + else if (osvi.dwMajorVersion <= 4) _tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax); // Test for specific product on Windows NT 4.0 SP6 and later. if (bOsVersionInfoEx) { // Test for the workstation type. - #if WINVER < 0x0500 - if (osvi.wReserved[1] == VER_NT_WORKSTATION) - #else - if (osvi.wProductType == VER_NT_WORKSTATION) - #endif // WINVER < 0x0500 - { - if (osvi.dwMajorVersion == 4) - _tcsncat(szVersion, _T("Workstation 4.0 "), cntMax); - #if WINVER < 0x0500 - else if (osvi.wReserved[0] & VER_SUITE_PERSONAL) - #else - else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) - #endif // WINVER < 0x0500 + if (productType == VER_NT_WORKSTATION) + { + if (osvi.dwMajorVersion == 4) + _tcsncat(szVersion, _T("Workstation 4.0 "), cntMax); + else if (suiteMask & VER_SUITE_PERSONAL) _tcsncat(szVersion, _T("Home Edition "), cntMax); - #if WINVER < 0x0500 - else if (osvi.wReserved[0] & VER_SUITE_EMBEDDEDNT) - #else - else if (osvi.wSuiteMask & VER_SUITE_EMBEDDEDNT) - #endif // WINVER < 0x0500 + else if (suiteMask & VER_SUITE_EMBEDDEDNT) _tcsncat(szVersion, _T("Embedded "), cntMax); - else - _tcsncat(szVersion, _T("Professional "), cntMax); - } - // Test for the server type. - #if WINVER < 0x0500 - else if (osvi.wReserved[1] == VER_NT_SERVER) - #else - else if (osvi.wProductType == VER_NT_SERVER) - #endif // WINVER < 0x0500 - { - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + else + _tcsncat(szVersion, _T("Professional "), cntMax); + } + // Test for the server type. + else if (productType == VER_NT_SERVER) { - #if WINVER < 0x0500 - if (osvi.wReserved[0] & VER_SUITE_DATACENTER) - #else - if (osvi.wSuiteMask & VER_SUITE_DATACENTER) - #endif // WINVER < 0x0500 + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + { + if (suiteMask & VER_SUITE_DATACENTER) _tcsncat(szVersion, _T("Datacenter Edition "), cntMax); - #if WINVER < 0x0500 - else if (osvi.wReserved[0] & VER_SUITE_ENTERPRISE) - #else - else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - #endif // WINVER < 0x0500 + else if (suiteMask & VER_SUITE_ENTERPRISE) _tcsncat(szVersion, _T("Enterprise Edition "), cntMax); - #if WINVER < 0x0500 - else if (osvi.wReserved[0] == VER_SUITE_BLADE) - #else - else if (osvi.wSuiteMask == VER_SUITE_BLADE) - #endif // WINVER < 0x0500 + else if (suiteMask == VER_SUITE_BLADE) _tcsncat(szVersion, _T("Web Edition "), cntMax); - else - _tcsncat(szVersion, _T("Standard Edition "), cntMax); - } - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - { - #if WINVER < 0x0500 - if (osvi.wReserved[0] & VER_SUITE_DATACENTER) - #else - if (osvi.wSuiteMask & VER_SUITE_DATACENTER) - #endif // WINVER < 0x0500 + else + _tcsncat(szVersion, _T("Standard Edition "), cntMax); + } + else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + { + if (suiteMask & VER_SUITE_DATACENTER) _tcsncat(szVersion, _T("Datacenter Server "), cntMax); - #if WINVER < 0x0500 - else if (osvi.wReserved[0] & VER_SUITE_ENTERPRISE) - #else - else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - #endif // WINVER < 0x0500 + else if (suiteMask & VER_SUITE_ENTERPRISE) _tcsncat(szVersion, _T("Advanced Server "), cntMax); - else - _tcsncat(szVersion, _T("Server "), cntMax); - } - else // Windows NT 4.0 - { - #if WINVER < 0x0500 - if (osvi.wReserved[0] & VER_SUITE_ENTERPRISE) - #else - if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - #endif // WINVER < 0x0500 + else + _tcsncat(szVersion, _T("Server "), cntMax); + } + else // Windows NT 4.0 + { + if (suiteMask & VER_SUITE_ENTERPRISE) _tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax); - else - _tcsncat(szVersion, _T("Server 4.0 "), cntMax); + else + _tcsncat(szVersion, _T("Server 4.0 "), cntMax); + } } } - } - // Display service pack (if any) and build number. - if (osvi.dwMajorVersion == 4 && _tcsicmp(osvi.szCSDVersion, _T("Service Pack 6")) == 0) - { - HKEY hKey; - LONG lRet; - // Test for SP6 versus SP6a. - lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey); - if (lRet == ERROR_SUCCESS) + // Display service pack (if any) and build number. + if (osvi.dwMajorVersion == 4 && _tcsicmp(osvi.szCSDVersion, _T("Service Pack 6")) == 0) { - _stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"), - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); + HKEY hKey; + LONG lRet; + + // Test for SP6 versus SP6a. + lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey); + if (lRet == ERROR_SUCCESS) + { + _stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"), + osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); + _tcsncat(szVersion, wszTmp, cntMax); + } + else // Windows NT 4.0 prior to SP6a + { + _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), + osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); + _tcsncat(szVersion, wszTmp, cntMax); + } + ::RegCloseKey(hKey); } - else // Windows NT 4.0 prior to SP6a + else // Windows NT 3.51 and earlier or Windows 2000 and later { - _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), - osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); + if (!_tcslen(osvi.szCSDVersion)) + _stprintf(wszTmp, _T("(Version %d.%d, Build %d)"), + osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); + else + _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), + osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); _tcsncat(szVersion, wszTmp, cntMax); } - ::RegCloseKey(hKey); - } - else // Windows NT 3.51 and earlier or Windows 2000 and later - { - if (!_tcslen(osvi.szCSDVersion)) - _stprintf(wszTmp, _T("(Version %d.%d, Build %d)"), - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - else - _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), - osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); + break; } - break; default: _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); -- cgit v1.2.3 From 193a0d5f153c593e421bf2f7e36a536acceaf36b Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 3 Feb 2013 15:21:36 +0100 Subject: Fix engrish in doc --- src/server/game/AI/CreatureAIImpl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 03402ce415f..7121a031ec2 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -637,9 +637,9 @@ class EventMap * @brief Internal timer. * * This does not represent the real date/time value. - * It's more like a stop watch: It can run, it can be stopped, + * It's more like a stopwatch: It can run, it can be stopped, * it can be resetted and so on. Events occur when this timer - * has reached their time value. It's value is changed in the + * has reached their time value. Its value is changed in the * Update method. */ uint32 _time; -- cgit v1.2.3 From ccc19366601afe6afad528308530e0811e7aa80d Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 3 Feb 2013 15:36:29 +0100 Subject: Core/Loot: Items in generated loot will now be split in multiple stacks if their count exceeds max stack size defined in item_template --- src/server/game/Loot/LootMgr.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 59696a47fe0..128cf358557 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -351,7 +351,6 @@ LootItem::LootItem(LootStoreItem const& li) needs_quest = li.needs_quest; - count = urand(li.mincountOrRef, li.maxcount); // constructor called for mincountOrRef > 0 only randomSuffix = GenerateEnchSuffixFactor(itemid); randomPropertyId = Item::GenerateItemRandomPropertyId(itemid); is_looted = 0; @@ -400,26 +399,30 @@ void LootItem::AddAllowedLooter(const Player* player) // // Inserts the item into the loot (called by LootTemplate processors) -void Loot::AddItem(LootStoreItem const & item) +void Loot::AddItem(LootStoreItem const& item) { - if (item.needs_quest) // Quest drop - { - if (quest_items.size() < MAX_NR_QUEST_ITEMS) - quest_items.push_back(LootItem(item)); - } - else if (items.size() < MAX_NR_LOOT_ITEMS) // Non-quest drop + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); + if (!proto) + return; + + uint32 count = urand(item.mincountOrRef, item.maxcount); + uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0); + + std::vector& lootItems = item.needs_quest ? quest_items : items; + uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS; + + for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i) { - items.push_back(LootItem(item)); + LootItem generatedLoot(item); + generatedLoot.count = std::min(count, proto->GetMaxStackSize()); + lootItems.push_back(generatedLoot); + count -= proto->GetMaxStackSize(); // non-conditional one-player only items are counted here, // free for all items are counted in FillFFALoot(), // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() - if (item.conditions.empty()) - { - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); - if (!proto || (proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0) - ++unlootedCount; - } + if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT)) + ++unlootedCount; } } -- cgit v1.2.3 From cfaabe50cf229040b9f6c7d379a1879579c18bb9 Mon Sep 17 00:00:00 2001 From: Krogonos Date: Sun, 3 Feb 2013 09:12:03 -0600 Subject: Fixed a few file names to improve searching. Signed-off-by: Krogonos --- src/server/scripts/Kalimdor/CMakeLists.txt | 6 +- .../CullingOfStratholme/boss_chrono_lord_epoch.cpp | 153 +++++++++++++++++++ .../CullingOfStratholme/boss_epoch.cpp | 153 ------------------- .../CullingOfStratholme/boss_infinite.cpp | 89 ----------- .../boss_infinite_corruptor.cpp | 89 +++++++++++ .../CullingOfStratholme/boss_salramm.cpp | 163 --------------------- .../boss_salramm_the_fleshcrafter.cpp | 163 +++++++++++++++++++++ 7 files changed, 408 insertions(+), 408 deletions(-) create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp (limited to 'src') diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index 5c44cd7ef27..536824e7a63 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -38,11 +38,11 @@ set(scripts_STAT_SRCS Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp + Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp + Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp - Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp + Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp new file mode 100644 index 00000000000..fad5736e18f --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +/* Script Data Start +SDName: Boss epoch +SDAuthor: Tartalo +SD%Complete: 80 +SDComment: TODO: Intro, consecutive attacks to a random target durin time wrap, adjust timers +SDCategory: +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CURSE_OF_EXERTION = 52772, + SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec. + SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec. + SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank + H_SPELL_WOUNDING_STRIKE = 58830 +}; + +enum Yells +{ + SAY_INTRO = 0, + SAY_AGGRO = 1, + SAY_TIME_WARP = 2, + SAY_SLAY = 3, + SAY_DEATH = 4 +}; + +class boss_epoch : public CreatureScript +{ +public: + boss_epoch() : CreatureScript("boss_epoch") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_epochAI (creature); + } + + struct boss_epochAI : public ScriptedAI + { + boss_epochAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + uint8 uiStep; + + uint32 uiStepTimer; + uint32 uiWoundingStrikeTimer; + uint32 uiTimeWarpTimer; + uint32 uiTimeStopTimer; + uint32 uiCurseOfExertionTimer; + + InstanceScript* instance; + + void Reset() + { + uiStep = 1; + uiStepTimer = 26000; + uiCurseOfExertionTimer = 9300; + uiTimeWarpTimer = 25300; + uiTimeStopTimer = 21300; + uiWoundingStrikeTimer = 5300; + + if (instance) + instance->SetData(DATA_EPOCH_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + Talk(SAY_AGGRO); + + if (instance) + instance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if (uiCurseOfExertionTimer < diff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_CURSE_OF_EXERTION); + uiCurseOfExertionTimer = 9300; + } else uiCurseOfExertionTimer -= diff; + + if (uiWoundingStrikeTimer < diff) + { + DoCastVictim(SPELL_WOUNDING_STRIKE); + uiWoundingStrikeTimer = 5300; + } else uiWoundingStrikeTimer -= diff; + + if (uiTimeStopTimer < diff) + { + DoCastAOE(SPELL_TIME_STOP); + uiTimeStopTimer = 21300; + } else uiTimeStopTimer -= diff; + + if (uiTimeWarpTimer < diff) + { + Talk(SAY_TIME_WARP); + DoCastAOE(SPELL_TIME_WARP); + uiTimeWarpTimer = 25300; + } else uiTimeWarpTimer -= diff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + + if (instance) + instance->SetData(DATA_EPOCH_EVENT, DONE); + } + + void KilledUnit(Unit* victim) + { + if (victim == me) + return; + + Talk(SAY_SLAY); + } + }; + +}; + +void AddSC_boss_epoch() +{ + new boss_epoch(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp deleted file mode 100644 index fad5736e18f..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * - * 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, see . - */ - -/* Script Data Start -SDName: Boss epoch -SDAuthor: Tartalo -SD%Complete: 80 -SDComment: TODO: Intro, consecutive attacks to a random target durin time wrap, adjust timers -SDCategory: -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CURSE_OF_EXERTION = 52772, - SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec. - SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec. - SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank - H_SPELL_WOUNDING_STRIKE = 58830 -}; - -enum Yells -{ - SAY_INTRO = 0, - SAY_AGGRO = 1, - SAY_TIME_WARP = 2, - SAY_SLAY = 3, - SAY_DEATH = 4 -}; - -class boss_epoch : public CreatureScript -{ -public: - boss_epoch() : CreatureScript("boss_epoch") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_epochAI (creature); - } - - struct boss_epochAI : public ScriptedAI - { - boss_epochAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - uint8 uiStep; - - uint32 uiStepTimer; - uint32 uiWoundingStrikeTimer; - uint32 uiTimeWarpTimer; - uint32 uiTimeStopTimer; - uint32 uiCurseOfExertionTimer; - - InstanceScript* instance; - - void Reset() - { - uiStep = 1; - uiStepTimer = 26000; - uiCurseOfExertionTimer = 9300; - uiTimeWarpTimer = 25300; - uiTimeStopTimer = 21300; - uiWoundingStrikeTimer = 5300; - - if (instance) - instance->SetData(DATA_EPOCH_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_AGGRO); - - if (instance) - instance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiCurseOfExertionTimer < diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_CURSE_OF_EXERTION); - uiCurseOfExertionTimer = 9300; - } else uiCurseOfExertionTimer -= diff; - - if (uiWoundingStrikeTimer < diff) - { - DoCastVictim(SPELL_WOUNDING_STRIKE); - uiWoundingStrikeTimer = 5300; - } else uiWoundingStrikeTimer -= diff; - - if (uiTimeStopTimer < diff) - { - DoCastAOE(SPELL_TIME_STOP); - uiTimeStopTimer = 21300; - } else uiTimeStopTimer -= diff; - - if (uiTimeWarpTimer < diff) - { - Talk(SAY_TIME_WARP); - DoCastAOE(SPELL_TIME_WARP); - uiTimeWarpTimer = 25300; - } else uiTimeWarpTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_EPOCH_EVENT, DONE); - } - - void KilledUnit(Unit* victim) - { - if (victim == me) - return; - - Talk(SAY_SLAY); - } - }; - -}; - -void AddSC_boss_epoch() -{ - new boss_epoch(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp deleted file mode 100644 index 8c2861db299..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * - * 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CORRUPTING_BLIGHT = 60588, - SPELL_VOID_STRIKE = 60590 -}; - -enum Yells -{ - SAY_AGGRO = 0, - SAY_DEATH = 1, - SAY_FAIL = 2 -}; - -class boss_infinite_corruptor : public CreatureScript -{ -public: - boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_infinite_corruptorAI(creature); - } - - struct boss_infinite_corruptorAI : public ScriptedAI - { - boss_infinite_corruptorAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - void Reset() - { - if (instance) - instance->SetData(DATA_INFINITE_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_AGGRO); - if (instance) - instance->SetData(DATA_INFINITE_EVENT, IN_PROGRESS); - } - - void UpdateAI(uint32 const /*diff*/) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - if (instance) - instance->SetData(DATA_INFINITE_EVENT, DONE); - } - }; - -}; - -void AddSC_boss_infinite_corruptor() -{ - new boss_infinite_corruptor(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp new file mode 100644 index 00000000000..8c2861db299 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CORRUPTING_BLIGHT = 60588, + SPELL_VOID_STRIKE = 60590 +}; + +enum Yells +{ + SAY_AGGRO = 0, + SAY_DEATH = 1, + SAY_FAIL = 2 +}; + +class boss_infinite_corruptor : public CreatureScript +{ +public: + boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_infinite_corruptorAI(creature); + } + + struct boss_infinite_corruptorAI : public ScriptedAI + { + boss_infinite_corruptorAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + InstanceScript* instance; + + void Reset() + { + if (instance) + instance->SetData(DATA_INFINITE_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + Talk(SAY_AGGRO); + if (instance) + instance->SetData(DATA_INFINITE_EVENT, IN_PROGRESS); + } + + void UpdateAI(uint32 const /*diff*/) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + if (instance) + instance->SetData(DATA_INFINITE_EVENT, DONE); + } + }; + +}; + +void AddSC_boss_infinite_corruptor() +{ + new boss_infinite_corruptor(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp deleted file mode 100644 index d7d9beaedd4..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * - * 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, see . - */ - -/* Script Data Start -SDName: Boss salramm -SDAuthor: Tartalo -SD%Complete: 80 -SDComment: TODO: Intro -SDCategory: -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CURSE_OF_TWISTED_FLESH = 58845, - SPELL_EXPLODE_GHOUL = 52480, - H_SPELL_EXPLODE_GHOUL = 58825, - SPELL_SHADOW_BOLT = 57725, - H_SPELL_SHADOW_BOLT = 58828, - SPELL_STEAL_FLESH = 52708, - SPELL_SUMMON_GHOULS = 52451 -}; - -enum Yells -{ - SAY_AGGRO = 0, - SAY_SPAWN = 1, - SAY_SLAY = 2, - SAY_DEATH = 3, - SAY_EXPLODE_GHOUL = 4, - SAY_STEAL_FLESH = 5, - SAY_SUMMON_GHOULS = 6 -}; - -class boss_salramm : public CreatureScript -{ -public: - boss_salramm() : CreatureScript("boss_salramm") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_salrammAI (creature); - } - - struct boss_salrammAI : public ScriptedAI - { - boss_salrammAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - if (instance) - Talk(SAY_SPAWN); - } - - uint32 uiCurseFleshTimer; - uint32 uiExplodeGhoulTimer; - uint32 uiShadowBoltTimer; - uint32 uiStealFleshTimer; - uint32 uiSummonGhoulsTimer; - - InstanceScript* instance; - - void Reset() - { - uiCurseFleshTimer = 30000; //30s DBM - uiExplodeGhoulTimer = urand(25000, 28000); //approx 6 sec after summon ghouls - uiShadowBoltTimer = urand(8000, 12000); // approx 10s - uiStealFleshTimer = 12345; - uiSummonGhoulsTimer = urand(19000, 24000); //on a video approx 24s after aggro - - if (instance) - instance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_AGGRO); - - if (instance) - instance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Curse of twisted flesh timer - if (uiCurseFleshTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CURSE_OF_TWISTED_FLESH); - uiCurseFleshTimer = 37000; - } else uiCurseFleshTimer -= diff; - - //Shadow bolt timer - if (uiShadowBoltTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_BOLT); - uiShadowBoltTimer = urand(8000, 12000); - } else uiShadowBoltTimer -= diff; - - //Steal Flesh timer - if (uiStealFleshTimer <= diff) - { - Talk(SAY_STEAL_FLESH); - if (Unit* random_pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(random_pTarget, SPELL_STEAL_FLESH); - uiStealFleshTimer = 10000; - } else uiStealFleshTimer -= diff; - - //Summon ghouls timer - if (uiSummonGhoulsTimer <= diff) - { - Talk(SAY_SUMMON_GHOULS); - if (Unit* random_pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(random_pTarget, SPELL_SUMMON_GHOULS); - uiSummonGhoulsTimer = 10000; - } else uiSummonGhoulsTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_SALRAMM_EVENT, DONE); - } - - void KilledUnit(Unit* victim) - { - if (victim == me) - return; - - Talk(SAY_SLAY); - } - }; - -}; - -void AddSC_boss_salramm() -{ - new boss_salramm(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp new file mode 100644 index 00000000000..d7d9beaedd4 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +/* Script Data Start +SDName: Boss salramm +SDAuthor: Tartalo +SD%Complete: 80 +SDComment: TODO: Intro +SDCategory: +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CURSE_OF_TWISTED_FLESH = 58845, + SPELL_EXPLODE_GHOUL = 52480, + H_SPELL_EXPLODE_GHOUL = 58825, + SPELL_SHADOW_BOLT = 57725, + H_SPELL_SHADOW_BOLT = 58828, + SPELL_STEAL_FLESH = 52708, + SPELL_SUMMON_GHOULS = 52451 +}; + +enum Yells +{ + SAY_AGGRO = 0, + SAY_SPAWN = 1, + SAY_SLAY = 2, + SAY_DEATH = 3, + SAY_EXPLODE_GHOUL = 4, + SAY_STEAL_FLESH = 5, + SAY_SUMMON_GHOULS = 6 +}; + +class boss_salramm : public CreatureScript +{ +public: + boss_salramm() : CreatureScript("boss_salramm") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_salrammAI (creature); + } + + struct boss_salrammAI : public ScriptedAI + { + boss_salrammAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + if (instance) + Talk(SAY_SPAWN); + } + + uint32 uiCurseFleshTimer; + uint32 uiExplodeGhoulTimer; + uint32 uiShadowBoltTimer; + uint32 uiStealFleshTimer; + uint32 uiSummonGhoulsTimer; + + InstanceScript* instance; + + void Reset() + { + uiCurseFleshTimer = 30000; //30s DBM + uiExplodeGhoulTimer = urand(25000, 28000); //approx 6 sec after summon ghouls + uiShadowBoltTimer = urand(8000, 12000); // approx 10s + uiStealFleshTimer = 12345; + uiSummonGhoulsTimer = urand(19000, 24000); //on a video approx 24s after aggro + + if (instance) + instance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + Talk(SAY_AGGRO); + + if (instance) + instance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Curse of twisted flesh timer + if (uiCurseFleshTimer <= diff) + { + DoCast(me->getVictim(), SPELL_CURSE_OF_TWISTED_FLESH); + uiCurseFleshTimer = 37000; + } else uiCurseFleshTimer -= diff; + + //Shadow bolt timer + if (uiShadowBoltTimer <= diff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHADOW_BOLT); + uiShadowBoltTimer = urand(8000, 12000); + } else uiShadowBoltTimer -= diff; + + //Steal Flesh timer + if (uiStealFleshTimer <= diff) + { + Talk(SAY_STEAL_FLESH); + if (Unit* random_pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(random_pTarget, SPELL_STEAL_FLESH); + uiStealFleshTimer = 10000; + } else uiStealFleshTimer -= diff; + + //Summon ghouls timer + if (uiSummonGhoulsTimer <= diff) + { + Talk(SAY_SUMMON_GHOULS); + if (Unit* random_pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(random_pTarget, SPELL_SUMMON_GHOULS); + uiSummonGhoulsTimer = 10000; + } else uiSummonGhoulsTimer -= diff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + + if (instance) + instance->SetData(DATA_SALRAMM_EVENT, DONE); + } + + void KilledUnit(Unit* victim) + { + if (victim == me) + return; + + Talk(SAY_SLAY); + } + }; + +}; + +void AddSC_boss_salramm() +{ + new boss_salramm(); +} -- cgit v1.2.3 From 124b5ed6e7f9be9ffe6453e1defef3df5d409d8c Mon Sep 17 00:00:00 2001 From: m7nu3l Date: Sun, 3 Feb 2013 14:46:17 -0300 Subject: Core/AI: Implemented functionality for _isCombatMovementAllowed in ScriptedAI, only when AttackStart is called. --- src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 8 ++++++++ src/server/game/AI/ScriptedAI/ScriptedCreature.h | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 9709cb0ecc2..090c73f456f 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -108,6 +108,14 @@ void ScriptedAI::AttackStartNoMove(Unit* who) DoStartNoMovement(who); } +void ScriptedAI::AttackStart(Unit* who) +{ + if (IsCombatMovementAllowed()) + CreatureAI::AttackStart(who); + else + AttackStartNoMove(who); +} + void ScriptedAI::UpdateAI(uint32 const /*diff*/) { //Check if we have a current target diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 50363f20ed5..15068557aca 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -136,6 +136,9 @@ struct ScriptedAI : public CreatureAI //Called at creature aggro either by MoveInLOS or Attack Start void EnterCombat(Unit* /*victim*/) {} + // Called before EnterCombat even before the creature is in combat. + void AttackStart(Unit* /*target*/); + // ************* //AI Helper Functions // ************* @@ -191,7 +194,11 @@ struct ScriptedAI : public CreatureAI void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE); - //Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims + // Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims + // NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart + // You should make the necessary to make it happen so. + // Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset(). + // It will keep the last value you set. void SetCombatMovement(bool allowMovement); bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; } -- cgit v1.2.3 From ffb4c63fe303111c1694e89dcb19419226974fcd Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Mon, 4 Feb 2013 05:22:09 +0200 Subject: DB/Misc: Add full script for Pilfering Perfume (A:24656 H:24541) Closes #5205 --- sql/updates/world/2013_02_04_02_world_misc.sql | 119 +++++++++++++++++++++++++ src/server/scripts/Spells/spell_generic.cpp | 58 ++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 sql/updates/world/2013_02_04_02_world_misc.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_04_02_world_misc.sql b/sql/updates/world/2013_02_04_02_world_misc.sql new file mode 100644 index 00000000000..300d0e31bcb --- /dev/null +++ b/sql/updates/world/2013_02_04_02_world_misc.sql @@ -0,0 +1,119 @@ +-- Pilfering Perfume (A:24656 H:24541) + +SET @QUEST_A := 24656; +SET @QUEST_H := 24541; + +SET @SNIP := 38066; -- Inspector Snip Snagglebolt +SET @SNAP := 37172; -- Detective Snap Snagglebolt +SET @MENUID := 10976; + +SET @TRIGGER_SW_OUT := 5703; -- outside +SET @TRIGGER_SW_IN := 5704; -- inside +SET @TRIGGER_ORG_OUT := 5705; -- outside +SET @TRIGGER_ORG_IN := 5706; -- inside + +SET @SPELL_UNIFORM := 71450; -- Crown Parcel Service Uniform +SET @SPELL_CONTRABAND := 71459; -- Crown Chemical Co. Contraband + +SET @SPELL_CREDIT_A := 71522; -- Crown Chemical Co. Supplies +SET @SPELL_CREDIT_H := 71539; -- Crown Chemical Co. Supplies + +SET @GUID := 48571; -- set by TDB,need 3 (48571,48572,48573) +SET @EVENT := 8; -- Love is in the Air +SET @NPC_GUARD := 37671; -- Crown Supply Guard + +-- missing npcs on horde side +DELETE FROM `creature` WHERE `id`=@NPC_GUARD; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@GUID+0,@NPC_GUARD,1,1,1,0,0,1391.2,-4486.23,31.4544,3.3355,300,0,0,42,0,0,0,0,0), +(@GUID+1,@NPC_GUARD,1,1,1,0,0,1392.66,-4481.87,31.3782,1.97284,300,0,0,42,0,0,0,0,0), +(@GUID+2,@NPC_GUARD,1,1,1,0,0,1393.92,-4489.57,31.4737,4.93701,300,0,0,42,0,0,0,0,0); + +DELETE FROM `game_event_creature` WHERE `eventEntry`=@EVENT AND `guid` BETWEEN @GUID+0 AND @GUID+2; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(@EVENT,@GUID+0), +(@EVENT,@GUID+1), +(@EVENT,@GUID+2); + +-- removing a wrong spawn +DELETE FROM `creature` WHERE `guid`=40507; +DELETE FROM `game_event_creature` WHERE `guid`=40507; + +-- deleting wrong previous spawns and reusing some guids to spawn proper ones +DELETE FROM `gameobject` WHERE `guid` IN (24416,24417,24418,24419,24420,24421,24422,24423,24433,24434,24435,24436,24437,24438,24439,24440,24441); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(24416,181015,1,1,1,1392.938,-4485.202,31.41421,0,0,0,0,1,120,255,1), +(24417,201778,1,1,1,1393.677,-4486.033,32.67227,0,0,0,0,1,120,255,1), +(24418,201752,1,1,1,1394.184,-4484.108,31.24833,4.32842,0,0,0,1,120,255,1), +(24419,201778,1,1,1,1394.26,-4484.368,32.50796,5.148723,0,0,0,1,120,255,1), +(24420,201752,1,1,1,1393.319,-4486.797,31.42903,4.101525,0,0,0,1,120,255,1), +(24421,201752,1,1,1,1394.401,-4485.688,31.35416,5.916668,0,0,0,1,120,255,1), +(24422,201752,1,1,1,1394.042,-4488.397,31.4775,4.32842,0,0,0,1,120,255,1), +(24423,201752,1,1,1,1396.476,-4482.715,32.14788,4.32842,0,0,0,1,120,255,1), +(24433,181015,1,1,1,1395.002,-4487.113,31.37537,3.874631,0,0,0,1,120,255,1), +(24434,181015,1,1,1,1396.632,-4482.505,30.87226,5.166176,0,0,0,1,120,255,1), +(24435,201752,1,1,1,1395.813,-4486.439,32.56021,1.710422,0,0,0,1,120,255,1), +(24436,201752,1,1,1,1396.595,-4486.056,31.15484,4.32842,0,0,0,1,120,255,1), +(24437,201752,1,1,1,1397.377,-4488.021,33.71862,0.157079,0,0,0,1,120,255,1), +(24438,181015,1,1,1,1397.51,-4487.901,32.46279,3.68265,0,0,0,1,120,255,1), +(24439,201752,1,1,1,1397.571,-4487.939,31.21067,3.33359,0,0,0,1,120,255,1); +-- these guids will remain free +DELETE FROM `game_event_gameobject` WHERE `eventEntry`=@EVENT AND `guid` IN (24440,24441); + +-- Snip & Snap sai +UPDATE `creature_template` SET `npcflag`=`npcflag`|1|2,`gossip_menu_id`=@MENUID,`AIName`='SmartAI' WHERE `entry` IN (@SNIP,@SNAP); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@SNIP,@SNAP) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@SNIP,0,0,0,19,0,100,0,@QUEST_A,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On quest accept - Spellcast'), +(@SNIP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option select - Close gossip'), +(@SNIP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snip - On gossip option accept - Spellcast'), +-- +(@SNAP,0,0,0,19,0,100,0,@QUEST_H,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On quest accept - Spellcast'), +(@SNAP,0,1,2,62,0,100,0,@MENUID,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option select - Close gossip'), +(@SNAP,0,2,0,61,0,100,0,0,0,0,0,11,@SPELL_UNIFORM,0,0,0,0,0,7,0,0,0,0,0,0,0,'Snap - On gossip option accept - Spellcast'); + +DELETE FROM `areatrigger_involvedrelation` WHERE `id` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_involvedrelation` (`id`,`quest`) VALUES +(@TRIGGER_SW_OUT,@QUEST_A), +(@TRIGGER_SW_IN,@QUEST_A), +-- +(@TRIGGER_ORG_OUT,@QUEST_H), +(@TRIGGER_ORG_IN,@QUEST_H); + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES +(@TRIGGER_SW_OUT,'SmartTrigger'), +(@TRIGGER_SW_IN,'SmartTrigger'), +-- +(@TRIGGER_ORG_OUT,'SmartTrigger'), +(@TRIGGER_ORG_IN,'SmartTrigger'); + +-- usig invoker cast because normal cast doesn't want to work(LoS issue,i think) +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN) AND `source_type`=2; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@TRIGGER_SW_OUT,2,0,0,46,0,100,0,@TRIGGER_SW_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_SW_IN,2,0,0,46,0,100,0,@TRIGGER_SW_IN,0,0,0,85,@SPELL_CREDIT_A,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +-- +(@TRIGGER_ORG_OUT,2,0,0,46,0,100,0,@TRIGGER_ORG_OUT,0,0,0,85,@SPELL_CONTRABAND,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"), +(@TRIGGER_ORG_IN,2,0,0,46,0,100,0,@TRIGGER_ORG_IN,0,0,0,85,@SPELL_CREDIT_H,0,0,0,0,0,7,0,0,0,0,0,0,0,"On Trigger - Cast - Invoker"); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry` IN (@TRIGGER_SW_OUT,@TRIGGER_SW_IN,@TRIGGER_ORG_OUT,@TRIGGER_ORG_IN); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@MENUID; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(22,1,@TRIGGER_SW_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_SW_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,0,9,0,@QUEST_A,0,0,0,0,0,'','show gossip option only if player has quest taken'), +-- +(22,1,@TRIGGER_ORG_OUT,2,0,1,0,@SPELL_UNIFORM,0,0,0,0,0,'','execute sai only if player has aura'), +(22,1,@TRIGGER_ORG_IN,2,0,1,0,@SPELL_CONTRABAND,0,0,0,0,0,'','execute sai only if player has aura'), +(15,@MENUID,0,0,1,9,0,@QUEST_H,0,0,0,0,0,'','show gossip option only if player has quest taken'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (@SPELL_CREDIT_A,@SPELL_CREDIT_H,-@SPELL_UNIFORM); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(@SPELL_CREDIT_A,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(@SPELL_CREDIT_H,-@SPELL_UNIFORM,1,'Remove Crown Parcel Service Uniform on Crown Chemical Co. Supplies hit'), +(-@SPELL_UNIFORM,-@SPELL_CONTRABAND,0,'Remove Crown Chemical Co. Contraband when Crown Parcel Service Uniform is removed'); + +DELETE FROM `spell_script_names` WHERE `spell_id`=@SPELL_UNIFORM; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(@SPELL_UNIFORM,'spell_gen_aura_service_uniform'); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 05fad623114..e7befff87a3 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3518,6 +3518,63 @@ class spell_gen_replenishment : public SpellScriptLoader } }; +enum ServiceUniform +{ + SPELL_SERVICE_UNIFORM = 71450, + + MODEL_GOBLIN_MALE = 31002, + MODEL_GOBLIN_FEMALE = 31003, +}; + +class spell_gen_aura_service_uniform : public SpellScriptLoader +{ + public: + spell_gen_aura_service_uniform() : SpellScriptLoader("spell_gen_aura_service_uniform") { } + + class spell_gen_aura_service_uniform_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_aura_service_uniform_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SERVICE_UNIFORM)) + return false; + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // Apply model goblin + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (target->getGender() == GENDER_MALE) + target->SetDisplayId(MODEL_GOBLIN_MALE); + else + target->SetDisplayId(MODEL_GOBLIN_FEMALE); + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (target->GetTypeId() == TYPEID_PLAYER) + target->RestoreDisplayId(); + } + + void Register() + { + AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_aura_service_uniform_AuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3597,4 +3654,5 @@ void AddSC_generic_spell_scripts() new spell_gen_bonked(); new spell_gen_gift_of_naaru(); new spell_gen_replenishment(); + new spell_gen_aura_service_uniform(); } -- cgit v1.2.3 From f753c989f25e1f3bbb8c667ffd0028a0c0aa389d Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 04:08:51 +0100 Subject: Core/Dungeon Finder: Simplify Spell Luck of the draw code Core/Dungeon Finder: Partial recode of "group list" using existing Lfg functions --- src/server/game/DungeonFinding/LFGMgr.cpp | 26 ++++++++++++++ src/server/game/DungeonFinding/LFGMgr.h | 3 ++ src/server/game/Maps/Map.cpp | 6 +--- src/server/scripts/Commands/cs_misc.cpp | 53 ++++++++++++++--------------- src/server/scripts/Spells/spell_generic.cpp | 46 ++++++++++++------------- 5 files changed, 78 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 0f23925cc2b..4c6a8b92e0b 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -2039,3 +2039,29 @@ void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) SetGroup(guid, gguid); AddPlayerToGroup(gguid, guid); } + +bool LFGMgr::inRandomLfgDungeon(uint64 guid) +{ + if (GetState(guid) != LFG_STATE_NONE) + { + LfgDungeonSet const& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + { + LFGDungeonData const* dungeon = GetLFGDungeon(*dungeons.begin()); + if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) + return true; + } + } + + return false; +} + +bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) +{ + if (uint32 dungeonId = GetDungeon(guid, true)) + if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) + if (uint32(dungeon->map) == map && dungeon->difficulty == difficulty) + return true; + + return false; +} diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 74c7ca9e3d3..5b26cf9854c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -381,6 +381,9 @@ class LFGMgr void SetupGroupMember(uint64 guid, uint64 gguid); uint64 GetGroup(uint64 guid); + bool inRandomLfgDungeon(uint64 guid); + bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); + private: uint8 GetTeam(uint64 guid); void RestoreState(uint64 guid, char const* debugMsg); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 184450ef8d6..6358acfb97d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2486,11 +2486,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) } if (group && group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) - if (uint32(dungeon->map) == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM) - player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index ce9d5088317..08140772db9 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,7 +33,7 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" -#include "LFG.h" +#include "LFGMgr.h" #include "GroupMgr.h" class misc_commandscript : public CommandScript @@ -2834,41 +2834,40 @@ public: { handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); - Group::MemberSlotList::const_iterator itr; - for (itr = members.begin(); itr != members.end(); ++itr) + for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - std::ostringstream flags, roles; - if ((*itr).flags & MEMBER_FLAG_ASSISTANT) - flags << "Assistant "; - if ((*itr).flags & MEMBER_FLAG_MAINTANK) - flags << "MainTank "; - if ((*itr).flags & MEMBER_FLAG_MAINASSIST) - flags << "MainAssist "; - - if ((*itr).roles & PLAYER_ROLE_LEADER) - roles << "Leader "; - if ((*itr).roles & PLAYER_ROLE_TANK) - roles << "Tank "; - if ((*itr).roles & PLAYER_ROLE_HEALER) - roles << "Healer "; - if ((*itr).roles & PLAYER_ROLE_DAMAGE) - roles << "Damage "; + Group::MemberSlot const& slot = *itr; + + std::string flags; + if (slot.flags & MEMBER_FLAG_ASSISTANT) + flags = "Assistant"; + + if (slot.flags & MEMBER_FLAG_MAINTANK) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainTank"); + } + + if (slot.flags & MEMBER_FLAG_MAINASSIST) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainAssist"); + } + + if (flags.empty()) + flags = "None"; Player* p = ObjectAccessor::FindPlayer((*itr).guid); const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; - std::string flagsStr = (flags.str().empty()) ? "None" : flags.str(); - std::string rolesStr = (roles.str().empty()) ? "None" : roles.str(); - - handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, (*itr).name.c_str(), onlineState, GUID_LOPART((*itr).guid), flagsStr.c_str(), rolesStr.c_str()); + handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, + GUID_LOPART(slot.guid), flags.c_str(), LFGMgr::GetRolesString(slot.roles).c_str()); } - return true; } else - { handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); - return true; - } return true; } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index e7befff87a3..54ca3efd6d5 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1715,10 +1715,29 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader class spell_gen_luck_of_the_draw_AuraScript : public AuraScript { PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); + Map const* map; + Difficulty difficulty; bool Load() { - return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER; + Player* owner = GetUnitOwner()->ToPlayer(); + if (!owner) + return false; + + Group* group = owner->GetGroup(); + if (!group || group->isLFGGroup()) + return false; + + if (!sLFGMgr->inRandomLfgDungeon(owner->GetGUID())) + return false; + + map = owner->GetMap(); + difficulty = owner->GetMap()->GetDifficulty(); + + if (!sLFGMgr->inLfgDungeonMap(owner->GetGUID(), map->GetId(), difficulty)) + return false; + + return true; } // cheap hax to make it have update calls @@ -1730,30 +1749,9 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader void Update(AuraEffect* /*effect*/) { - if (Player* owner = GetUnitOwner()->ToPlayer()) - { - const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(owner->GetGUID()); - LfgDungeonSet::const_iterator itr = dungeons.begin(); - - if (itr == dungeons.end()) - { - Remove(AURA_REMOVE_BY_DEFAULT); - return; - } - - - LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*itr); - if (Group* group = owner->GetGroup()) - if (Map const* map = owner->GetMap()) - if (group->isLFGGroup()) - if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) - return; // in correct dungeon - + Map const* currentMap = GetUnitOwner()->ToPlayer()->GetMap(); + if (currentMap != map || currentMap->GetDifficulty() != difficulty) Remove(AURA_REMOVE_BY_DEFAULT); - } } void Register() -- cgit v1.2.3 From 9bdfc877748501066a6fce91b9d5f774eab5ac77 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 04:43:18 +0100 Subject: Core/Dungeon Finder: Use lfg namespace to encapsulate all LFG classes, structs and enums --- src/server/game/DungeonFinding/LFG.cpp | 91 ++++++++++++++++++ src/server/game/DungeonFinding/LFG.h | 9 ++ src/server/game/DungeonFinding/LFGGroupData.cpp | 5 + src/server/game/DungeonFinding/LFGGroupData.h | 5 + src/server/game/DungeonFinding/LFGMgr.cpp | 88 +---------------- src/server/game/DungeonFinding/LFGMgr.h | 10 +- src/server/game/DungeonFinding/LFGPlayerData.cpp | 5 + src/server/game/DungeonFinding/LFGPlayerData.h | 5 + src/server/game/DungeonFinding/LFGQueue.cpp | 11 ++- src/server/game/DungeonFinding/LFGQueue.h | 5 + src/server/game/DungeonFinding/LFGScripts.cpp | 5 + src/server/game/DungeonFinding/LFGScripts.h | 5 + src/server/game/Entities/Player/Player.cpp | 29 ++---- src/server/game/Groups/Group.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 116 +++++++++++------------ src/server/game/Maps/Map.cpp | 2 +- src/server/game/Server/WorldSession.h | 23 +++-- src/server/scripts/Commands/cs_lfg.cpp | 10 +- src/server/scripts/Commands/cs_misc.cpp | 4 +- 19 files changed, 242 insertions(+), 188 deletions(-) create mode 100644 src/server/game/DungeonFinding/LFG.cpp (limited to 'src') diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp new file mode 100644 index 00000000000..e146899841f --- /dev/null +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -0,0 +1,91 @@ +#include "LFG.h" +#include "Language.h" +#include "ObjectMgr.h" + +namespace lfg +{ + +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons) +{ + std::string dungeonstr = ""; + if (!dungeons.empty()) + { + std::ostringstream o; + LfgDungeonSet::const_iterator it = dungeons.begin(); + o << (*it); + for (++it; it != dungeons.end(); ++it) + o << ", " << uint32(*it); + dungeonstr = o.str(); + } + return dungeonstr; +} + +std::string GetRolesString(uint8 roles) +{ + std::string rolesstr = ""; + + if (roles & PLAYER_ROLE_TANK) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); + + if (roles & PLAYER_ROLE_HEALER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); + } + + if (roles & PLAYER_ROLE_DAMAGE) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); + } + + if (roles & PLAYER_ROLE_LEADER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); + } + + if (rolesstr.empty()) + rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); + + return rolesstr; +} + +std::string GetStateString(LfgState state) +{ + int32 entry = LANG_LFG_ERROR; + switch (state) + { + case LFG_STATE_NONE: + entry = LANG_LFG_STATE_NONE; + break; + case LFG_STATE_ROLECHECK: + entry = LANG_LFG_STATE_ROLECHECK; + break; + case LFG_STATE_QUEUED: + entry = LANG_LFG_STATE_QUEUED; + break; + case LFG_STATE_PROPOSAL: + entry = LANG_LFG_STATE_PROPOSAL; + break; + case LFG_STATE_DUNGEON: + entry = LANG_LFG_STATE_DUNGEON; + break; + case LFG_STATE_BOOT: + entry = LANG_LFG_STATE_BOOT; + break; + case LFG_STATE_FINISHED_DUNGEON: + entry = LANG_LFG_STATE_FINISHED_DUNGEON; + break; + case LFG_STATE_RAIDBROWSER: + entry = LANG_LFG_STATE_RAIDBROWSER; + break; + } + + return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); +} + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index ebbcfb1d71a..541e4d6bd43 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -20,6 +20,9 @@ #include "Common.h" +namespace lfg +{ + enum LFGEnum { LFG_TANKS_NEEDED = 1, @@ -99,4 +102,10 @@ typedef std::list LfgGuidList; typedef std::map LfgRolesMap; typedef std::map LfgGroupsMap; +std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); +std::string GetRolesString(uint8 roles); +std::string GetStateString(LfgState state); + +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 427225bf323..f711514e26d 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -18,6 +18,9 @@ #include "LFG.h" #include "LFGGroupData.h" +namespace lfg +{ + LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Leader(0), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) { } @@ -122,3 +125,5 @@ uint8 LfgGroupData::GetKicksLeft() const { return m_KicksLeft; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 2ad020d3bc1..47e562c37aa 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgGroupEnum { LFG_GROUP_MAX_KICKS = 3, @@ -75,4 +78,6 @@ class LfgGroupData uint8 m_KicksLeft; ///< Number of kicks left }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 4c6a8b92e0b..05a15b9cb6a 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -33,6 +33,9 @@ #include "GameEventMgr.h" #include "WorldSession.h" +namespace lfg +{ + LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)) { @@ -95,89 +98,6 @@ void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid) CharacterDatabase.Execute(stmt); } -std::string LFGMgr::ConcatenateDungeons(LfgDungeonSet const& dungeons) -{ - std::string dungeonstr = ""; - if (!dungeons.empty()) - { - std::ostringstream o; - LfgDungeonSet::const_iterator it = dungeons.begin(); - o << (*it); - for (++it; it != dungeons.end(); ++it) - o << ", " << uint32(*it); - dungeonstr = o.str(); - } - return dungeonstr; -} - -std::string LFGMgr::GetRolesString(uint8 roles) -{ - std::string rolesstr = ""; - - if (roles & PLAYER_ROLE_TANK) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_TANK)); - - if (roles & PLAYER_ROLE_HEALER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_HEALER)); - } - - if (roles & PLAYER_ROLE_DAMAGE) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_DAMAGE)); - } - - if (roles & PLAYER_ROLE_LEADER) - { - if (!rolesstr.empty()) - rolesstr.append(", "); - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_LEADER)); - } - - if (rolesstr.empty()) - rolesstr.append(sObjectMgr->GetTrinityStringForDBCLocale(LANG_LFG_ROLE_NONE)); - - return rolesstr; -} - -std::string LFGMgr::GetStateString(LfgState state) -{ - int32 entry = LANG_LFG_ERROR; - switch (state) - { - case LFG_STATE_NONE: - entry = LANG_LFG_STATE_NONE; - break; - case LFG_STATE_ROLECHECK: - entry = LANG_LFG_STATE_ROLECHECK; - break; - case LFG_STATE_QUEUED: - entry = LANG_LFG_STATE_QUEUED; - break; - case LFG_STATE_PROPOSAL: - entry = LANG_LFG_STATE_PROPOSAL; - break; - case LFG_STATE_DUNGEON: - entry = LANG_LFG_STATE_DUNGEON; - break; - case LFG_STATE_BOOT: - entry = LANG_LFG_STATE_BOOT; - break; - case LFG_STATE_FINISHED_DUNGEON: - entry = LANG_LFG_STATE_FINISHED_DUNGEON; - break; - case LFG_STATE_RAIDBROWSER: - entry = LANG_LFG_STATE_RAIDBROWSER; - break; - } - - return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); -} - /// Load rewards for completing dungeons void LFGMgr::LoadRewards() { @@ -2065,3 +1985,5 @@ bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) return false; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 5b26cf9854c..20116caaaf3 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -30,6 +30,9 @@ class Group; class Player; class Quest; +namespace lfg +{ + enum LfgOptions { LFG_OPTION_ENABLE_DUNGEON_FINDER = 0x01, @@ -371,9 +374,6 @@ class LFGMgr bool IsSeasonActive(uint32 dungeonId); std::string DumpQueueInfo(bool full = false); - static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); - static std::string GetRolesString(uint8 roles); - static std::string GetStateString(LfgState state); void LoadLFGDungeons(bool reload = false); LFGDungeonData const* GetLFGDungeon(uint32 id); @@ -429,5 +429,7 @@ class LFGMgr LfgGuidList teleportStore; ///< Players being teleported }; -#define sLFGMgr ACE_Singleton::instance() +} // namespace lfg + +#define sLFGMgr ACE_Singleton::instance() #endif diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp index 410076f7e75..e8ef430bc1f 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.cpp +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -17,6 +17,9 @@ #include "LFGPlayerData.h" +namespace lfg +{ + LfgPlayerData::LfgPlayerData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Team(0), m_Group(0), m_Roles(0), m_Comment("") {} @@ -122,3 +125,5 @@ LfgDungeonSet const& LfgPlayerData::GetSelectedDungeons() const { return m_SelectedDungeons; } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h index 055924fd364..a425ce77bad 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.h +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + /** Stores all lfg data needed about the player. */ @@ -68,4 +71,6 @@ class LfgPlayerData LfgDungeonSet m_SelectedDungeons; ///< Selected Dungeons when joined LFG }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index f1d2dbb313d..6a98fccecdc 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -27,6 +27,9 @@ #include "World.h" #include "GroupMgr.h" +namespace lfg +{ + /** Given a list of guids returns the concatenation using | as delimiter @@ -431,7 +434,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) { std::ostringstream o; for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it) - o << ", " << it->first << ": " << sLFGMgr->GetRolesString(it->second); + o << ", " << it->first << ": " << GetRolesString(it->second); sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Roles not compatible%s", strGuids.c_str(), o.str().c_str()); SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES); @@ -441,12 +444,12 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) LfgGuidList::iterator itguid = check.begin(); proposalDungeons = QueueDataStore[*itguid].dungeons; std::ostringstream o; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(proposalDungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(proposalDungeons) << ")"; for (++itguid; itguid != check.end(); ++itguid) { LfgDungeonSet temporal; LfgDungeonSet &dungeons = QueueDataStore[*itguid].dungeons; - o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(dungeons) << ")"; + o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")"; std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin())); proposalDungeons = temporal; } @@ -671,3 +674,5 @@ void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQu --queueData.dps; } } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index acb78d2c0f2..db7e7bbf318 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -20,6 +20,9 @@ #include "LFG.h" +namespace lfg +{ + enum LfgCompatibility { LFG_COMPATIBILITY_PENDING, @@ -140,4 +143,6 @@ class LFGQueue LfgGuidList newToQueueStore; ///< New groups to add to queue }; +} // namespace lfg + #endif diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 568b61eef2f..ac95d289397 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -29,6 +29,9 @@ #include "ObjectAccessor.h" #include "WorldSession.h" +namespace lfg +{ + LFGPlayerScript::LFGPlayerScript() : PlayerScript("LFGPlayerScript") { } @@ -208,3 +211,5 @@ void LFGGroupScript::OnInviteMember(Group* group, uint64 guid) if (leader && !gguid) sLFGMgr->LeaveLfg(leader); } + +} // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 227543e1899..e9c6b1499d1 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -26,6 +26,9 @@ class Player; class Group; +namespace lfg +{ + class LFGPlayerScript : public PlayerScript { public: @@ -50,3 +53,5 @@ class LFGGroupScript : public GroupScript void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); void OnInviteMember(Group* group, uint64 guid); }; + +} // namespace lfg diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 59f9e1e3efb..9c398bd88fb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11913,7 +11913,7 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); + lfg::LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); if (dungeons.empty()) return EQUIP_ERR_OK; // not using LFG @@ -11923,10 +11923,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje // check if looted object is inside the lfg dungeon bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); - if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true)) - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) - lootedObjectInDungeon = true; + lootedObjectInDungeon = sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty()); if (!lootedObjectInDungeon) return EQUIP_ERR_OK; @@ -23426,14 +23423,14 @@ PartyResult Player::CanUninviteFromGroup() const if (!sLFGMgr->GetKicksLeft(gguid)) return ERR_PARTY_LFG_BOOT_LIMIT; - LfgState state = sLFGMgr->GetState(gguid); - if (state == LFG_STATE_BOOT) + lfg::LfgState state = sLFGMgr->GetState(gguid); + if (state == lfg::LFG_STATE_BOOT) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; - if (grp->GetMembersCount() <= LFG_GROUP_KICK_VOTES_NEEDED) + if (grp->GetMembersCount() <= lfg::LFG_GROUP_KICK_VOTES_NEEDED) return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; - if (state == LFG_STATE_FINISHED_DUNGEON) + if (state == lfg::LFG_STATE_FINISHED_DUNGEON) return ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE; if (grp->isRollLootActive()) @@ -23463,22 +23460,12 @@ PartyResult Player::CanUninviteFromGroup() const bool Player::isUsingLfg() { - return sLFGMgr->GetState(GetGUID()) != LFG_STATE_NONE; + return sLFGMgr->GetState(GetGUID()) != lfg::LFG_STATE_NONE; } bool Player::inRandomLfgDungeon() { - if (isUsingLfg()) - { - const LfgDungeonSet& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (!dungeons.empty()) - { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin()); - if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) - return true; - } - } - return false; + return sLFGMgr->inRandomLfgDungeon(GetGUID()); } void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 711e07ef941..eb2d33c63a0 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1496,7 +1496,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) data << uint8(slot->roles); if (isLFGGroup()) { - data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done + data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done data << uint32(sLFGMgr->GetDungeon(m_guid)); } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 0654ae326f9..60fc63694ee 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,20 +23,20 @@ #include "WorldPacket.h" #include "WorldSession.h" -void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) +void BuildPlayerLockDungeonBlock(WorldPacket& data, lfg::LfgLockMap const& lock) { data << uint32(lock.size()); // Size of lock dungeons - for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) + for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) { data << uint32(it->first); // Dungeon entry (id + type) data << uint32(it->second); // Lock status } } -void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMap) +void BuildPartyLockDungeonBlock(WorldPacket& data, lfg::LfgLockPartyMap const& lockMap) { data << uint8(lockMap.size()); - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) { data << uint64(it->first); // Player guid BuildPlayerLockDungeonBlock(data, it->second); @@ -45,7 +45,7 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { - if (!sLFGMgr->isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER) || + if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { @@ -66,7 +66,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) return; } - LfgDungeonSet newDungeons; + lfg::LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { uint32 dungeon; @@ -167,21 +167,21 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion - LfgDungeonSet randomDungeons; + lfg::LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); - LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); - for (LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) + lfg::LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); + for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) { - LFGDungeonData const& dungeon = itr->second; - if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + lfg::LFGDungeonData const& dungeon = itr->second; + if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) randomDungeons.insert(dungeon.Entry()); } // Get player locked Dungeons - LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); + lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); @@ -189,10 +189,10 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4)); data << uint8(randomDungeons.size()); // Random Dungeon count - for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) - LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); + lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; bool done = false; if (reward) @@ -250,7 +250,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* return; // Get the locked dungeons of the other party members - LfgLockPartyMap lockMap; + lfg::LfgLockPartyMap lockMap; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); @@ -265,7 +265,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* } uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PARTY_INFO %s", GetPlayerInfo().c_str()); @@ -297,7 +297,7 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_GET_STATUS %s", GetPlayerInfo().c_str()); uint64 guid = GetPlayer()->GetGUID(); - LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); + lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid); if (GetPlayer()->GetGroup()) { @@ -313,19 +313,19 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) } } -void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) +void WorldSession::SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData) { bool queued = false; uint8 size = uint8(updateData.dungeons.size()); switch (updateData.updateType) { - case LFG_UPDATETYPE_JOIN_QUEUE: - case LFG_UPDATETYPE_ADDED_TO_QUEUE: + case lfg::LFG_UPDATETYPE_JOIN_QUEUE: + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: queued = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -343,14 +343,14 @@ void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } SendPacket(&data); } -void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) +void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData) { bool join = false; bool queued = false; @@ -358,15 +358,15 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) switch (updateData.updateType) { - case LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success + case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success queued = true; // no break on purpose - case LFG_UPDATETYPE_PROPOSAL_BEGIN: + case lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN: join = true; break; - case LFG_UPDATETYPE_UPDATE_STATUS: - join = updateData.state != LFG_STATE_ROLECHECK && updateData.state != LFG_STATE_NONE; - queued = updateData.state == LFG_STATE_QUEUED; + case lfg::LFG_UPDATETYPE_UPDATE_STATUS: + join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE; + queued = updateData.state == lfg::LFG_STATE_QUEUED; break; default: break; @@ -387,7 +387,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) data << uint8(0); // unk - Always 0 data << uint8(size); - for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) + for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it) data << uint32(*it); data << updateData.comment; } @@ -406,9 +406,9 @@ void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles) SendPacket(&data); } -void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) +void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) { - LfgDungeonSet dungeons; + lfg::LfgDungeonSet dungeons; if (roleCheck.rDungeonId) dungeons.insert(roleCheck.rDungeonId); else @@ -418,13 +418,13 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); data << uint32(roleCheck.state); // Check result - data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); + data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) { - for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) + for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { - LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); + lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } @@ -441,7 +441,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) Player* player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level - for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) + for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { if (it->first == roleCheck.leader) continue; @@ -458,10 +458,10 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) SendPacket(&data); } -void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) +void WorldSession::SendLfgJoinResult(lfg::LfgJoinResultData const& joinData) { uint32 size = 0; - for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) + for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u", @@ -475,7 +475,7 @@ void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) +void WorldSession::SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData) { sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " @@ -498,7 +498,7 @@ void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) +void WorldSession::SendLfgPlayerReward(lfg::LfgPlayerRewardData const& rewardData) { if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest) return; @@ -532,42 +532,42 @@ void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) SendPacket(&data); } -void WorldSession::SendLfgBootProposalUpdate(LfgPlayerBoot const& boot) +void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot) { uint64 guid = GetPlayer()->GetGUID(); - LfgAnswer playerVote = boot.votes.find(guid)->second; + lfg::LfgAnswer playerVote = boot.votes.find(guid)->second; uint8 votesNum = 0; uint8 agreeNum = 0; uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000); - for (LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) + for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) { - if (it->second != LFG_ANSWER_PENDING) + if (it->second != lfg::LFG_ANSWER_PENDING) { ++votesNum; - if (it->second == LFG_ANSWER_AGREE) + if (it->second == lfg::LFG_ANSWER_AGREE) ++agreeNum; } } sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - " "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - " "needed: %u - reason %s", - GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), - uint8(playerVote == LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, - secsleft, LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); + GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), + uint8(playerVote == lfg::LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum, + secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); data << uint8(boot.inProgress); // Vote in progress - data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote - data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree + data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote + data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree data << uint64(boot.victim); // Victim GUID data << uint32(votesNum); // Total Votes data << uint32(agreeNum); // Agree Count data << uint32(secsleft); // Time Left - data << uint32(LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes + data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes data << boot.reason.c_str(); // Kick reason SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) +void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) { uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = proposal.players.find(guid)->second.group; @@ -580,12 +580,12 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) // show random dungeon if player selected random dungeon and it's not lfg group if (!silent) { - LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end()) dungeonEntry = (*playerDungeons.begin()); } - if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) + if (lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) dungeonEntry = dungeon->Entry(); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); @@ -596,9 +596,9 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size - for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) + for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { - LfgProposalPlayer const& player = it->second; + lfg::LfgProposalPlayer const& player = it->second; data << uint32(player.role); // Role data << uint8(it->first == guid); // Self player if (!player.group) // Player not it a group @@ -611,8 +611,8 @@ void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) data << uint8(player.group == proposal.group); // In dungeon (silent) data << uint8(player.group == gguid); // Same Group than player } - data << uint8(player.accept != LFG_ANSWER_PENDING);// Answered - data << uint8(player.accept == LFG_ANSWER_AGREE); // Accepted + data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered + data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 6358acfb97d..288592d1029 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2486,7 +2486,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) } if (group && group->isLFGGroup()) - player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + player->CastSpell(player, lfg::LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index abe048279db..11bb7a36f5a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -48,15 +48,18 @@ struct AreaTableEntry; struct AuctionEntry; struct DeclinedName; struct ItemTemplate; +struct MovementInfo; + +namespace lfg +{ struct LfgJoinResultData; -struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; struct LfgQueueStatusData; struct LfgPlayerRewardData; struct LfgRoleCheck; struct LfgUpdateData; -struct MovementInfo; +} enum AccountDataType { @@ -782,16 +785,16 @@ class WorldSession void HandleLfrLeaveOpcode(WorldPacket& recvData); void HandleLfgGetStatus(WorldPacket& recvData); - void SendLfgUpdatePlayer(LfgUpdateData const& updateData); - void SendLfgUpdateParty(LfgUpdateData const& updateData); + void SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData); + void SendLfgUpdateParty(lfg::LfgUpdateData const& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(LfgRoleCheck const& pRoleCheck); + void SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& pRoleCheck); void SendLfgLfrList(bool update); - void SendLfgJoinResult(LfgJoinResultData const& joinData); - void SendLfgQueueStatus(LfgQueueStatusData const& queueData); - void SendLfgPlayerReward(LfgPlayerRewardData const& lfgPlayerRewardData); - void SendLfgBootProposalUpdate(LfgPlayerBoot const& boot); - void SendLfgUpdateProposal(LfgProposal const& proposal); + void SendLfgJoinResult(lfg::LfgJoinResultData const& joinData); + void SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData); + void SendLfgPlayerReward(lfg::LfgPlayerRewardData const& lfgPlayerRewardData); + void SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot); + void SendLfgUpdateProposal(lfg::LfgProposal const& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 7f39a8fc024..aa9d9308bcd 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -28,12 +28,12 @@ void GetPlayerInfo(ChatHandler* handler, Player* player) return; uint64 guid = player->GetGUID(); - LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); + lfg::LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_PLAYER_INFO, player->GetName().c_str(), - state.c_str(), uint8(dungeons.size()), sLFGMgr->ConcatenateDungeons(dungeons).c_str(), - sLFGMgr->GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); + state.c_str(), uint8(dungeons.size()), lfg::ConcatenateDungeons(dungeons).c_str(), + lfg::GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); } class lfg_commandscript : public CommandScript @@ -87,7 +87,7 @@ public: } uint64 guid = grp->GetGUID(); - std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(), state.c_str(), sLFGMgr->GetDungeon(guid)); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 08140772db9..cc1b62ea99d 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -33,7 +33,7 @@ #include "ace/INET_Addr.h" #include "Player.h" #include "Pet.h" -#include "LFGMgr.h" +#include "LFG.h" #include "GroupMgr.h" class misc_commandscript : public CommandScript @@ -2863,7 +2863,7 @@ public: const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, - GUID_LOPART(slot.guid), flags.c_str(), LFGMgr::GetRolesString(slot.roles).c_str()); + GUID_LOPART(slot.guid), flags.c_str(), lfg::GetRolesString(slot.roles).c_str()); } } else -- cgit v1.2.3 From f743424f630af8c8b940bcc3a8ed08512708540c Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 05:50:52 +0100 Subject: Core/Dungeon Finder: Corrections to previous commit - player::inRandomLfgDungeon was supposed to return if current player map and difficulty are the ones player applied for --- src/server/game/DungeonFinding/LFG.cpp | 17 +++++++++++++++++ src/server/game/DungeonFinding/LFGMgr.cpp | 5 ++++- src/server/game/DungeonFinding/LFGMgr.h | 2 +- src/server/game/Entities/Player/Player.cpp | 8 +++++++- src/server/scripts/Spells/spell_generic.cpp | 2 +- 5 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp index e146899841f..ce16ad5533e 100644 --- a/src/server/game/DungeonFinding/LFG.cpp +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + #include "LFG.h" #include "Language.h" #include "ObjectMgr.h" diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 05a15b9cb6a..3e8cc7d4aa9 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1960,7 +1960,7 @@ void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) AddPlayerToGroup(gguid, guid); } -bool LFGMgr::inRandomLfgDungeon(uint64 guid) +bool LFGMgr::selectedRandomLfgDungeon(uint64 guid) { if (GetState(guid) != LFG_STATE_NONE) { @@ -1978,6 +1978,9 @@ bool LFGMgr::inRandomLfgDungeon(uint64 guid) bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) { + if (!IS_GROUP_GUID(guid)) + guid = GetGroup(guid); + if (uint32 dungeonId = GetDungeon(guid, true)) if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) if (uint32(dungeon->map) == map && dungeon->difficulty == difficulty) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 20116caaaf3..43ae128174f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -381,7 +381,7 @@ class LFGMgr void SetupGroupMember(uint64 guid, uint64 gguid); uint64 GetGroup(uint64 guid); - bool inRandomLfgDungeon(uint64 guid); + bool selectedRandomLfgDungeon(uint64 guid); bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); private: diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9c398bd88fb..72ddd0b8595 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23465,7 +23465,13 @@ bool Player::isUsingLfg() bool Player::inRandomLfgDungeon() { - return sLFGMgr->inRandomLfgDungeon(GetGUID()); + if (sLFGMgr->selectedRandomLfgDungeon(GetGUID())) + { + Map const* map = GetMap(); + return sLFGMgr->inLfgDungeonMap(GetGUID(), map->GetId(), map->GetDifficulty()); + } + + return false; } void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 54ca3efd6d5..61f4a81bc73 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1728,7 +1728,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader if (!group || group->isLFGGroup()) return false; - if (!sLFGMgr->inRandomLfgDungeon(owner->GetGUID())) + if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) return false; map = owner->GetMap(); -- cgit v1.2.3 From ec5d16db8a688a2b6262333e5f1e927e2c1f639a Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 06:43:03 +0100 Subject: Core/Dungeon Finder: Declare some functions private as those are not used outside LFGMgr. Also do not expose LFGDungeonData outside LFGMgr --- src/server/game/DungeonFinding/LFGMgr.cpp | 31 ++++-- src/server/game/DungeonFinding/LFGMgr.h | 167 +++++++++++++++++----------- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Globals/ObjectMgr.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 23 +--- src/server/scripts/Spells/spell_generic.cpp | 2 +- 6 files changed, 135 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 3e8cc7d4aa9..d9d4a897eed 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -127,7 +127,7 @@ void LFGMgr::LoadRewards() uint32 firstQuestId = fields[2].GetUInt32(); uint32 otherQuestId = fields[3].GetUInt32(); - if (!GetLFGDungeon(dungeonId)) + if (!GetLFGDungeonEntry(dungeonId)) { sLog->outError(LOG_FILTER_SQL, "Dungeon %u specified in table `lfg_dungeon_rewards` does not exist!", dungeonId); continue; @@ -168,11 +168,6 @@ LFGDungeonData const* LFGMgr::GetLFGDungeon(uint32 id) return NULL; } -LFGDungeonContainer & LFGMgr::GetLFGDungeonMap() -{ - return LfgDungeonStore; -} - void LFGMgr::LoadLFGDungeons(bool reload /* = false */) { uint32 oldMSTime = getMSTime(); @@ -1595,7 +1590,7 @@ const std::string& LFGMgr::GetComment(uint64 guid) return PlayersStore[guid].GetComment(); } -bool LFGMgr::IsTeleported(uint64 pguid) +bool LFGMgr::hasPendingTeleport(uint64 pguid) { if (std::find(teleportStore.begin(), teleportStore.end(), pguid) != teleportStore.end()) { @@ -1989,4 +1984,26 @@ bool LFGMgr::inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty) return false; } +uint32 LFGMgr::GetLFGDungeonEntry(uint32 id) +{ + if (id) + if (LFGDungeonData const* dungeon = GetLFGDungeon(id)) + return dungeon->Entry(); + + return 0; +} + +LfgDungeonSet LFGMgr::GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion) +{ + LfgDungeonSet randomDungeons; + for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeonStore.begin(); itr != LfgDungeonStore.end(); ++itr) + { + lfg::LFGDungeonData const& dungeon = itr->second; + if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) + randomDungeons.insert(dungeon.Entry()); + } + return randomDungeons; +} + } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 43ae128174f..da7980647bb 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -299,91 +299,125 @@ class LFGMgr ~LFGMgr(); public: + // Functions used outside lfg namespace void Update(uint32 diff); - // Reward - void LoadRewards(); + // World.cpp + /// Finish the dungeon for the given group. All check are performed using internal lfg data void FinishDungeon(uint64 gguid, uint32 dungeonId); - LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); - - // Queue - void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); - void LeaveLfg(uint64 guid); - - // Role Check - void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); - - // Group Matching - static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); - void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); - - // Proposals - uint32 AddProposal(LfgProposal& proposal); - void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Loads rewards for random dungeons + void LoadRewards(); + /// Loads dungeons from dbc and adds teleport coords + void LoadLFGDungeons(bool reload = false); - // Teleportation - void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + // Multiple files + /// Check if given guid applied for random dungeon + bool selectedRandomLfgDungeon(uint64 guid); + /// Check if given guid applied for given map and difficulty. Used to know + bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); + /// Get selected dungeons + LfgDungeonSet const& GetSelectedDungeons(uint64 guid); + /// Get current lfg state + LfgState GetState(uint64 guid); + /// Get current dungeon + uint32 GetDungeon(uint64 guid, bool asId = true); + /// Get the map id of the current dungeon + uint32 GetDungeonMapId(uint64 guid); + /// Get kicks left in current group + uint8 GetKicksLeft(uint64 gguid); + /// Load Lfg group info from DB + void _LoadFromDB(Field* fields, uint64 guid); + /// Initializes player data after loading group data from DB + void SetupGroupMember(uint64 guid, uint64 gguid); + /// Player has pending teleport action + bool hasPendingTeleport(uint64 guid); + /// Return Lfg dungeon entry for given dungeon id + uint32 GetLFGDungeonEntry(uint32 id); - // Vote kick - void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); - void UpdateBoot(uint64 guid, bool accept); + // cs_lfg + /// Get current player roles + uint8 GetRoles(uint64 guid); + /// Get current player comment (used for LFR) + std::string const& GetComment(uint64 gguid); + /// Gets current lfg options + uint32 GetOptions(); // cs_lfg + /// Sets new lfg options + void SetOptions(uint32 options); + /// Checks if given lfg option is enabled + bool isOptionEnabled(uint32 option); + /// Clears queue - Only for internal testing + void Clean(); + /// Dumps the state of the queue - Only for internal testing + std::string DumpQueueInfo(bool full = false); + // LFGScripts + /// Get leader of the group (using internal data) + uint64 GetLeader(uint64 guid); + /// Initializes locked dungeons for given player (called at login or level change) void InitializeLockedDungeons(Player* player, uint8 level = 0); - - void SetRoles(uint64 guid, uint8 roles); - void SetComment(uint64 guid, std::string const& comment); + /// Inits new proposal to boot a player + void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); + /// Sets player team void SetTeam(uint64 guid, uint8 team); + /// Sets player group void SetGroup(uint64 guid, uint64 group); + /// Gets player group + uint64 GetGroup(uint64 guid); + /// Sets the leader of the group void SetLeader(uint64 gguid, uint64 leader); - void SetState(uint64 guid, LfgState state); - - void _LoadFromDB(Field* fields, uint64 guid); - void _SaveToDB(uint64 guid, uint32 db_guid); - - void RemovePlayerData(uint64 guid); + /// Removes saved group data void RemoveGroupData(uint64 guid); + /// Removes a player from a group uint8 RemovePlayerFromGroup(uint64 gguid, uint64 guid); + /// Adds player to group void AddPlayerToGroup(uint64 gguid, uint64 guid); + // LFGHandler + /// Get locked dungeons LfgLockMap const& GetLockedDungeons(uint64 guid); - LfgDungeonSet const& GetSelectedDungeons(uint64 guid); - uint32 GetDungeon(uint64 guid, bool asId = true); - uint32 GetDungeonMapId(uint64 guid); - LfgState GetState(uint64 guid); + /// Returns current lfg status + LfgUpdateData GetLfgStatus(uint64 guid); + /// Checks if Seasonal dungeon is active + bool IsSeasonActive(uint32 dungeonId); + /// Gets the random dungeon reward corresponding to given dungeon and player level + LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); + /// Returns all random and seasonal dungeons for given level and expansion + LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion); + /// Teleport a player to/from selected dungeon + void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + /// Updates player boot proposal with new player answer + void UpdateBoot(uint64 guid, bool accept); + /// Updates proposal to join dungeon with player answer + void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); + /// Updates the role check with player answer + void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); + /// Sets player lfg roles + void SetRoles(uint64 guid, uint8 roles); + /// Sets player lfr comment + void SetComment(uint64 guid, std::string const& comment); + /// Join Lfg with selected roles, dungeons and comment + void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); + /// Leaves lfg + void LeaveLfg(uint64 guid); + + // LfgQueue + /// Get last lfg state (NONE, DUNGEON or FINISHED_DUNGEON) LfgState GetOldState(uint64 guid); - uint8 GetKicksLeft(uint64 gguid); - uint64 GetLeader(uint64 guid); + /// Check if given group guid is lfg bool IsLfgGroup(uint64 guid); - uint8 GetRoles(uint64 guid); - std::string const& GetComment(uint64 gguid); - LfgGuidSet const& GetPlayers(uint64 guid); + /// Gets the player count of given group uint8 GetPlayerCount(uint64 guid); - - bool IsTeleported(uint64 guid); - + /// Add a new Proposal + uint32 AddProposal(LfgProposal& proposal); + /// Checks if all players are queued bool AllQueued(LfgGuidList const& check); - void Clean(); - + /// Checks if given roles match, modifies given roles map with new roles + static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); + /// Checks if given players are ignoring each other static bool HasIgnore(uint64 guid1, uint64 guid2); + /// Sends queue status to player static void SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data); - bool isOptionEnabled(uint32 option); - uint32 GetOptions(); - void SetOptions(uint32 options); - LfgUpdateData GetLfgStatus(uint64 guid); - bool IsSeasonActive(uint32 dungeonId); - - std::string DumpQueueInfo(bool full = false); - - void LoadLFGDungeons(bool reload = false); - LFGDungeonData const* GetLFGDungeon(uint32 id); - LFGDungeonContainer& GetLFGDungeonMap(); - void SetupGroupMember(uint64 guid, uint64 gguid); - uint64 GetGroup(uint64 guid); - - bool selectedRandomLfgDungeon(uint64 guid); - bool inLfgDungeonMap(uint64 guid, uint32 map, Difficulty difficulty); - private: uint8 GetTeam(uint64 guid); void RestoreState(uint64 guid, char const* debugMsg); @@ -392,6 +426,11 @@ class LFGMgr void SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons); void SetLockedDungeons(uint64 guid, LfgLockMap const& lock); void DecreaseKicksLeft(uint64 guid); + void SetState(uint64 guid, LfgState state); + void RemovePlayerData(uint64 guid); + void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); + void _SaveToDB(uint64 guid, uint32 db_guid); + LFGDungeonData const* GetLFGDungeon(uint32 id); // Proposals void RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdateType type); @@ -410,6 +449,8 @@ class LFGMgr void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data); void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal); + LfgGuidSet const& GetPlayers(uint64 guid); + // General variables uint32 m_QueueTimer; ///< used to check interval of update uint32 m_lfgProposalId; ///< used as internal counter for proposals diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 72ddd0b8595..a4356f55340 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7446,7 +7446,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (Group* group = GetGroup()) { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - if (GetSession() && group->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) + if (GetSession() && group->isLFGGroup() && sLFGMgr->hasPendingTeleport(GetGUID())) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index a3a5c865a48..1dd824759c9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5010,7 +5010,7 @@ void ObjectMgr::LoadInstanceEncounters() continue; } - if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeon(lastEncounterDungeon)) + if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon)) { sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon); continue; diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 60fc63694ee..619e9b68b51 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -167,18 +167,9 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion - lfg::LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); - uint8 expansion = GetPlayer()->GetSession()->Expansion(); - - lfg::LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); - for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) - { - lfg::LFGDungeonData const& dungeon = itr->second; - if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) - && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) - randomDungeons.insert(dungeon.Entry()); - } + lfg::LfgDungeonSet const& randomDungeons = + sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion()); // Get player locked Dungeons lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); @@ -421,13 +412,8 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) - { for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) - { - lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); - data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon - } - } + data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon data << uint8(roleCheck.roles.size()); // Players in group if (!roleCheck.roles.empty()) @@ -585,8 +571,7 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal) dungeonEntry = (*playerDungeons.begin()); } - if (lfg::LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) - dungeonEntry = dungeon->Entry(); + dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeonEntry); // Dungeon diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 61f4a81bc73..39992e94c21 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1725,7 +1725,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader return false; Group* group = owner->GetGroup(); - if (!group || group->isLFGGroup()) + if (!group || !group->isLFGGroup()) return false; if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) -- cgit v1.2.3 From c7c3ae648c95e1b988dba64f8e902c026eafb30e Mon Sep 17 00:00:00 2001 From: m7nu3l Date: Mon, 4 Feb 2013 04:44:44 -0300 Subject: Core/MovementGenerator: Now MovementInform event is called at the truly end of Finalize function. Thanks to Trista. --- .../game/Movement/MovementGenerators/PointMovementGenerator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 06b2315f294..1f5503948c8 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -128,8 +128,6 @@ void EffectMovementGenerator::Finalize(Unit* unit) if (unit->GetTypeId() != TYPEID_UNIT) return; - if (unit->ToCreature()->AI()) - unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); // Need restore previous movement since we have no proper states system if (unit->isAlive() && !unit->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING)) { @@ -138,4 +136,7 @@ void EffectMovementGenerator::Finalize(Unit* unit) else unit->GetMotionMaster()->Initialize(); } + + if (unit->ToCreature()->AI()) + unit->ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); } -- cgit v1.2.3 From b980aff83e214bab60f141c879c2a392789a4d16 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 08:21:25 +0100 Subject: Core: Implement Role based Access Control - This system will give more control of actions an account can perform. System defines: - Permissions to perform some action - Roles: a set of permissions that have some relation - Groups: a set of roles that have some relation Operations: - Grant: Assign and allow - Deny: Assign and do not allow - Revoke: Remove Precedence to know if something can be done: Grant, Deny. That means, if you are granted some action by a role but you have denied the permission, the action can not be done. Some Rules: - Groups can only have roles - Roles can only have permissions - An account can be assigned granted and denied roles. Permissions inherited from roles are granted if roles is granted and denied if roles is denied - An account can be assigned granted and denied permissions - An account can have multiple groups, roles and permissions - An account can not have same role granted and denied at same time - An acconnt can not have same permission granted and denied at same time - Id 0 can not be used to define a group, role or permission Added some permissions as a sample of use (Instant Logout, Skip Queue, Join BGs, Join DF) and some permissions as a workaround to commands till command system is modified to use RBAC --- sql/updates/auth/2013_02_04_00_auth_misc.sql | 173 ++++++++++++++++ sql/updates/world/2013_02_04_03_world_misc.sql | 53 +++++ src/server/game/AI/CreatureAIImpl.h | 30 +-- src/server/game/Accounts/AccountMgr.cpp | 217 ++++++++++++++++++++- src/server/game/Accounts/AccountMgr.h | 27 ++- src/server/game/Chat/Chat.cpp | 25 ++- src/server/game/DungeonFinding/LFGMgr.cpp | 11 +- src/server/game/DungeonFinding/LFGMgr.h | 2 +- src/server/game/Entities/Player/Player.cpp | 11 +- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/Miscellaneous/Language.h | 35 +++- src/server/game/Scripting/ScriptLoader.cpp | 2 + src/server/game/Server/WorldSession.cpp | 29 ++- src/server/game/Server/WorldSession.h | 6 + src/server/game/Server/WorldSocket.cpp | 1 + src/server/game/World/World.cpp | 7 +- src/server/scripts/Commands/CMakeLists.txt | 1 + src/server/scripts/Commands/cs_account.cpp | 34 +--- .../Database/Implementation/LoginDatabase.cpp | 16 +- .../shared/Database/Implementation/LoginDatabase.h | 10 + src/server/worldserver/worldserver.conf.dist | 20 -- 21 files changed, 625 insertions(+), 87 deletions(-) create mode 100644 sql/updates/auth/2013_02_04_00_auth_misc.sql create mode 100644 sql/updates/world/2013_02_04_03_world_misc.sql (limited to 'src') diff --git a/sql/updates/auth/2013_02_04_00_auth_misc.sql b/sql/updates/auth/2013_02_04_00_auth_misc.sql new file mode 100644 index 00000000000..573b58ac156 --- /dev/null +++ b/sql/updates/auth/2013_02_04_00_auth_misc.sql @@ -0,0 +1,173 @@ +-- Need them first in case of re-execute due to foreign keys +DROP TABLE IF EXISTS `rbac_account_permissions`; +DROP TABLE IF EXISTS `rbac_account_roles`; +DROP TABLE IF EXISTS `rbac_account_groups`; +DROP TABLE IF EXISTS `rbac_role_permissions`; +DROP TABLE IF EXISTS `rbac_group_roles`; +DROP TABLE IF EXISTS `rbac_permissions`; +DROP TABLE IF EXISTS `rbac_roles`; +DROP TABLE IF EXISTS `rbac_groups`; +DROP TABLE IF EXISTS `rbac_security_level_groups`; + +CREATE TABLE IF NOT EXISTS `rbac_groups` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', + `name` varchar(50) NOT NULL COMMENT 'Group name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group List'; + +CREATE TABLE IF NOT EXISTS `rbac_roles` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Role id', + `name` varchar(50) NOT NULL COMMENT 'Role name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Roles List'; + +CREATE TABLE IF NOT EXISTS `rbac_permissions` ( + `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Permission id', + `name` varchar(100) NOT NULL COMMENT 'Permission name', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Permission List'; + +CREATE TABLE IF NOT EXISTS `rbac_group_roles` ( + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + PRIMARY KEY (`groupId`, `roleId`), + CONSTRAINT `fk__rbac_group_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_group_roles__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Group Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_role_permissions` ( + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + PRIMARY KEY (`roleId`, `permissionId`), + CONSTRAINT `fk__role_permissions__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__role_permissions__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Role Permission relation'; + +CREATE TABLE IF NOT EXISTS `rbac_security_level_groups` ( + `secId` int(10) unsigned NOT NULL COMMENT 'Security Level id', + `groupId` int(10) unsigned NOT NULL COMMENT 'group id', + PRIMARY KEY (`secId`, `groupId`), + CONSTRAINT `fk__rbac_security_level_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Default groups to assign when an account is set gm level'; + +CREATE TABLE IF NOT EXISTS `rbac_account_groups` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `groupId` int(10) unsigned NOT NULL COMMENT 'Group id', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `groupId`, `realmId`), + CONSTRAINT `fk__rbac_account_groups__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_groups__rbac_groups` + FOREIGN KEY (`groupId`) REFERENCES `rbac_groups`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Group relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_roles` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `roleId` int(10) unsigned NOT NULL COMMENT 'Role id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `roleId`, `realmId`), + CONSTRAINT `fk__rbac_account_roles__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_roles` + FOREIGN KEY (`roleId`) REFERENCES `rbac_roles`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Role relation'; + +CREATE TABLE IF NOT EXISTS `rbac_account_permissions` ( + `accountId` int(10) unsigned NOT NULL COMMENT 'Account id', + `permissionId` int(10) unsigned NOT NULL COMMENT 'Permission id', + `granted` tinyint(1) NOT NULL default 1 COMMENT 'Granted = 1, Denied = 0', + `realmId` int(11) NOT NULL DEFAULT '-1' COMMENT 'Realm Id, -1 means all', + PRIMARY KEY (`accountId`, `permissionId`, `realmId`), + CONSTRAINT `fk__rbac_account_permissions__account` + FOREIGN KEY (`accountId`) REFERENCES `account`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT, + CONSTRAINT `fk__rbac_account_roles__rbac_permissions` + FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions`(`id`) + ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account-Permission relation'; + +DELETE FROM `rbac_permissions` WHERE `id` BETWEEN 1 AND 10; +INSERT INTO `rbac_permissions` (`id`, `name`) VALUES +(1, 'Instant logout'), +(2, 'Skip Queue'), +(3, 'Join Normal Battleground'), +(4, 'Join Random Battleground'), +(5, 'Join Arenas'), +(6, 'Join Dungeon Finder'), +(7, 'Player Commands (Temporal till commands moved to rbac)'), +(8, 'Moderator Commands (Temporal till commands moved to rbac)'), +(9, 'GameMaster Commands (Temporal till commands moved to rbac)'), +(10, 'Administrator Commands (Temporal till commands moved to rbac)'); + +DELETE FROM `rbac_roles` WHERE `id` BETWEEN 1 AND 7; +INSERT INTO `rbac_roles` (`id`, `name`) VALUES +(1, 'Player Commands'), +(2, 'Moderator Commands'), +(3, 'GameMaster Commands'), +(4, 'Administrator Commands'), +(5, 'Quick Login/Logout'), +(6, 'Use Battleground/Arenas'), +(7, 'Use Dungeon Finder'); + +DELETE FROM `rbac_groups` WHERE `id` BETWEEN 1 AND 4; +INSERT INTO `rbac_groups` (`id`, `name`) VALUES +(1, 'Player'), +(2, 'Moderator'), +(3, 'GameMaster'), +(4, 'Administrator'); + +DELETE FROM `rbac_role_permissions` WHERE `roleId` BETWEEN 1 AND 7; +INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES +(5, 1), +(5, 2), +(6, 3), +(6, 4), +(6, 5), +(7, 6), +(1, 7), +(2, 8), +(3, 9), +(4, 10); + +DELETE FROM `rbac_group_roles` WHERE `groupId` BETWEEN 1 AND 4; +INSERT INTO `rbac_group_roles` (`groupId`, `roleId`) VALUES +(1, 1), +(1, 6), +(1, 7), +(2, 2), +(2, 5), +(3, 3), +(4, 4); + +TRUNCATE `rbac_account_groups`; +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 1, -1 FROM `account`; -- Add Player group to all accounts +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 2, `RealmID` FROM `account_access` WHERE `gmlevel` > 0; -- Add Moderator group to all Moderator or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 3, `RealmID` FROM `account_access` WHERE `gmlevel` > 1; -- Add GameMaster group to all GameMasters or higher GM level +INSERT INTO `rbac_account_groups` (`accountId`, `groupId`, `realmId`) SELECT `id`, 4, `RealmID` FROM `account_access` WHERE `gmlevel` > 2; -- Add Administrator group to all Administrators + +TRUNCATE `rbac_security_level_groups`; +INSERT INTO `rbac_security_level_groups` (`secId`, `groupId`) VALUES +(0, 1), +(1, 1), +(1, 2), +(2, 1), +(2, 2), +(2, 3), +(3, 1), +(3, 2), +(3, 3), +(3, 4); diff --git a/sql/updates/world/2013_02_04_03_world_misc.sql b/sql/updates/world/2013_02_04_03_world_misc.sql new file mode 100644 index 00000000000..a609d411b6e --- /dev/null +++ b/sql/updates/world/2013_02_04_03_world_misc.sql @@ -0,0 +1,53 @@ +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 63 AND 95; +INSERT INTO trinity_string (entry, content_default) VALUES +(63, "Wrong parameter id: %u, does not exist"), +(64, "Wrong parameter realmId: %d"), +(65, "Couldn't add group %u (%s) realmId %d. Account %u (%s) already has that group"), +(66, "Couldn't remove group %u (%s) realmId %d. Account %u (%s) does not have that group"), +(67, "Added group %u (%s) realmId %d to account %u (%s)"), +(68, "Removed group %u (%s) realmId %d from account %u (%s)"), +(69, "Account %u (%s) groups:"), +(70, "Empty List"), +(71, "- %u (%s)"), +(72, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) already has that role"), +(73, "Couldn't grant role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(74, "Granted role %u (%s) realmId %d to account %u (%s)"), +(75, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) already has that role"), +(76, "Couldn't deny role %u (%s) realmId %d. Account %u (%s) has that role in deny list"), +(77, "Denied role %u (%s) realmId %d to account %u (%s)"), +(78, "Denied role %u (%s) realmId %d to account %u (%s)"), +(79, "Couldn't revoke role %u (%s) realmId %d. Account %u (%s) does not have that role"), +(80, "Account %u (%s) granted roles:"), +(81, "Account %u (%s) denied roles:"), +(82, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(83, "Couldn't grant permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(84, "Granted permission %u (%s) realmId %d to account %u (%s)"), +(85, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) already has that permission"), +(86, "Couldn't deny permission %u (%s) realmId %d. Account %u (%s) has that permission in deny list"), +(87, "Denied permission %u (%s) realmId %d to account %u (%s)"), +(88, "Revoked permission %u (%s) realmId %d to account %u (%s)"), +(89, "Couldn't revoke permission %u (%s) realmId %d. Account %u (%s) does not have that permission"), +(90, "Account %u (%s) granted permissions:"), +(91, "Account %u (%s) denied permissions:"), +(92, "Account %u (%s) global permissions:"), +(93, "Groups:"), +(94, "Roles:"), +(95, "Permissions:"); + +DELETE FROM `command` WHERE `name` LIKE '.rbac%'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('.rbac account', 3, 'Syntax: .rbac account [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\n\nNote: Shows real permissions after checking group and roles'), +('.rbac account group', 3, 'Syntax: .rbac account group [$account]\n\nView groups of selected player or given account\nNote: Only those that affect current realm'), +('.rbac account group add', 3, 'Syntax: .rbac account group add [$account] #id [#realmId]\n\nAdd a group to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account group remove', 3, 'Syntax: .rbac account group remove [$account] #id\n\nRemove a group from selected player or given account.'), +('.rbac account role', 3, 'Syntax: .rbac account role [$account]\n\nView roles of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited roles from groups'), +('.rbac account role grant', 3, 'Syntax: .rbac account role grant [$account] #id [#realmId]\n\nGrant a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role deny', 3, 'Syntax: .rbac account role deny [$account] #id [#realmId]\n\nDeny a role to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account role revoke', 3, 'Syntax: .rbac account role revoke [$account] #id\n\nRemove a role from an account\n\nNote: Removes the role from granted or denied roles'), +('.rbac account permission', 3, 'Syntax: .rbac account permission [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm\nNote: Only those directly granted or denied, does not include inherited permissions from roles'), +('.rbac account permission grant', 3, 'Syntax: .rbac account permission grant [$account] #id [#realmId]\n\nGrant a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission deny', 3, 'Syntax: .rbac account permission deny [$account] #id [#realmId]\n\nDeny a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'), +('.rbac account permission revoke', 3, 'Syntax: .rbac account permission revoke [$account] #id\n\nRemove a permission from an account\n\nNote: Removes the permission from granted or denied permissions'), +('.rbac list groups', 3, 'Syntax: .rbac list groups [$id]\n\nView list of all groups. If $id is given will show group info and his inherited roles.'), +('.rbac list roles', 3, 'Syntax: .rbac list roles [$id]\n\nView list of all roles. If $id is given will show role info and his inherited permissions.'), +('.rbac list permissions', 3, 'Syntax: .rbac list permissions [$id]\n\nView list of all permissions. If $id is given will show only info for that permission.'); diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 7121a031ec2..6c5cb5622b3 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -314,10 +314,10 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c class EventMap { /** - * Internal storage type. + * Internal storage type. * Key: Time as uint32 when the event should occur. - * Value: The event data as uint32. - * + * Value: The event data as uint32. + * * Structure of event data: * - Bit 0 - 15: Event Id. * - Bit 16 - 23: Group @@ -454,7 +454,7 @@ class EventMap { if (Empty()) return; - + uint32 eventId = _eventMap.begin()->second; _eventMap.erase(_eventMap.begin()); ScheduleEvent(eventId, time); @@ -480,7 +480,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) @@ -492,7 +492,7 @@ class EventMap return eventId; } } - + return 0; } @@ -506,7 +506,7 @@ class EventMap while (!Empty()) { EventStore::iterator itr = _eventMap.begin(); - + if (itr->first > _time) return 0; else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) @@ -514,7 +514,7 @@ class EventMap else return (itr->second & 0x0000FFFF); } - + return 0; } @@ -538,7 +538,7 @@ class EventMap { if (!group || group > 8 || Empty()) return; - + EventStore delayed; for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) @@ -551,7 +551,7 @@ class EventMap else ++itr; } - + _eventMap.insert(delayed.begin(), delayed.end()); } @@ -578,7 +578,7 @@ class EventMap * @name CancelEventGroup * @brief Cancel events belonging to specified group. * @param group Group to cancel. - */ + */ void CancelEventGroup(uint32 group) { if (!group || group > 8 || Empty()) @@ -610,7 +610,7 @@ class EventMap return 0; } - + /** * @name GetNextEventTime * @return Time of next event. @@ -636,14 +636,14 @@ class EventMap * @name _time * @brief Internal timer. * - * This does not represent the real date/time value. + * This does not represent the real date/time value. * It's more like a stopwatch: It can run, it can be stopped, * it can be resetted and so on. Events occur when this timer * has reached their time value. Its value is changed in the * Update method. */ uint32 _time; - + /** * @name _phase * @brief Phase mask of the event map. @@ -653,7 +653,7 @@ class EventMap * AddPhase. RemovePhase deactives a phase. */ uint8 _phase; - + /** * @name _eventMap * @brief Internal event storage map. Contains the scheduled events. diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 3c3eded1f68..ce382342de8 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -17,6 +17,7 @@ */ #include "AccountMgr.h" +#include "Config.h" #include "DatabaseEnv.h" #include "ObjectAccessor.h" #include "Player.h" @@ -26,6 +27,7 @@ AccountMgr::AccountMgr() { + } AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) @@ -44,12 +46,22 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass stmt->setString(0, username); stmt->setString(1, CalculateShaPassHash(username, password)); - LoginDatabase.Execute(stmt); + LoginDatabase.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT); LoginDatabase.Execute(stmt); + // Add default rbac groups for that security level + RBACData* rbac = new RBACData(GetId(username), username, -1); + // No need to Load From DB, as it's new data + + RBACGroupContainer const& groupsToAdd = _defaultGroups[0]; // 0: Default sec level + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, -1); + + delete rbac; + return AOR_OK; // everything's fine } @@ -303,3 +315,206 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel) { return gmlevel == SEC_CONSOLE; } + +void AccountMgr::LoadRBAC() +{ + uint32 oldMSTime = getMSTime(); + uint32 count1 = 0; + uint32 count2 = 0; + uint32 count3 = 0; + + QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account permission definitions. DB table `rbac_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _permissions[id] = new RBACPermission(id, field[1].GetString()); + ++count1; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role definitions. DB table `rbac_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _roles[id] = new RBACRole(id, field[1].GetString()); + ++count2; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account role-permission definitions. DB table `rbac_role_permissions` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACRole* role = _roles[id]; + role->GrantPermission(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group definitions. DB table `rbac_groups` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + _groups[id] = new RBACGroup(id, field[1].GetString()); + ++count3; + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account group-role definitions. DB table `rbac_group_roles` is empty."); + return; + } + + do + { + Field* field = result->Fetch(); + uint32 id = field[0].GetUInt32(); + RBACGroup* group = _groups[id]; + group->GrantRole(field[1].GetUInt32()); + } + while (result->NextRow()); + + result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC"); + if (!result) + { + sLog->outInfo(LOG_FILTER_SQL, ">> Loaded 0 account default groups for security levels definitions. DB table `rbac_security_level_groups` is empty."); + return; + } + + uint8 lastSecId = 255; + RBACGroupContainer* groups = NULL; + do + { + Field* field = result->Fetch(); + uint8 secId = field[0].GetUInt8(); + + if (lastSecId != secId) + groups = &_defaultGroups[secId]; + + groups->insert(field[1].GetUInt32()); + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime)); +} + +void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) +{ + int32 serverRealmId = realmId != -1 ? realmId : ConfigMgr::GetIntDefault("RealmID", 0); + bool needDelete = false; + if (!rbac) + { + needDelete = true; + rbac = new RBACData(accountId, "", serverRealmId); + rbac->LoadFromDB(); + } + + // Get max security level and realm (checking current realm and -1) + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID); + stmt->setUInt32(0, accountId); + stmt->setInt32(1, serverRealmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* field = result->Fetch(); + uint8 secLevel = field[0].GetUInt8(); + int32 realmId = field[1].GetUInt32(); + + RBACGroupContainer const& groupsToRemove = _defaultGroups[secLevel]; + for (RBACGroupContainer::const_iterator it = groupsToRemove.begin(); it != groupsToRemove.end(); ++it) + rbac->RemoveGroup(*it, realmId); + } + while (result->NextRow()); + } + + // Add new groups depending on the new security Level + RBACGroupContainer const& groupsToAdd = _defaultGroups[securityLevel]; + for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it) + rbac->AddGroup(*it, realmId); + + if (needDelete) + delete rbac; + + // Delete old security level from DB + if (realmId == -1) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + LoginDatabase.Execute(stmt); + } + else + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); + stmt->setUInt32(0, accountId); + stmt->setUInt32(1, realmId); + LoginDatabase.Execute(stmt); + } + + // Add new security level + if (securityLevel) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); + stmt->setUInt32(0, accountId); + stmt->setUInt8(1, securityLevel); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + } +} + +RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const +{ + RBACGroupsContainer::const_iterator it = _groups.find(group); + if (it != _groups.end()) + return it->second; + + return NULL; +} + +RBACRole const* AccountMgr::GetRBACRole(uint32 role) const +{ + RBACRolesContainer::const_iterator it = _roles.find(role); + if (it != _roles.end()) + return it->second; + + return NULL; +} + +RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const +{ + RBACPermissionsContainer::const_iterator it = _permissions.find(permission); + if (it != _permissions.end()) + return it->second; + + return NULL; +} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index c8de5688e73..90c533ca5fa 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -19,8 +19,7 @@ #ifndef _ACCMGR_H #define _ACCMGR_H -#include "Define.h" -#include +#include "RBAC.h" #include enum AccountOpResult @@ -35,6 +34,11 @@ enum AccountOpResult #define MAX_ACCOUNT_STR 16 +typedef std::map RBACPermissionsContainer; +typedef std::map RBACRolesContainer; +typedef std::map RBACGroupsContainer; +typedef std::map RBACDefaultSecurityGroupContainer; + class AccountMgr { friend class ACE_Singleton; @@ -43,7 +47,7 @@ class AccountMgr AccountMgr(); public: - static AccountOpResult CreateAccount(std::string username, std::string password); + AccountOpResult CreateAccount(std::string username, std::string password); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); @@ -62,6 +66,23 @@ class AccountMgr static bool IsGMAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); static bool IsConsoleAccount(uint32 gmlevel); + + void UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); + + void LoadRBAC(); + RBACGroup const* GetRBACGroup(uint32 group) const; + RBACRole const* GetRBACRole(uint32 role) const; + RBACPermission const* GetRBACPermission(uint32 permission) const; + + RBACGroupsContainer const& GetRBACGroupList() const { return _groups; } + RBACRolesContainer const& GetRBACRoleList() const { return _roles; } + RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } + + private: + RBACPermissionsContainer _permissions; + RBACRolesContainer _roles; + RBACGroupsContainer _groups; + RBACDefaultSecurityGroupContainer _defaultGroups; }; #define sAccountMgr ACE_Singleton::instance() diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 0bf7c8591e3..b8f80fb36ac 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -122,8 +122,27 @@ const char *ChatHandler::GetTrinityString(int32 entry) const bool ChatHandler::isAvailable(ChatCommand const& cmd) const { - // check security level only for simple command (without child commands) - return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel); + uint32 permission = 0; + + ///@Workaround:: Fast adaptation to RBAC system till all commands are moved to permissions + switch (AccountTypes(cmd.SecurityLevel)) + { + case SEC_ADMINISTRATOR: + permission = RBAC_PERM_ADMINISTRATOR_COMMANDS; + break; + case SEC_GAMEMASTER: + permission = RBAC_PERM_GAMEMASTER_COMMANDS; + break; + case SEC_MODERATOR: + permission = RBAC_PERM_MODERATOR_COMMANDS; + break; + case SEC_PLAYER: + default: + permission = RBAC_PERM_PLAYER_COMMANDS; + break; + } + + return m_session->HasPermission(permission); } bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong) @@ -431,7 +450,7 @@ bool ChatHandler::ParseCommands(char const* text) std::string fullcmd = text; - if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS)) + if (m_session && !m_session->HasPermission(RBAC_PERM_PLAYER_COMMANDS)) return false; /// chat case (.command or !command format) diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index d9d4a897eed..e18a103e21c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -379,6 +379,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) uint8 expansion = player->GetSession()->Expansion(); LfgDungeonSet const& dungeons = GetDungeonsByRandom(0); LfgLockMap lock; + bool denyJoin = !player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER); for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) { @@ -387,7 +388,9 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) continue; uint32 lockData = 0; - if (dungeon->expansion > expansion) + if (denyJoin) + lockData = LFG_LOCKSTATUS_RAID_LOCKED; + else if (dungeon->expansion > expansion) lockData = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player)) lockData = LFG_LOCKSTATUS_RAID_LOCKED; @@ -469,7 +472,9 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const } // Check player or group member restrictions - if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) + if (!player->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_NOT_MEET_REQS; + else if (player->InBattleground() || player->InArena() || player->InBattlegroundQueue()) joinData.result = LFG_JOIN_USING_BG_SYSTEM; else if (player->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_DESERTER; @@ -488,6 +493,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { if (Player* plrg = itr->getSource()) { + if (!plrg->GetSession()->HasPermission(RBAC_PERM_JOIN_DUNGEON_FINDER)) + joinData.result = LFG_JOIN_PARTY_NOT_MEET_REQS; if (plrg->HasAura(LFG_SPELL_DUNGEON_DESERTER)) joinData.result = LFG_JOIN_PARTY_DESERTER; else if (plrg->HasAura(LFG_SPELL_DUNGEON_COOLDOWN)) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index da7980647bb..07c4281f86f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -343,7 +343,7 @@ class LFGMgr uint32 GetOptions(); // cs_lfg /// Sets new lfg options void SetOptions(uint32 options); - /// Checks if given lfg option is enabled + /// Checks if given lfg option is enabled bool isOptionEnabled(uint32 option); /// Clears queue - Only for internal testing void Clean(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a4356f55340..dc98facc5ab 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21757,12 +21757,21 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) } } -bool Player::CanJoinToBattleground(Battleground const* /*bg*/) const +bool Player::CanJoinToBattleground(Battleground const* bg) const { // check Deserter debuff if (HasAura(26013)) return false; + if (bg->isArena() && !GetSession()->HasPermission(RBAC_PERM_JOIN_ARENAS)) + return false; + + if (bg->IsRandom() && !GetSession()->HasPermission(RBAC_PERM_JOIN_RANDOM_BG)) + return false; + + if (!GetSession()->HasPermission(RBAC_PERM_JOIN_NORMAL_BG)) + return false; + return true; } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index aa4c9f35085..6272f42ec8c 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -396,7 +396,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() || - GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))) + HasPermission(RBAC_PERM_INSTANT_LOGOUT)) { WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); data << uint8(0); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index e13cc86747c..5868b60b722 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -86,7 +86,40 @@ enum TrinityStrings LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, LANG_IMPROPER_VALUE = 62, - // Room for more level 0 63-99 not used + LANG_RBAC_WRONG_PARAMETER_ID = 63, + LANG_RBAC_WRONG_PARAMETER_REALM = 64, + LANG_RBAC_GROUP_IN_LIST = 65, + LANG_RBAC_GROUP_NOT_IN_LIST = 66, + LANG_RBAC_GROUP_ADDED = 67, + LANG_RBAC_GROUP_REMOVED = 68, + LANG_RBAC_GROUP_LIST_HEADER = 69, + LANG_RBAC_LIST_EMPTY = 70, + LANG_RBAC_LIST_ELEMENT = 71, + LANG_RBAC_ROLE_GRANTED_IN_LIST = 72, + LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST = 73, + LANG_RBAC_ROLE_GRANTED = 74, + LANG_RBAC_ROLE_DENIED_IN_LIST = 75, + LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST = 76, + LANG_RBAC_ROLE_DENIED = 77, + LANG_RBAC_ROLE_REVOKED = 78, + LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST = 79, + LANG_RBAC_ROLE_LIST_HEADER_GRANTED = 80, + LANG_RBAC_ROLE_LIST_HEADER_DENIED = 81, + LANG_RBAC_PERM_GRANTED_IN_LIST = 82, + LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 83, + LANG_RBAC_PERM_GRANTED = 84, + LANG_RBAC_PERM_DENIED_IN_LIST = 85, + LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 86, + LANG_RBAC_PERM_DENIED = 87, + LANG_RBAC_PERM_REVOKED = 88, + LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 89, + LANG_RBAC_PERM_LIST_HEADER_GRANTED = 90, + LANG_RBAC_PERM_LIST_HEADER_DENIED = 91, + LANG_RBAC_PERM_LIST_GLOBAL = 92, + LANG_RBAC_LIST_GROUPS_HEADER = 93, + LANG_RBAC_LIST_ROLES_HEADER = 94, + LANG_RBAC_LIST_PERMISSIONS_HEADER = 95, + // Room for more level 0 96-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index efd45188d42..afc153a5000 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -70,6 +70,7 @@ void AddSC_mmaps_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); +void AddSC_rbac_commandscript(); void AddSC_reload_commandscript(); void AddSC_reset_commandscript(); void AddSC_server_commandscript(); @@ -700,6 +701,7 @@ void AddCommandScripts() AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); + AddSC_rbac_commandscript(); AddSC_reload_commandscript(); AddSC_reset_commandscript(); AddSC_server_commandscript(); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 6c689319bc7..522dc95105d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -21,6 +21,7 @@ */ #include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it +#include "Config.h" #include "Common.h" #include "DatabaseEnv.h" #include "Log.h" @@ -115,7 +116,8 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 m_TutorialsChanged(false), recruiterId(recruiter), isRecruiter(isARecruiter), - timeLastWhoCommand(0) + timeLastWhoCommand(0), + _RBACData(NULL) { if (sock) { @@ -143,8 +145,8 @@ WorldSession::~WorldSession() m_Socket = NULL; } - if (_warden) - delete _warden; + delete _warden; + delete _RBACData; ///- empty incoming packet queue WorldPacket* packet = NULL; @@ -1200,3 +1202,24 @@ void WorldSession::InitWarden(BigNumber* k, std::string const& os) // _warden->Init(this, k); } } + +void WorldSession::LoadPermissions() +{ + uint32 id = GetAccountId(); + std::string name; + int32 realmId = ConfigMgr::GetIntDefault("RealmID", 0); + AccountMgr::GetName(id, name); + + _RBACData = new RBACData(id, name, realmId); + _RBACData->LoadFromDB(); +} + +RBACData* WorldSession::GetRBACData() +{ + return _RBACData; +} + +bool WorldSession::HasPermission(uint32 permission) +{ + return _RBACData->HasPermission(permission); +} diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 11bb7a36f5a..d6877b8a18a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,6 +24,7 @@ #define __WORLDSESSION_H #include "Common.h" +#include "AccountMgr.h" #include "SharedDefines.h" #include "AddonMgr.h" #include "DatabaseEnv.h" @@ -216,6 +217,10 @@ class WorldSession void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); + RBACData* GetRBACData(); + bool HasPermission(uint32 permissionId); + void LoadPermissions(); + AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } Player* GetPlayer() const { return _player; } @@ -954,6 +959,7 @@ class WorldSession bool isRecruiter; ACE_Based::LockedQueue _recvQueue; time_t timeLastWhoCommand; + RBACData* _RBACData; }; #endif /// @} diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index c80d25be139..c77cad70186 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -953,6 +953,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) m_Session->LoadGlobalAccountData(); m_Session->LoadTutorialsData(); m_Session->ReadAddonsInfo(recvPacket); + m_Session->LoadPermissions(); // Initialize Warden system only if it is enabled by config if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index f28b9548e5f..d02ba402c53 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -267,7 +267,7 @@ void World::AddSession_(WorldSession* s) if (decrease_session) --Sessions; - if (pLimit > 0 && Sessions >= pLimit && AccountMgr::IsPlayerAccount(s->GetSecurity()) && !HasRecentlyDisconnected(s)) + if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s)) { AddQueuedPlayer(s); UpdateMaxSessionCounters(); @@ -585,7 +585,6 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_TICKET_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Ticket", 1); m_int_configs[CONFIG_AUCTION_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Auction", 1); m_int_configs[CONFIG_MAIL_LEVEL_REQ] = ConfigMgr::GetIntDefault("LevelReq.Mail", 1); - m_bool_configs[CONFIG_ALLOW_PLAYER_COMMANDS] = ConfigMgr::GetBoolDefault("AllowPlayerCommands", 1); m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = ConfigMgr::GetBoolDefault("PreserveCustomChannels", false); m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = ConfigMgr::GetIntDefault("PreserveCustomChannelDuration", 14); m_bool_configs[CONFIG_GRID_UNLOAD] = ConfigMgr::GetBoolDefault("GridUnload", true); @@ -1059,8 +1058,6 @@ void World::LoadConfigSettings(bool reload) sLog->outError(LOG_FILTER_SERVER_LOADING, "ClientCacheVersion can't be negative %d, ignored.", clientCacheId); } - m_int_configs[CONFIG_INSTANT_LOGOUT] = ConfigMgr::GetIntDefault("InstantLogout", SEC_MODERATOR); - m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = ConfigMgr::GetIntDefault("Guild.EventLogRecordsCount", GUILD_EVENTLOG_MAX_RECORDS); if (m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] > GUILD_EVENTLOG_MAX_RECORDS) m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = GUILD_EVENTLOG_MAX_RECORDS; @@ -1348,6 +1345,8 @@ void World::SetInitialWorldSettings() sObjectMgr->SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Localization strings loaded in %u ms", GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Account Roles and Permissions..."); + sAccountMgr->LoadRBAC(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Page Texts..."); sObjectMgr->LoadPageTexts(); diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 7b9e2444952..83e97b2c80d 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -35,6 +35,7 @@ set(scripts_STAT_SRCS Commands/cs_modify.cpp Commands/cs_npc.cpp Commands/cs_quest.cpp + Commands/cs_rbac.cpp Commands/cs_reload.cpp Commands/cs_reset.cpp Commands/cs_tele.cpp diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 3a20a03bb4a..4dc44bbfc58 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -106,7 +106,7 @@ public: if (!accountName || !password) return false; - AccountOpResult result = AccountMgr::CreateAccount(std::string(accountName), std::string(password)); + AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password)); switch (result) { case AOR_OK: @@ -503,36 +503,8 @@ public: return false; } - // If gmRealmID is -1, delete all values for the account id, else, insert values for the specific realmID - PreparedStatement* stmt; - - if (gmRealmID == -1) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - } - else - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt32(1, realmID); - } - - LoginDatabase.Execute(stmt); - - if (gm != 0) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS); - - stmt->setUInt32(0, targetAccountId); - stmt->setUInt8(1, uint8(gm)); - stmt->setInt32(2, gmRealmID); - - LoginDatabase.Execute(stmt); - } - + RBACData* rbac = isAccountNameGiven ? NULL : handler->getSelectedPlayer()->GetSession()->GetRBACData(); + sAccountMgr->UpdateAccountAccess(rbac, targetAccountId, uint8(gm), gmRealmID); handler->PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); return true; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 227680b2d6b..210e2b3ac60 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -55,7 +55,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); @@ -87,4 +87,18 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS, "SELECT groupId FROM rbac_account_groups WHERE accountId = ? AND (realmId = ? OR realmId = -1) GROUP BY groupId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP, "INSERT INTO rbac_account_groups (accountId, groupId, realmId) VALUES (?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP, "DELETE FROM rbac_account_groups WHERE accountId = ? AND groupId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES, "SELECT roleId, granted FROM rbac_account_roles WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY roleId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE, "INSERT INTO rbac_account_roles (accountId, roleId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE, "DELETE FROM rbac_account_roles WHERE accountId = ? AND roleId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); + + PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH); + PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); + PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 798016d553d..211706b26b8 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -108,6 +108,16 @@ enum LoginDatabaseStatements LOGIN_SEL_REALMLIST_SECURITY_LEVEL, LOGIN_DEL_ACCOUNT, + LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, + LOGIN_SEL_RBAC_ACCOUNT_GROUPS, + LOGIN_INS_RBAC_ACCOUNT_GROUP, + LOGIN_DEL_RBAC_ACCOUNT_GROUP, + LOGIN_SEL_RBAC_ACCOUNT_ROLES, + LOGIN_INS_RBAC_ACCOUNT_ROLE, + LOGIN_DEL_RBAC_ACCOUNT_ROLE, + LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, + LOGIN_INS_RBAC_ACCOUNT_PERMISSION, + LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 641fe1ebb62..f6a09667dda 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -813,18 +813,6 @@ RecruitAFriend.MaxLevel = 60 RecruitAFriend.MaxDifference = 4 -# -# InstantLogout -# Description: Required security level for instantly logging out everywhere. -# Does not work while in combat, dueling or falling. -# Default: 1 - (Enabled, Mods/GMs/Admins) -# 0 - (Enabled, Everyone) -# 2 - (Enabled, GMs/Admins) -# 3 - (Enabled, Admins) -# 4 - (Disabled) - -InstantLogout = 1 - # # DisableWaterBreath # Description: Required security level for water breathing. @@ -1567,14 +1555,6 @@ ChatLevelReq.Whisper = 1 ChatLevelReq.Say = 1 -# -# AllowPlayerCommands -# Description: Allow players to use commands. -# Default: 1 - (Enabled) -# 0 - (Disabled) - -AllowPlayerCommands = 1 - # # PreserveCustomChannels # Description: Store custom chat channel settings like password, automatic ownership handout -- cgit v1.2.3 From 683de1d62484d1c9c5396a7c41507f03116509aa Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 09:39:01 +0100 Subject: Core/RBAC: Add SQL to remove bad data from account_access, otherwise other sqls will fail due to use of FOREIGN KEYS - Also add missing files from previous commit --- sql/updates/auth/2013_02_04_00_auth_misc.sql | 5 +- src/server/game/Accounts/RBAC.cpp | 334 ++++++++++++ src/server/game/Accounts/RBAC.h | 410 ++++++++++++++ src/server/scripts/Commands/cs_rbac.cpp | 780 +++++++++++++++++++++++++++ 4 files changed, 1528 insertions(+), 1 deletion(-) create mode 100644 src/server/game/Accounts/RBAC.cpp create mode 100644 src/server/game/Accounts/RBAC.h create mode 100644 src/server/scripts/Commands/cs_rbac.cpp (limited to 'src') diff --git a/sql/updates/auth/2013_02_04_00_auth_misc.sql b/sql/updates/auth/2013_02_04_00_auth_misc.sql index 573b58ac156..815df637be0 100644 --- a/sql/updates/auth/2013_02_04_00_auth_misc.sql +++ b/sql/updates/auth/2013_02_04_00_auth_misc.sql @@ -1,13 +1,16 @@ +-- Delete bad data from the DB before adding foreign keys +DELETE FROM `account_access` WHERE `id` NOT IN (SELECT `id` FROM `account`); + -- Need them first in case of re-execute due to foreign keys DROP TABLE IF EXISTS `rbac_account_permissions`; DROP TABLE IF EXISTS `rbac_account_roles`; DROP TABLE IF EXISTS `rbac_account_groups`; DROP TABLE IF EXISTS `rbac_role_permissions`; DROP TABLE IF EXISTS `rbac_group_roles`; +DROP TABLE IF EXISTS `rbac_security_level_groups`; DROP TABLE IF EXISTS `rbac_permissions`; DROP TABLE IF EXISTS `rbac_roles`; DROP TABLE IF EXISTS `rbac_groups`; -DROP TABLE IF EXISTS `rbac_security_level_groups`; CREATE TABLE IF NOT EXISTS `rbac_groups` ( `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Group id', diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp new file mode 100644 index 00000000000..0b08e277fb2 --- /dev/null +++ b/src/server/game/Accounts/RBAC.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +#include "RBAC.h" + +RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) +{ + // Check if group Id exists + RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId); + if (!group) + return RBAC_ID_DOES_NOT_EXISTS; + + // Already added? + std::pair::iterator, bool> ret = _groups.insert(groupId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, groupId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */) +{ + // could remove it? + if (!_groups.erase(groupId)) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, groupId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/) +{ + // Check if role Id exists + RBACRole const* role = sAccountMgr->GetRBACRole(roleId); + if (!role) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in denied list + if (_deniedRoles.find(roleId) != _deniedRoles.end()) + return RBAC_IN_DENIED_LIST; + + // Already added? + std::pair::iterator, bool> ret = _grantedRoles.insert(roleId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SaveRole(roleId, true, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/) +{ + // Check if role Id exists + RBACRole const* role = sAccountMgr->GetRBACRole(roleId); + if (!role) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in granted list + if (_grantedRoles.find(roleId) != _grantedRoles.end()) + return RBAC_IN_GRANTED_LIST; + + // Already added? + std::pair::iterator, bool> ret = _deniedRoles.insert(roleId); + if (!ret.second) + return RBAC_CANT_ADD_ALREADY_ADDED; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SaveRole(roleId, false, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::SaveRole(uint32 roleId, bool granted, int32 realmId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, roleId); + stmt->setBool(2, granted); + stmt->setInt32(3, realmId); + LoginDatabase.Execute(stmt); +} + +RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/) +{ + uint8 revoked = _grantedRoles.erase(roleId) + _deniedRoles.erase(roleId); + + // could remove it? + if (!revoked) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, roleId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in denied list + if (_deniedPerms.test(permissionId)) + return RBAC_IN_DENIED_LIST; + + // Already added? + if (_grantedPerms.test(permissionId)) + return RBAC_CANT_ADD_ALREADY_ADDED; + + _grantedPerms.set(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SavePermission(permissionId, true, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + return RBAC_ID_DOES_NOT_EXISTS; + + // Check if already added in granted list + if (_grantedPerms.test(permissionId)) + return RBAC_IN_GRANTED_LIST; + + // Already added? + if (_deniedPerms.test(permissionId)) + return RBAC_CANT_ADD_ALREADY_ADDED; + + _deniedPerms.set(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + SavePermission(permissionId, false, realmId); + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permission); + stmt->setBool(2, granted); + stmt->setInt32(3, realmId); + LoginDatabase.Execute(stmt); +} + +RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/) +{ + // Check if it's present in any list + if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission)) + return RBAC_CANT_REVOKE_NOT_IN_LIST; + + _grantedPerms.reset(permission); + _deniedPerms.reset(permission); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permission); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + + return RBAC_OK; +} + +void RBACData::LoadFromDB() +{ + // Load account group that affect current realm + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + AddGroup(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Load account roles (granted and denied) that affect current realm + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + result = LoginDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + if (fields[1].GetBool()) + GrantRole(fields[0].GetUInt32()); + else + DenyRole(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Load account permissions (granted and denied) that affect current realm + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + + result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* fields = result->Fetch(); + if (fields[1].GetBool()) + GrantPermission(fields[0].GetUInt32()); + else + DenyPermission(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Force calculation of permissions, it wasn't performed at load time + // while adding groups, roles and permissions + CalculateNewPermissions(); +} + +void RBACData::CalculateNewPermissions() +{ + // Get the list of directly granted roles + RBACRoleContainer tempGrantedRoles = GetGrantedRoles(); + + // Add those roles inherited from groups + for (RBACGroupContainer::const_iterator itGroup = _groups.begin(); itGroup != _groups.end(); ++itGroup) + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(*itGroup); + if (!group) // Should never happen due to foreign keys in DB + continue; + + RBACRoleContainer const& roles = group->GetRoles(); + for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + tempGrantedRoles.insert(*it); + } + + // Get the list of granted permissions + _globalPerms = GetGrantedPermissions(); + + // Add those permissions inherited from roles granted + for (RBACRoleContainer::const_iterator it = tempGrantedRoles.begin(); it != tempGrantedRoles.end(); ++it) + if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) + _globalPerms |= role->GetPermissions(); + + // Remove denied permissions from the list + _globalPerms &= ~GetDeniedPermissions(); + + // Remove those permissions inherited from denied roles + for (RBACRoleContainer::const_iterator it = _deniedRoles.begin(); it != _deniedRoles.end(); ++it) + if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) + _globalPerms &= ~role->GetPermissions(); +} diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h new file mode 100644 index 00000000000..5420df29d17 --- /dev/null +++ b/src/server/game/Accounts/RBAC.h @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +/** +* @file RBAC.h +* @brief Role Based Access Control related classes definition +* +* This file contains all the classes and enums used to implement +* Role Based Access Control +* +* RBAC Rules: +* - Pemission: Defines an autorization to perform certain operation. +* - Role: Set of permissions. +* - Group: Set of roles. +* - An Account can have multiple groups, roles and permissions. +* - Account Groups can only be granted or revoked +* - Account Roles and Permissions can be granted, denied or revoked +* - Grant: Assignment of the object (role/permission) and allow it +* - Deny: Assignment of the object (role/permission) and deny it +* - Revoke: Removal of the object (role/permission) no matter if it was granted or denied +* - Global Permissions are computed as: +* Group Grants + Role Grants + User Grans - Role Grants - User Grants +* - Groups, Roles and Permissions can be assigned by realm +*/ + +#ifndef _RBAC_H +#define _RBAC_H + +#include "Define.h" +#include +#include +#include +#include + +enum RBACPermissions +{ + RBAC_PERM_INSTANT_LOGOUT = 1, + RBAC_PERM_SKIP_QUEUE, + RBAC_PERM_JOIN_NORMAL_BG, + RBAC_PERM_JOIN_RANDOM_BG, + RBAC_PERM_JOIN_ARENAS, + RBAC_PERM_JOIN_DUNGEON_FINDER, + RBAC_PERM_PLAYER_COMMANDS, + RBAC_PERM_MODERATOR_COMMANDS, + RBAC_PERM_GAMEMASTER_COMMANDS, + RBAC_PERM_ADMINISTRATOR_COMMANDS, + RBAC_PERM_MAX +}; + +enum RBACCommandResult +{ + RBAC_OK, + RBAC_CANT_ADD_ALREADY_ADDED, + RBAC_CANT_REVOKE_NOT_IN_LIST, + RBAC_IN_GRANTED_LIST, + RBAC_IN_DENIED_LIST, + RBAC_ID_DOES_NOT_EXISTS +}; + +typedef std::bitset RBACPermissionContainer; +typedef std::set RBACRoleContainer; +typedef std::set RBACGroupContainer; + +class RBACObject +{ + public: + RBACObject(uint32 id = 0, std::string const& name = ""): + _id(id), _name(name) { } + + /// Gets the Name of the Object + std::string const& GetName() const { return _name; } + /// Gets the Id of the Object + uint32 GetId() const { return _id; } + + private: + uint32 _id; ///> id of the object + std::string _name; ///> name of the object +}; + +/// Permission: Defines an autorization to perform certain operation +class RBACPermission: public RBACObject +{ + public: + RBACPermission(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } +}; + +/// Set of Permissions +class RBACRole: public RBACObject +{ + public: + RBACRole(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } + + /// Gets the Permissions assigned to this role + RBACPermissionContainer const& GetPermissions() const { return _perms; } + /// Grants a Permission (Adds) + void GrantPermission(uint32 id) { _perms.set(id); } + /// Revokes a Permission (Removes) + void RevokePermission(uint32 id) { _perms.reset(id); } + + private: + RBACPermissionContainer _perms; ///> Set of permissions +}; + +/// Set of Roles +class RBACGroup: public RBACObject +{ + public: + RBACGroup(uint32 id = 0, std::string const& name = ""): + RBACObject(id, name) { } + + /// Gets the Roles assigned to this group + RBACRoleContainer const& GetRoles() const { return _roles; } + /// Grants a Role (Adds) + void GrantRole(uint32 role) { _roles.insert(role); } + /// Revokes a Role (Removes) + void RevokeRole(uint32 role) { _roles.erase(role); } + + private: + RBACRoleContainer _roles; ///> Set of Roles +}; + +/* + * @name RBACData + * @brief Contains all needed information about the acccount + * + * This class contains all the data needed to calculate the account permissions. + * RBACDAta is formed by group permissions and user permissions through: + * - Granted Groups, which contains roles, which contains permissions: Set of granted permissions + * - Granted Roles, which contains permissions: Set of granted permissions + * - Denied Roles, which contains permissions: Set of denied permissions + * - Granted Permissions + * - Denied Permissions + * + * Calculation of current Permissions: Granted permissions - Denied permissions + * - Granted permissions: through groups, through roles and directly assigned + * - Denied permissions: through roles and directly assigned + */ +class RBACData: public RBACObject +{ + public: + RBACData(uint32 id, std::string const& name, int32 realmId): + RBACObject(id, name), _realmId(realmId) { } + + /** + * @name HasPermission + * @brief Checks if certain action is allowed + * + * Checks if certain action can be performed. + * + * @return grant or deny action + * + * Example Usage: + * @code + * bool Player::CanJoinArena(Battleground* bg) + * { + * return bg->isArena() && HasPermission(RBAC_PERM_JOIN_ARENA); + * } + * @endcode + */ + bool HasPermission(uint32 permission) { return _globalPerms.test(permission); } + + // Functions enabled to be used by command system + /// Returns all the granted permissions (after computation) + RBACPermissionContainer const& GetPermissions() const { return _globalPerms; } + /// Returns all the granted permissions + RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; } + /// Returns all the denied permissions + RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; } + /// Returns all the granted roles + RBACRoleContainer const& GetGrantedRoles() const { return _grantedRoles; } + /// Returns all the denied roles + RBACRoleContainer const& GetDeniedRoles() const { return _deniedRoles; } + /// Returns all the granted groups + RBACGroupContainer const& GetGroups() const { return _groups; } + + /** + * @name AddGroup + * @brief Adds new group + * + * Add a new group to the account. If realm is 0 or the group can not be added + * No save to db action will be performed. + * + * Fails if group Id does not exists or group already present + * + * @param groupId group to be added + * @param realmId realm affected + * + * @return Success or failure (with reason) to add the group + * + * Example Usage: + * @code + * // previously defined "RBACData* rbac" with proper initialization + * uint32 groupId = 2; + * if (rbac->AddGroup(groupId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully added", groupId); + * @endcode + */ + RBACCommandResult AddGroup(uint32 groupId, int32 realmId = 0); + + /** + * @name RemoveGroup + * @brief Removes a group + * + * Removes a group from the account. If realm is 0 or the group can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if group not present + * + * @param groupId group to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the group + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 groupId = 2; + * if (rbac->RemoveGroup(groupId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully removed", groupId); + * @endcode + */ + RBACCommandResult RemoveGroup(uint32 groupId, int32 realmId = 0); + + /** + * @name GrantRole + * @brief Grants a role + * + * Grants a role to the account. If realm is 0 or the role can not be added + * No save to db action will be performed. + * + * Fails if role Id does not exists or role already granted or denied + * + * @param roleId role to be granted + * @param realmId realm affected + * + * @return Success or failure (with reason) to grant the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->GrantRole(roleId) == RBAC_IN_DENIED_LIST) + * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant role %u, already denied", roleId); + * @endcode + */ + RBACCommandResult GrantRole(uint32 roleId, int32 realmId = 0); + + /** + * @name DenyRole + * @brief Denies a role + * + * Denied a role to the account. If realm is 0 or the role can not be added + * No save to db action will be performed. + * + * Fails if role Id does not exists or role already granted or denied + * + * @param roleId role to be denied + * @param realmId realm affected + * + * @return Success or failure (with reason) to deny the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->DenyRole(roleId) == RBAC_ID_DOES_NOT_EXISTS) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", roleId); + * @endcode + */ + RBACCommandResult DenyRole(uint32 roleId, int32 realmId = 0); + + /** + * @name RevokeRole + * @brief Removes a role + * + * Removes a role from the account. If realm is 0 or the role can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if role not present + * + * @param roleId role to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the role + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 roleId = 2; + * if (rbac->RevokeRole(roleId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId); + * @endcode + */ + RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0); + + /** + * @name GrantRole + * @brief Grants a permission + * + * Grants a permission to the account. If realm is 0 or the permission can not be added + * No save to db action will be performed. + * + * Fails if permission Id does not exists or permission already granted or denied + * + * @param permissionId permission to be granted + * @param realmId realm affected + * + * @return Success or failure (with reason) to grant the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->GrantRole(permissionId) == RBAC_IN_DENIED_LIST) + * sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant permission %u, already denied", permissionId); + * @endcode + */ + RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId = 0); + + /** + * @name DenyPermission + * @brief Denies a permission + * + * Denied a permission to the account. If realm is 0 or the permission can not be added + * No save to db action will be performed. + * + * Fails if permission Id does not exists or permission already granted or denied + * + * @param permissionId permission to be denied + * @param realmId realm affected + * + * @return Success or failure (with reason) to deny the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->DenyRole(permissionId) == RBAC_ID_DOES_NOT_EXISTS) + * sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", permissionId); + * @endcode + */ + RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId = 0); + + /** + * @name RevokePermission + * @brief Removes a permission + * + * Removes a permission from the account. If realm is 0 or the permission can not be removed + * No save to db action will be performed. Any delete operation will always affect + * "all realms (-1)" in addition to the realm specified + * + * Fails if permission not present + * + * @param permissionId permission to be removed + * @param realmId realm affected + * + * @return Success or failure (with reason) to remove the permission + * + * Example Usage: + * // previously defined "RBACData* rbac" with proper initialization + * uint32 permissionId = 2; + * if (rbac->RevokeRole(permissionId) == RBAC_OK) + * sLog->outDebug(LOG_FILTER_PLAYER, "Permission %u succesfully removed", permissionId); + * @endcode + */ + RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0); + + /// Loads all permissions, groups and roles assigned to current account + void LoadFromDB(); + private: + /// Saves a role to DB, Granted or Denied + void SaveRole(uint32 role, bool granted, int32 realm); + /// Saves a permission to DB, Granted or Denied + void SavePermission(uint32 role, bool granted, int32 realm); + + /** + * @name CalculateNewPermissions + * @brief Calculates new permissions + * + * Calculates new permissions after some change in groups, roles or permissions. + * The calculation is done Granted - Denied: + * - Granted permissions: through groups, through roles and directly assigned + * - Denied permissions: through roles and directly assigned + */ + void CalculateNewPermissions(); + + int32 GetRealmId() { return _realmId; } + + int32 _realmId; ///> RealmId Affected + RBACGroupContainer _groups; ///> Granted groups + RBACRoleContainer _grantedRoles; ///> Granted roles + RBACRoleContainer _deniedRoles; ///> Denied roles + RBACPermissionContainer _grantedPerms; ///> Granted permissions + RBACPermissionContainer _deniedPerms; ///> Denied permissions + RBACPermissionContainer _globalPerms; ///> Calculated permissions +}; + +#endif diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp new file mode 100644 index 00000000000..fb21def4c02 --- /dev/null +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * 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, see . + */ + +/* ScriptData +Name: rbac_commandscript +%Complete: 100 +Comment: All role based access control related commands (including account related) +Category: commandscripts +EndScriptData */ + +#include "RBAC.h" +#include "Config.h" +#include "Chat.h" +#include "Language.h" +#include "Player.h" +#include "ScriptMgr.h" + +struct RBACCommandData +{ + RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { } + uint32 id; + int32 realmId; + RBACData* rbac; + bool needDelete; +}; + +class rbac_commandscript : public CommandScript +{ +public: + rbac_commandscript() : CommandScript("rbac_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand rbacGroupsCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, true, &HandleRBACGroupAddCommand, "", NULL }, + { "remove", SEC_ADMINISTRATOR, true, &HandleRBACGroupRemoveCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACGroupListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacRolesCommandTable[] = + { + { "grant", SEC_ADMINISTRATOR, true, &HandleRBACRoleGrantCommand, "", NULL }, + { "deny", SEC_ADMINISTRATOR, true, &HandleRBACRoleDenyCommand, "", NULL }, + { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACRoleRevokeCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACRoleListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacPermsCommandTable[] = + { + { "grant", SEC_ADMINISTRATOR, true, &HandleRBACPermGrantCommand, "", NULL }, + { "deny", SEC_ADMINISTRATOR, true, &HandleRBACPermDenyCommand, "", NULL }, + { "revoke", SEC_ADMINISTRATOR, true, &HandleRBACPermRevokeCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACPermListCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacListCommandTable[] = + { + { "groups", SEC_ADMINISTRATOR, true, &HandleRBACListGroupsCommand, "", NULL }, + { "roles", SEC_ADMINISTRATOR, true, &HandleRBACListRolesCommand, "", NULL }, + { "permissions", SEC_ADMINISTRATOR, true, &HandleRBACListPermissionsCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacAccountCommandTable[] = + { + { "group", SEC_ADMINISTRATOR, true, NULL, "", rbacGroupsCommandTable }, + { "role", SEC_ADMINISTRATOR, true, NULL, "", rbacRolesCommandTable }, + { "permission", SEC_ADMINISTRATOR, true, NULL, "", rbacPermsCommandTable }, + { "", SEC_ADMINISTRATOR, true, &HandleRBACAccountPermissionCommand, "", NULL }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand rbacCommandTable[] = + { + { "account", SEC_ADMINISTRATOR, true, NULL, "", rbacAccountCommandTable }, + { "list", SEC_ADMINISTRATOR, true, NULL, "", rbacListCommandTable }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "rbac", SEC_ADMINISTRATOR, true, NULL, "", rbacCommandTable }, + { NULL, SEC_ADMINISTRATOR, false, NULL, "", NULL } + }; + + return commandTable; + } + + static RBACCommandData* ReadParams(ChatHandler* handler, char const* args, bool checkParams = true) + { + if (!args) + return NULL; + + char* param1 = strtok((char*)args, " "); + char* param2 = strtok(NULL, " "); + char* param3 = strtok(NULL, " "); + + int32 realmId = -1; + uint32 accountId = 0; + std::string accountName; + uint32 id = 0; + RBACCommandData* data = NULL; + RBACData* rdata = NULL; + bool useSelectedPlayer = false; + + if (checkParams) + { + if (!param3) + { + if (param2) + realmId = atoi(param2); + + if (param1) + id = atoi(param1); + + useSelectedPlayer = true; + } + else + { + id = atoi(param2); + realmId = atoi(param3); + } + + if (!id) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return NULL; + } + + if (realmId < -1 || !realmId) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_REALM, realmId); + handler->SetSentErrorMessage(true); + return NULL; + } + } + else if (!param1) + useSelectedPlayer = true; + + if (useSelectedPlayer) + { + Player* player = handler->getSelectedPlayer(); + if (!player) + return NULL; + + rdata = player->GetSession()->GetRBACData(); + accountId = rdata->GetId(); + AccountMgr::GetName(accountId, accountName); + } + else + { + accountName = param1; + + if (AccountMgr::normalizeString(accountName)) + accountId = AccountMgr::GetId(accountName); + + if (!accountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return NULL; + } + } + + if (checkParams && handler->HasLowerSecurityAccount(NULL, accountId, true)) + return NULL; + + data = new RBACCommandData(); + + if (!rdata) + { + data->rbac = new RBACData(accountId, accountName, ConfigMgr::GetIntDefault("RealmID", 0)); + data->rbac->LoadFromDB(); + data->needDelete = true; + } + else + data->rbac = rdata; + + data->id = id; + data->realmId = realmId; + return data; + } + + static bool HandleRBACGroupAddCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->AddGroup(command->id, command->realmId); + RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_GROUP_IN_LIST, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_GROUP_ADDED, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACGroupRemoveCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RemoveGroup(command->id, command->realmId); + RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_GROUP_NOT_IN_LIST, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_GROUP_REMOVED, command->id, group->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACGroupListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_GROUP_LIST_HEADER, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& groups = command->rbac->GetGroups(); + if (groups.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACGroupContainer::const_iterator it = groups.begin(); it != groups.end(); ++it) + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleGrantCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->GrantRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_DENIED_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleDenyCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->DenyRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_GRANTED_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleRevokeCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RevokeRole(command->id, command->realmId); + RBACRole const* role = sAccountMgr->GetRBACRole(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED, command->id, role->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACRoleListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& granted = command->rbac->GetGrantedRoles(); + if (granted.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = granted.begin(); it != granted.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + + handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACGroupContainer const& denied = command->rbac->GetDeniedRoles(); + if (denied.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = denied.begin(); it != denied.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->GrantPermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_DENIED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermDenyCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->DenyPermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_IN_GRANTED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermRevokeCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + RBACCommandResult result = command->rbac->RevokePermission(command->id, command->realmId); + RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACPermListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions(); + if (!granted.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (granted.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions(); + if (!denied.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (denied.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACAccountPermissionCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_PERM_LIST_GLOBAL, command->rbac->GetId(), command->rbac->GetName().c_str()); + RBACPermissionContainer const& permissions = command->rbac->GetPermissions(); + if (!permissions.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (permissions.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + if (command->needDelete) + delete command; + + return true; + } + + static bool HandleRBACListGroupsCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACGroupsContainer const& groups = sAccountMgr->GetRBACGroupList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); + for (RBACGroupsContainer::const_iterator it = groups.begin(); it != groups.end(); ++it) + { + RBACGroup const* group = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + } + } + else + { + RBACGroup const* group = sAccountMgr->GetRBACGroup(id); + if (!group) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + RBACRoleContainer const& roles = group->GetRoles(); + if (roles.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + { + RBACRole const* role = sAccountMgr->GetRBACRole(*it); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + } + + return true; + } + + static bool HandleRBACListRolesCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACRolesContainer const& roles = sAccountMgr->GetRBACRoleList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + for (RBACRolesContainer::const_iterator it = roles.begin(); it != roles.end(); ++it) + { + RBACRole const* role = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + } + } + else + { + RBACRole const* role = sAccountMgr->GetRBACRole(id); + if (!role) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + RBACPermissionContainer const& permissions = role->GetPermissions(); + if (!permissions.any()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (uint32 i = 0; i < RBAC_PERM_MAX; ++i) + if (permissions.test(i)) + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + } + + return true; + } + + static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + for (RBACPermissionsContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it) + { + RBACPermission const* permission = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + else + { + RBACPermission const* permission = sAccountMgr->GetRBACPermission(id); + if (!permission) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + + return true; + } +}; + +void AddSC_rbac_commandscript() +{ + new rbac_commandscript(); +} -- cgit v1.2.3 From 67f686106d7d372d1ed652800582df15999d099c Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 10:10:15 +0100 Subject: Fix compile without PCH --- src/server/game/Accounts/RBAC.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 0b08e277fb2..4a069df05cd 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -16,6 +16,8 @@ */ #include "RBAC.h" +#include "AccountMgr.h" +#include "DatabaseEnv.h" RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */) { -- cgit v1.2.3 From 61979f85918ed7acda19075d3a3201ad15bbcaea Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 16:52:43 +0100 Subject: Scripts/Player: Add OnMapChanged to PlayerScripts (after map changed) Core/Dungeon Finder: Use OnMapChanged script to cast/remove Luck of the draw - Also move code to force party update to LfgPlayerScript - Remove some obsolete Lfg code after recent commits --- .../2013_02_04_05_world_spell_script_names.sql | 1 + src/server/game/DungeonFinding/LFGMgr.cpp | 14 ----- src/server/game/DungeonFinding/LFGMgr.h | 9 ++-- src/server/game/DungeonFinding/LFGScripts.cpp | 18 +++++++ src/server/game/DungeonFinding/LFGScripts.h | 1 + src/server/game/Entities/Player/Player.cpp | 19 +------ src/server/game/Maps/Map.cpp | 4 -- src/server/game/Scripting/ScriptMgr.cpp | 2 + src/server/game/Scripting/ScriptMgr.h | 3 ++ src/server/scripts/Spells/spell_generic.cpp | 61 ---------------------- 10 files changed, 29 insertions(+), 103 deletions(-) create mode 100644 sql/updates/world/2013_02_04_05_world_spell_script_names.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_04_05_world_spell_script_names.sql b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql new file mode 100644 index 00000000000..055e4b1d77d --- /dev/null +++ b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=72221; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index e18a103e21c..9bb65b63557 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1085,7 +1085,6 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) break; } - teleportStore.push_back(pguid); SetState(pguid, LFG_STATE_DUNGEON); } @@ -1320,10 +1319,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported out. Current Map %u - Expected Map %u", player->GetName().c_str(), player->GetMapId(), uint32(dungeon->map)); if (player->GetMapId() == uint32(dungeon->map)) - { - player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); player->TeleportToBGEntryPoint(); - } return; } @@ -1597,16 +1593,6 @@ const std::string& LFGMgr::GetComment(uint64 guid) return PlayersStore[guid].GetComment(); } -bool LFGMgr::hasPendingTeleport(uint64 pguid) -{ - if (std::find(teleportStore.begin(), teleportStore.end(), pguid) != teleportStore.end()) - { - teleportStore.remove(pguid); - return true; - } - return false; -} - LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 07c4281f86f..96fedb65547 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -329,8 +329,6 @@ class LFGMgr void _LoadFromDB(Field* fields, uint64 guid); /// Initializes player data after loading group data from DB void SetupGroupMember(uint64 guid, uint64 gguid); - /// Player has pending teleport action - bool hasPendingTeleport(uint64 guid); /// Return Lfg dungeon entry for given dungeon id uint32 GetLFGDungeonEntry(uint32 id); @@ -340,7 +338,7 @@ class LFGMgr /// Get current player comment (used for LFR) std::string const& GetComment(uint64 gguid); /// Gets current lfg options - uint32 GetOptions(); // cs_lfg + uint32 GetOptions(); /// Sets new lfg options void SetOptions(uint32 options); /// Checks if given lfg option is enabled @@ -355,8 +353,6 @@ class LFGMgr uint64 GetLeader(uint64 guid); /// Initializes locked dungeons for given player (called at login or level change) void InitializeLockedDungeons(Player* player, uint8 level = 0); - /// Inits new proposal to boot a player - void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); /// Sets player team void SetTeam(uint64 guid, uint8 team); /// Sets player group @@ -385,6 +381,8 @@ class LFGMgr LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion); /// Teleport a player to/from selected dungeon void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); + /// Inits new proposal to boot a player + void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason); /// Updates player boot proposal with new player answer void UpdateBoot(uint64 guid, bool accept); /// Updates proposal to join dungeon with player answer @@ -467,7 +465,6 @@ class LFGMgr LfgPlayerBootContainer BootsStore; ///< Current player kicks LfgPlayerDataContainer PlayersStore; ///< Player data LfgGroupDataContainer GroupsStore; ///< Group data - LfgGuidList teleportStore; ///< Players being teleported }; } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index ac95d289397..46a4ed4a134 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -88,6 +88,24 @@ void LFGPlayerScript::OnBindToInstance(Player* player, Difficulty difficulty, ui sLFGMgr->InitializeLockedDungeons(player); } +void LFGPlayerScript::OnMapChanged(Player* player) +{ + Map const* map = player->GetMap(); + + if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty())) + { + Group* group = player->GetGroup(); + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + if (Player* member = itr->getSource()) + player->GetSession()->SendNameQueryOpcode(member->GetGUID()); + + if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID())) + player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); + } + else // if (player->HasAura(lfg:LFG_SPELL_LUCK_OF_THE_DRAW)) + player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); +} + LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript") { } diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index e9c6b1499d1..bb1900cad93 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -39,6 +39,7 @@ class LFGPlayerScript : public PlayerScript void OnLogout(Player* player); void OnLogin(Player* player); void OnBindToInstance(Player* player, Difficulty difficulty, uint32 mapId, bool permanent); + void OnMapChanged(Player* player); }; class LFGGroupScript : public GroupScript diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dc98facc5ab..18b2a837b5a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7444,17 +7444,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // group update if (Group* group = GetGroup()) - { SetGroupUpdateFlag(GROUP_UPDATE_FULL); - if (GetSession() && group->isLFGGroup() && sLFGMgr->hasPendingTeleport(GetGUID())) - { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - if (Player* member = itr->getSource()) - GetSession()->SendNameQueryOpcode(member->GetGUID()); - } - } - } m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -11913,19 +11903,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - lfg::LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); - if (dungeons.empty()) - return EQUIP_ERR_OK; // not using LFG - if (!GetGroup() || !GetGroup()->isLFGGroup()) return EQUIP_ERR_OK; // not in LFG group // check if looted object is inside the lfg dungeon - bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); - lootedObjectInDungeon = sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty()); - - if (!lootedObjectInDungeon) + if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty())) return EQUIP_ERR_OK; if (!proto) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 288592d1029..7fe516a1eb4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -26,7 +26,6 @@ #include "GridStates.h" #include "Group.h" #include "InstanceScript.h" -#include "LFGMgr.h" #include "MapInstanced.h" #include "MapManager.h" #include "ObjectAccessor.h" @@ -2484,9 +2483,6 @@ bool InstanceMap::AddPlayerToMap(Player* player) ASSERT(playerBind->save == mapSave); } } - - if (group && group->isLFGGroup()) - player->CastSpell(player, lfg::LFG_SPELL_LUCK_OF_THE_DRAW, true); } // for normal instances cancel the reset schedule when the diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index cae8ea9d2d5..8321b88962f 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -580,6 +580,8 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(map); ASSERT(player); + FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnPlayerEnter(map, player); SCR_MAP_END; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 7f140cfffe0..b13c2da7f6c 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -754,6 +754,9 @@ class PlayerScript : public UnitScript // Called when a player switches to a new zone virtual void OnUpdateZone(Player* /*player*/, uint32 /*newZone*/, uint32 /*newArea*/) { } + + // Called when a player changes to a new map (after moving to new map) + virtual void OnMapChanged(Player* /*player*/) { } }; class GuildScript : public ScriptObject diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 39992e94c21..edda9750709 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1707,66 +1707,6 @@ class spell_gen_damage_reduction_aura : public SpellScriptLoader } }; -class spell_gen_luck_of_the_draw : public SpellScriptLoader -{ - public: - spell_gen_luck_of_the_draw() : SpellScriptLoader("spell_gen_luck_of_the_draw") { } - - class spell_gen_luck_of_the_draw_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); - Map const* map; - Difficulty difficulty; - - bool Load() - { - Player* owner = GetUnitOwner()->ToPlayer(); - if (!owner) - return false; - - Group* group = owner->GetGroup(); - if (!group || !group->isLFGGroup()) - return false; - - if (!sLFGMgr->selectedRandomLfgDungeon(owner->GetGUID())) - return false; - - map = owner->GetMap(); - difficulty = owner->GetMap()->GetDifficulty(); - - if (!sLFGMgr->inLfgDungeonMap(owner->GetGUID(), map->GetId(), difficulty)) - return false; - - return true; - } - - // cheap hax to make it have update calls - void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) - { - isPeriodic = true; - amplitude = 5 * IN_MILLISECONDS; - } - - void Update(AuraEffect* /*effect*/) - { - Map const* currentMap = GetUnitOwner()->ToPlayer()->GetMap(); - if (currentMap != map || currentMap->GetDifficulty() != difficulty) - Remove(AURA_REMOVE_BY_DEFAULT); - } - - void Register() - { - DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_luck_of_the_draw_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_luck_of_the_draw_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_gen_luck_of_the_draw_AuraScript(); - } -}; - enum DummyTrigger { SPELL_PERSISTANT_SHIELD_TRIGGERED = 26470, @@ -3608,7 +3548,6 @@ void AddSC_generic_spell_scripts() new spell_gen_vehicle_scaling(); new spell_gen_oracle_wolvar_reputation(); new spell_gen_damage_reduction_aura(); - new spell_gen_luck_of_the_draw(); new spell_gen_dummy_trigger(); new spell_gen_spirit_healer_res(); new spell_gen_gadgetzan_transporter_backfire(); -- cgit v1.2.3 From fb7a544d842c1c3dcdf24c1f82b192d8ca20d18c Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 4 Feb 2013 17:04:40 +0100 Subject: Correction to previous commit (Use proper way to delete from spell_script_names) --- sql/updates/world/2013_02_04_05_world_spell_script_names.sql | 2 +- src/server/game/DungeonFinding/LFGScripts.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/sql/updates/world/2013_02_04_05_world_spell_script_names.sql b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql index 055e4b1d77d..4dd5ee52583 100644 --- a/sql/updates/world/2013_02_04_05_world_spell_script_names.sql +++ b/sql/updates/world/2013_02_04_05_world_spell_script_names.sql @@ -1 +1 @@ -DELETE FROM `spell_script_names` WHERE `spell_id`=72221; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_luck_of_the_draw'; diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 46a4ed4a134..a4716de9524 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -102,7 +102,7 @@ void LFGPlayerScript::OnMapChanged(Player* player) if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID())) player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } - else // if (player->HasAura(lfg:LFG_SPELL_LUCK_OF_THE_DRAW)) + else player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); } -- cgit v1.2.3 From 1e8bf1aad18088c0e5cde8918d653bc00b0187a4 Mon Sep 17 00:00:00 2001 From: w1sht0l1v3 Date: Mon, 4 Feb 2013 23:39:04 +0200 Subject: DB/Misc: Fix achievement Flirt With Disaster. --- ...13_02_04_07_world_achievement_criteria_data.sql | 20 +++++++++++++++++ src/server/scripts/World/achievement_scripts.cpp | 25 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 sql/updates/world/2013_02_04_07_world_achievement_criteria_data.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_04_07_world_achievement_criteria_data.sql b/sql/updates/world/2013_02_04_07_world_achievement_criteria_data.sql new file mode 100644 index 00000000000..dc873a02dfd --- /dev/null +++ b/sql/updates/world/2013_02_04_07_world_achievement_criteria_data.sql @@ -0,0 +1,20 @@ +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (3931,12859,4227,3929); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +-- aliance +-- Kissed Sraaz +(3931,1,9099,0,''), +(3931,11,0,0,'achievement_flirt_with_disaster_perf_check'), +(3931,15,3,0,''), +-- Handful of Rose Petals on Sraaz +(12859,1,9099,0,''), +(12859,11,0,0,'achievement_flirt_with_disaster_perf_check'), +(12859,15,3,0,''), +-- horde +-- Kissed Jeremiah Payson +(3929,1,8403,0,''), +(3929,11,0,0,'achievement_flirt_with_disaster_perf_check'), +(3929,15,3,0,''), +-- Handful of Rose Petals on Jeremiah Payson +(4227,1,8403,0,''), +(4227,11,0,0,'achievement_flirt_with_disaster_perf_check'), +(4227,15,3,0,''); diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index 41a32185620..d0ffe5214db 100644 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -315,6 +315,30 @@ class achievement_not_even_a_scratch : public AchievementCriteriaScript } }; +enum FlirtWithDisaster +{ + AURA_PERFUME_FOREVER = 70235, + AURA_PERFUME_ENCHANTRESS = 70234, + AURA_PERFUME_VICTORY = 70233, +}; + +class achievement_flirt_with_disaster_perf_check : public AchievementCriteriaScript +{ + public: + achievement_flirt_with_disaster_perf_check() : AchievementCriteriaScript("achievement_flirt_with_disaster_perf_check") { } + + bool OnCheck(Player* player, Unit* /*target*/) + { + if (!player) + return false; + + if (player->HasAura(AURA_PERFUME_FOREVER) || player->HasAura(AURA_PERFUME_ENCHANTRESS) || player->HasAura(AURA_PERFUME_VICTORY)) + return true; + + return false; + } +}; + void AddSC_achievement_scripts() { new achievement_resilient_victory(); @@ -333,4 +357,5 @@ void AddSC_achievement_scripts() new achievement_bg_sa_defense_of_ancients(); new achievement_tilted(); new achievement_not_even_a_scratch(); + new achievement_flirt_with_disaster_perf_check(); } -- cgit v1.2.3 From f9654d52e03240e0a44fdfed79e72cae710315b3 Mon Sep 17 00:00:00 2001 From: m7nu3l Date: Mon, 4 Feb 2013 19:18:48 -0300 Subject: Core/AI: Removed Scripted_NoMovementAI which has become obsolete. Use ScriptedAI::SetCombatMovement(false); to get the same functionality. --- src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 11 +------ src/server/game/AI/ScriptedAI/ScriptedCreature.h | 9 ------ .../SunwellPlateau/boss_eredar_twins.cpp | 10 +++---- .../SunwellPlateau/boss_kiljaeden.cpp | 31 +++++++++++++------- .../EasternKingdoms/SunwellPlateau/boss_muru.cpp | 10 ++++--- .../EasternKingdoms/zone_eversong_woods.cpp | 7 +++-- .../EasternKingdoms/zone_western_plaguelands.cpp | 7 +++-- .../BattleForMountHyjal/hyjal_trash.cpp | 6 ++-- .../scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp | 5 ++-- .../Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp | 32 +++++++++++--------- src/server/scripts/Kalimdor/zone_durotar.cpp | 5 ++-- .../AzjolNerub/Ahnkahet/boss_amanitar.cpp | 4 +-- .../AzjolNerub/Ahnkahet/boss_elder_nadox.cpp | 4 +-- .../Ahnkahet/boss_jedoga_shadowseeker.cpp | 6 ++-- .../ObsidianSanctum/boss_sartharion.cpp | 11 +++---- .../ChamberOfAspects/RubySanctum/boss_halion.cpp | 20 ++++++++----- .../TrialOfTheCrusader/boss_lord_jaraxxus.cpp | 10 ++++--- .../TrialOfTheCrusader/boss_twin_valkyr.cpp | 6 ++-- .../IcecrownCitadel/boss_lord_marrowgar.cpp | 6 ++-- .../Northrend/IcecrownCitadel/boss_sindragosa.cpp | 5 ++-- .../Northrend/IcecrownCitadel/icecrown_citadel.cpp | 5 ++-- .../scripts/Northrend/Naxxramas/boss_grobbulus.cpp | 6 ++-- .../Northrend/Nexus/Nexus/boss_anomalus.cpp | 5 ++-- .../scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp | 34 ++++++++++++++-------- .../Northrend/Ulduar/Ulduar/boss_razorscale.cpp | 10 ++++--- .../scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp | 5 ++-- .../UtgardeKeep/UtgardePinnacle/boss_svala.cpp | 6 ++-- .../Northrend/VaultOfArchavon/boss_toravon.cpp | 6 ++-- .../scripts/Northrend/zone_borean_tundra.cpp | 4 +-- .../scripts/Northrend/zone_crystalsong_forest.cpp | 7 +++-- src/server/scripts/Northrend/zone_dalaran.cpp | 4 +-- src/server/scripts/Northrend/zone_icecrown.cpp | 20 +++++++++---- .../scripts/Outland/BlackTemple/boss_supremus.cpp | 7 +++-- .../SerpentShrine/boss_lurker_below.cpp | 11 +++---- .../Outland/TempestKeep/Eye/boss_kaelthas.cpp | 7 +++-- src/server/scripts/World/npcs_special.cpp | 11 ++----- 36 files changed, 203 insertions(+), 150 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 090c73f456f..6c947d11f07 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -104,7 +104,7 @@ void ScriptedAI::AttackStartNoMove(Unit* who) if (!who) return; - if (me->Attack(who, false)) + if (me->Attack(who, true)) DoStartNoMovement(who); } @@ -447,15 +447,6 @@ bool ScriptedAI::EnterEvadeIfOutOfCombatArea(uint32 const diff) return true; } -void Scripted_NoMovementAI::AttackStart(Unit* target) -{ - if (!target) - return; - - if (me->Attack(target, true)) - DoStartNoMovement(target); -} - // BossAI - for instanced bosses BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), instance(creature->GetInstanceScript()), diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 15068557aca..b8c2b3f8363 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -276,15 +276,6 @@ struct ScriptedAI : public CreatureAI bool _isHeroic; }; -struct Scripted_NoMovementAI : public ScriptedAI -{ - Scripted_NoMovementAI(Creature* creature) : ScriptedAI(creature) {} - virtual ~Scripted_NoMovementAI() {} - - //Called at each attack of me by any victim - void AttackStart(Unit* target); -}; - class BossAI : public ScriptedAI { public: diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index c186ada72b7..73b52c4185f 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -345,10 +345,12 @@ public: return new boss_alythessAI (creature); }; - struct boss_alythessAI : public Scripted_NoMovementAI + struct boss_alythessAI : public ScriptedAI { - boss_alythessAI(Creature* creature) : Scripted_NoMovementAI(creature) + boss_alythessAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + instance = creature->GetInstanceScript(); IntroStepCounter = 10; } @@ -418,9 +420,7 @@ public: void AttackStart(Unit* who) { if (!me->isInCombat()) - { - Scripted_NoMovementAI::AttackStart(who); - } + ScriptedAI::AttackStart(who); } void MoveInLineOfSight(Unit* who) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 59face32389..c6cda9997b0 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -392,11 +392,13 @@ public: return new mob_kiljaeden_controllerAI (creature); } - struct mob_kiljaeden_controllerAI : public Scripted_NoMovementAI + struct mob_kiljaeden_controllerAI : public ScriptedAI { - mob_kiljaeden_controllerAI(Creature* creature) : Scripted_NoMovementAI(creature), summons(me) + mob_kiljaeden_controllerAI(Creature* creature) : ScriptedAI(creature), summons(me) { instance = creature->GetInstanceScript(); + + SetCombatMovement(false); } InstanceScript* instance; @@ -492,11 +494,13 @@ public: return new boss_kiljaedenAI (creature); } - struct boss_kiljaedenAI : public Scripted_NoMovementAI + struct boss_kiljaedenAI : public ScriptedAI { - boss_kiljaedenAI(Creature* creature) : Scripted_NoMovementAI(creature), summons(me) + boss_kiljaedenAI(Creature* creature) : ScriptedAI(creature), summons(me) { instance = creature->GetInstanceScript(); + + SetCombatMovement(false); } InstanceScript* instance; @@ -520,7 +524,7 @@ public: void InitializeAI() { - Scripted_NoMovementAI::InitializeAI(); + // Scripted_NoMovementAI::InitializeAI(); } void Reset() @@ -615,7 +619,8 @@ public: void EnterEvadeMode() { - Scripted_NoMovementAI::EnterEvadeMode(); + ScriptedAI::EnterEvadeMode(); + summons.DespawnAll(); // Reset the controller @@ -999,9 +1004,12 @@ public: return new mob_felfire_portalAI (creature); } - struct mob_felfire_portalAI : public Scripted_NoMovementAI + struct mob_felfire_portalAI : public ScriptedAI { - mob_felfire_portalAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + mob_felfire_portalAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } uint32 uiSpawnFiendTimer; @@ -1100,9 +1108,12 @@ public: return new mob_armageddonAI (creature); } - struct mob_armageddonAI : public Scripted_NoMovementAI + struct mob_armageddonAI : public ScriptedAI { - mob_armageddonAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + mob_armageddonAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } uint8 spell; uint32 uiTimer; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index 5eb79258005..b45e55e0605 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -213,10 +213,11 @@ public: return new boss_muruAI (creature); } - struct boss_muruAI : public Scripted_NoMovementAI + struct boss_muruAI : public ScriptedAI { - boss_muruAI(Creature* creature) : Scripted_NoMovementAI(creature), Summons(me) + boss_muruAI(Creature* creature) : ScriptedAI(creature), Summons(creature) { + SetCombatMovement(false); instance = creature->GetInstanceScript(); } @@ -377,10 +378,11 @@ public: return new npc_muru_portalAI (creature); } - struct npc_muru_portalAI : public Scripted_NoMovementAI + struct npc_muru_portalAI : public ScriptedAI { - npc_muru_portalAI(Creature* creature) : Scripted_NoMovementAI(creature), Summons(me) + npc_muru_portalAI(Creature* creature) : ScriptedAI(creature), Summons(creature) { + SetCombatMovement(false); instance = creature->GetInstanceScript(); } diff --git a/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp b/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp index 432768a51de..33cb5f649d7 100644 --- a/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp +++ b/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp @@ -551,9 +551,12 @@ public: return new npc_infused_crystalAI (creature); } - struct npc_infused_crystalAI : public Scripted_NoMovementAI + struct npc_infused_crystalAI : public ScriptedAI { - npc_infused_crystalAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + npc_infused_crystalAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } uint32 EndTimer; uint32 WaveTimer; diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index ee22b766154..6fa3401bcc9 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -254,9 +254,12 @@ public: return new npc_andorhal_towerAI (creature); } - struct npc_andorhal_towerAI : public Scripted_NoMovementAI + struct npc_andorhal_towerAI : public ScriptedAI { - npc_andorhal_towerAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + npc_andorhal_towerAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } void MoveInLineOfSight(Unit* who) { diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 2eb1b65fefd..c28d70e2634 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -1408,11 +1408,11 @@ public: return new alliance_riflemanAI(creature); } - struct alliance_riflemanAI : public Scripted_NoMovementAI + struct alliance_riflemanAI : public ScriptedAI { - alliance_riflemanAI(Creature* creature) : Scripted_NoMovementAI(creature) + alliance_riflemanAI(Creature* creature) : ScriptedAI(creature) { - Reset(); + SetCombatMovement(false); } uint32 ExplodeTimer; diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp index 285d893fe41..c69a696827e 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp @@ -197,11 +197,12 @@ class npc_buru_egg : public CreatureScript public: npc_buru_egg() : CreatureScript("npc_buru_egg") { } - struct npc_buru_eggAI : public Scripted_NoMovementAI + struct npc_buru_eggAI : public ScriptedAI { - npc_buru_eggAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_buru_eggAI(Creature* creature) : ScriptedAI(creature) { _instance = me->GetInstanceScript(); + SetCombatMovement(false); } void EnterCombat(Unit* attacker) diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index 3da1fc1dc5c..b5fbd644592 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -156,13 +156,15 @@ public: return new eye_of_cthunAI (creature); } - struct eye_of_cthunAI : public Scripted_NoMovementAI + struct eye_of_cthunAI : public ScriptedAI { - eye_of_cthunAI(Creature* creature) : Scripted_NoMovementAI(creature) + eye_of_cthunAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); if (!instance) sLog->outError(LOG_FILTER_TSCR, "No Instance eye_of_cthunAI"); + + SetCombatMovement(false); } InstanceScript* instance; @@ -460,9 +462,9 @@ public: return new cthunAI (creature); } - struct cthunAI : public Scripted_NoMovementAI + struct cthunAI : public ScriptedAI { - cthunAI(Creature* creature) : Scripted_NoMovementAI(creature) + cthunAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); @@ -916,15 +918,17 @@ public: return new eye_tentacleAI (creature); } - struct eye_tentacleAI : public Scripted_NoMovementAI + struct eye_tentacleAI : public ScriptedAI { - eye_tentacleAI(Creature* creature) : Scripted_NoMovementAI(creature) + eye_tentacleAI(Creature* creature) : ScriptedAI(creature) { if (Creature* pPortal = me->SummonCreature(MOB_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN)) { pPortal->SetReactState(REACT_PASSIVE); Portal = pPortal->GetGUID(); } + + SetCombatMovement(false); } uint32 MindflayTimer; @@ -989,9 +993,9 @@ public: return new claw_tentacleAI (creature); } - struct claw_tentacleAI : public Scripted_NoMovementAI + struct claw_tentacleAI : public ScriptedAI { - claw_tentacleAI(Creature* creature) : Scripted_NoMovementAI(creature) + claw_tentacleAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); @@ -1099,9 +1103,9 @@ public: return new giant_claw_tentacleAI (creature); } - struct giant_claw_tentacleAI : public Scripted_NoMovementAI + struct giant_claw_tentacleAI : public ScriptedAI { - giant_claw_tentacleAI(Creature* creature) : Scripted_NoMovementAI(creature) + giant_claw_tentacleAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); @@ -1218,9 +1222,9 @@ public: return new giant_eye_tentacleAI (creature); } - struct giant_eye_tentacleAI : public Scripted_NoMovementAI + struct giant_eye_tentacleAI : public ScriptedAI { - giant_eye_tentacleAI(Creature* creature) : Scripted_NoMovementAI(creature) + giant_eye_tentacleAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); @@ -1282,9 +1286,9 @@ public: return new flesh_tentacleAI (creature); } - struct flesh_tentacleAI : public Scripted_NoMovementAI + struct flesh_tentacleAI : public ScriptedAI { - flesh_tentacleAI(Creature* creature) : Scripted_NoMovementAI(creature) + flesh_tentacleAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp index fa6b830c1ae..9bd96957a52 100644 --- a/src/server/scripts/Kalimdor/zone_durotar.cpp +++ b/src/server/scripts/Kalimdor/zone_durotar.cpp @@ -175,10 +175,11 @@ class npc_tiger_matriarch_credit : public CreatureScript public: npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { } - struct npc_tiger_matriarch_creditAI : public Scripted_NoMovementAI + struct npc_tiger_matriarch_creditAI : public ScriptedAI { - npc_tiger_matriarch_creditAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_tiger_matriarch_creditAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp index d484e2a4279..bb08b48ab4a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp @@ -182,9 +182,9 @@ class mob_amanitar_mushrooms : public CreatureScript public: mob_amanitar_mushrooms() : CreatureScript("mob_amanitar_mushrooms") { } - struct mob_amanitar_mushroomsAI : public Scripted_NoMovementAI + struct mob_amanitar_mushroomsAI : public ScriptedAI { - mob_amanitar_mushroomsAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + mob_amanitar_mushroomsAI(Creature* creature) : ScriptedAI(creature) {} EventMap events; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp index ac668c33874..e9341e4956d 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp @@ -254,9 +254,9 @@ class mob_nadox_eggs : public CreatureScript public: mob_nadox_eggs() : CreatureScript("mob_nadox_eggs") { } - struct mob_nadox_eggsAI : public Scripted_NoMovementAI + struct mob_nadox_eggsAI : public ScriptedAI { - mob_nadox_eggsAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_nadox_eggsAI(Creature* creature) : ScriptedAI(creature) { creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); creature->UpdateAllStats(); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index c36bcf9708f..732216420f9 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -523,15 +523,17 @@ class npc_jedogas_aufseher_trigger : public CreatureScript public: npc_jedogas_aufseher_trigger() : CreatureScript("npc_jedogas_aufseher_trigger") { } - struct npc_jedogas_aufseher_triggerAI : public Scripted_NoMovementAI + struct npc_jedogas_aufseher_triggerAI : public ScriptedAI { - npc_jedogas_aufseher_triggerAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_jedogas_aufseher_triggerAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); bRemoved = false; bRemoved2 = false; bCasted = false; bCasted2 = false; + + SetCombatMovement(false); } InstanceScript* instance; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index f5864fe7b8f..3021e628063 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -1480,10 +1480,11 @@ public: return new mob_twilight_eggsAI(creature); } - struct mob_twilight_eggsAI : public Scripted_NoMovementAI + struct mob_twilight_eggsAI : public ScriptedAI { - mob_twilight_eggsAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_twilight_eggsAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); instance = creature->GetInstanceScript(); } @@ -1602,11 +1603,11 @@ public: return new npc_twilight_fissureAI(creature); } - struct npc_twilight_fissureAI : public Scripted_NoMovementAI + struct npc_twilight_fissureAI : public ScriptedAI { - npc_twilight_fissureAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_twilight_fissureAI(Creature* creature) : ScriptedAI(creature) { - Reset(); + SetCombatMovement(false); } uint32 VoidBlast_Timer; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index d31c2ead82d..d9fc1282e4c 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -973,11 +973,13 @@ class npc_meteor_strike_initial : public CreatureScript public: npc_meteor_strike_initial() : CreatureScript("npc_meteor_strike_initial") { } - struct npc_meteor_strike_initialAI : public Scripted_NoMovementAI + struct npc_meteor_strike_initialAI : public ScriptedAI { - npc_meteor_strike_initialAI(Creature* creature) : Scripted_NoMovementAI(creature), + npc_meteor_strike_initialAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) - { } + { + SetCombatMovement(false); + } void DoAction(int32 const action) { @@ -1045,13 +1047,15 @@ class npc_meteor_strike : public CreatureScript public: npc_meteor_strike() : CreatureScript("npc_meteor_strike") { } - struct npc_meteor_strikeAI : public Scripted_NoMovementAI + struct npc_meteor_strikeAI : public ScriptedAI { - npc_meteor_strikeAI(Creature* creature) : Scripted_NoMovementAI(creature), + npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { _range = 5.0f; _spawnCount = 0; + + SetCombatMovement(false); } void DoAction(int32 const action) @@ -1114,11 +1118,13 @@ class npc_combustion_consumption : public CreatureScript public: npc_combustion_consumption() : CreatureScript("npc_combustion_consumption") { } - struct npc_combustion_consumptionAI : public Scripted_NoMovementAI + struct npc_combustion_consumptionAI : public ScriptedAI { - npc_combustion_consumptionAI(Creature* creature) : Scripted_NoMovementAI(creature), + npc_combustion_consumptionAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summonerGuid(0) { + SetCombatMovement(false); + switch (me->GetEntry()) { case NPC_COMBUSTION: diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 073ebb0a35f..a44938e0f82 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -223,10 +223,11 @@ class mob_legion_flame : public CreatureScript public: mob_legion_flame() : CreatureScript("mob_legion_flame") { } - struct mob_legion_flameAI : public Scripted_NoMovementAI + struct mob_legion_flameAI : public ScriptedAI { - mob_legion_flameAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_legion_flameAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); _instance = creature->GetInstanceScript(); } @@ -258,10 +259,11 @@ class mob_infernal_volcano : public CreatureScript public: mob_infernal_volcano() : CreatureScript("mob_infernal_volcano") { } - struct mob_infernal_volcanoAI : public Scripted_NoMovementAI + struct mob_infernal_volcanoAI : public ScriptedAI { - mob_infernal_volcanoAI(Creature* creature) : Scripted_NoMovementAI(creature), _summons(me) + mob_infernal_volcanoAI(Creature* creature) : ScriptedAI(creature), _summons(me) { + SetCombatMovement(false); } void Reset() diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 9b6f4a6a0da..2509c3d0d59 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -654,11 +654,11 @@ class mob_bullet_controller : public CreatureScript public: mob_bullet_controller() : CreatureScript("mob_bullet_controller") { } - struct mob_bullet_controllerAI : public Scripted_NoMovementAI + struct mob_bullet_controllerAI : public ScriptedAI { - mob_bullet_controllerAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_bullet_controllerAI(Creature* creature) : ScriptedAI(creature) { - Reset(); + SetCombatMovement(false); } void Reset() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 1d340e61b61..16f0e4a7cde 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -424,11 +424,13 @@ class npc_bone_spike : public CreatureScript public: npc_bone_spike() : CreatureScript("npc_bone_spike") { } - struct npc_bone_spikeAI : public Scripted_NoMovementAI + struct npc_bone_spikeAI : public ScriptedAI { - npc_bone_spikeAI(Creature* creature) : Scripted_NoMovementAI(creature), _hasTrappedUnit(false) + npc_bone_spikeAI(Creature* creature) : ScriptedAI(creature), _hasTrappedUnit(false) { ASSERT(creature->GetVehicleKit()); + + SetCombatMovement(false); } void JustDied(Unit* /*killer*/) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 45c5302bfe8..1c6ed848158 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -576,11 +576,12 @@ class npc_ice_tomb : public CreatureScript public: npc_ice_tomb() : CreatureScript("npc_ice_tomb") { } - struct npc_ice_tombAI : public Scripted_NoMovementAI + struct npc_ice_tombAI : public ScriptedAI { - npc_ice_tombAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_ice_tombAI(Creature* creature) : ScriptedAI(creature) { _trappedPlayerGUID = 0; + SetCombatMovement(false); } void Reset() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 12868094b2e..5621f9b7a50 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -664,10 +664,11 @@ class npc_frost_freeze_trap : public CreatureScript public: npc_frost_freeze_trap() : CreatureScript("npc_frost_freeze_trap") { } - struct npc_frost_freeze_trapAI: public Scripted_NoMovementAI + struct npc_frost_freeze_trapAI: public ScriptedAI { - npc_frost_freeze_trapAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_frost_freeze_trapAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); } void DoAction(int32 const action) diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp index 536c2af2bd8..99d3bfe59b0 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp @@ -125,11 +125,11 @@ public: return new npc_grobbulus_poison_cloudAI(creature); } - struct npc_grobbulus_poison_cloudAI : public Scripted_NoMovementAI + struct npc_grobbulus_poison_cloudAI : public ScriptedAI { - npc_grobbulus_poison_cloudAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_grobbulus_poison_cloudAI(Creature* creature) : ScriptedAI(creature) { - Reset(); + SetCombatMovement(false); } uint32 Cloud_Timer; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp index 955c6b801af..fd5841a7727 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp @@ -191,11 +191,12 @@ class mob_chaotic_rift : public CreatureScript public: mob_chaotic_rift() : CreatureScript("mob_chaotic_rift") { } - struct mob_chaotic_riftAI : public Scripted_NoMovementAI + struct mob_chaotic_riftAI : public ScriptedAI { - mob_chaotic_riftAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_chaotic_riftAI(Creature* creature) : ScriptedAI(creature) { instance = me->GetInstanceScript(); + SetCombatMovement(false); } InstanceScript* instance; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 4db3b58c53f..0a873bc5792 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -216,10 +216,12 @@ class npc_iron_roots : public CreatureScript public: npc_iron_roots() : CreatureScript("npc_iron_roots") { } - struct npc_iron_rootsAI : public Scripted_NoMovementAI + struct npc_iron_rootsAI : public ScriptedAI { - npc_iron_rootsAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_iron_rootsAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip me->setFaction(14); @@ -1337,10 +1339,11 @@ class npc_sun_beam : public CreatureScript public: npc_sun_beam() : CreatureScript("npc_sun_beam") { } - struct npc_sun_beamAI : public Scripted_NoMovementAI + struct npc_sun_beamAI : public ScriptedAI { - npc_sun_beamAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_sun_beamAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); me->SetReactState(REACT_PASSIVE); DoCastAOE(SPELL_FREYA_UNSTABLE_ENERGY_VISUAL, true); DoCast(SPELL_FREYA_UNSTABLE_ENERGY); @@ -1358,10 +1361,11 @@ class npc_healthy_spore : public CreatureScript public: npc_healthy_spore() : CreatureScript("npc_healthy_spore") { } - struct npc_healthy_sporeAI : public Scripted_NoMovementAI + struct npc_healthy_sporeAI : public ScriptedAI { - npc_healthy_sporeAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_healthy_sporeAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC); me->SetReactState(REACT_PASSIVE); DoCast(me, SPELL_HEALTHY_SPORE_VISUAL); @@ -1397,10 +1401,12 @@ class npc_eonars_gift : public CreatureScript public: npc_eonars_gift() : CreatureScript("npc_eonars_gift") { } - struct npc_eonars_giftAI : public Scripted_NoMovementAI + struct npc_eonars_giftAI : public ScriptedAI { - npc_eonars_giftAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_eonars_giftAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + lifeBindersGiftTimer = 12000; DoCast(me, SPELL_GROW); DoCast(me, SPELL_PHEROMONES, true); @@ -1435,10 +1441,12 @@ class npc_nature_bomb : public CreatureScript public: npc_nature_bomb() : CreatureScript("npc_nature_bomb") { } - struct npc_nature_bombAI : public Scripted_NoMovementAI + struct npc_nature_bombAI : public ScriptedAI { - npc_nature_bombAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_nature_bombAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + bombTimer = urand(8000, 10000); DoCast(SPELL_OBJECT_BOMB); } @@ -1475,10 +1483,12 @@ class npc_unstable_sun_beam : public CreatureScript public: npc_unstable_sun_beam() : CreatureScript("npc_unstable_sun_beam") { } - struct npc_unstable_sun_beamAI : public Scripted_NoMovementAI + struct npc_unstable_sun_beamAI : public ScriptedAI { - npc_unstable_sun_beamAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_unstable_sun_beamAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + despawnTimer = urand(7000, 12000); instance = me->GetInstanceScript(); DoCast(me, SPELL_PHOTOSYNTHESIS); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index 79edede01df..b51c6994dd5 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -739,10 +739,11 @@ class npc_mole_machine_trigger : public CreatureScript public: npc_mole_machine_trigger() : CreatureScript("npc_mole_machine_trigger") { } - struct npc_mole_machine_triggerAI : public Scripted_NoMovementAI + struct npc_mole_machine_triggerAI : public ScriptedAI { - npc_mole_machine_triggerAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_mole_machine_triggerAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); } @@ -818,10 +819,11 @@ class npc_devouring_flame : public CreatureScript public: npc_devouring_flame() : CreatureScript("npc_devouring_flame") { } - struct npc_devouring_flameAI : public Scripted_NoMovementAI + struct npc_devouring_flameAI : public ScriptedAI { - npc_devouring_flameAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_devouring_flameAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index 43d19d78f8a..1ae6a35403b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -451,11 +451,12 @@ class mob_xt002_heart : public CreatureScript public: mob_xt002_heart() : CreatureScript("mob_xt002_heart") { } - struct mob_xt002_heartAI : public Scripted_NoMovementAI + struct mob_xt002_heartAI : public ScriptedAI { - mob_xt002_heartAI(Creature* creature) : Scripted_NoMovementAI(creature), + mob_xt002_heartAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { + SetCombatMovement(false); } void UpdateAI(uint32 const /*diff*/) { } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp index dffdadc5b9c..1442dddb120 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp @@ -459,11 +459,13 @@ public: return new npc_ritual_channelerAI(creature); } - struct npc_ritual_channelerAI : public Scripted_NoMovementAI + struct npc_ritual_channelerAI : public ScriptedAI { - npc_ritual_channelerAI(Creature* creature) :Scripted_NoMovementAI(creature) + npc_ritual_channelerAI(Creature* creature) :ScriptedAI(creature) { instance = creature->GetInstanceScript(); + + SetCombatMovement(false); } InstanceScript* instance; diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index 613b8ebf8dc..688e7d818df 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -234,9 +234,9 @@ class mob_frozen_orb_stalker : public CreatureScript public: mob_frozen_orb_stalker() : CreatureScript("mob_frozen_orb_stalker") { } - struct mob_frozen_orb_stalkerAI : public Scripted_NoMovementAI + struct mob_frozen_orb_stalkerAI : public ScriptedAI { - mob_frozen_orb_stalkerAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature) { creature->SetVisible(false); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE); @@ -244,6 +244,8 @@ class mob_frozen_orb_stalker : public CreatureScript instance = creature->GetInstanceScript(); spawned = false; + + SetCombatMovement(false); } void UpdateAI(const uint32 /*diff*/) diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 8e7507bce61..760156dc1c3 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -2207,9 +2207,9 @@ class npc_warmage_coldarra : public CreatureScript public: npc_warmage_coldarra() : CreatureScript("npc_warmage_coldarra") { } - struct npc_warmage_coldarraAI : public Scripted_NoMovementAI + struct npc_warmage_coldarraAI : public ScriptedAI { - npc_warmage_coldarraAI(Creature* creature) : Scripted_NoMovementAI(creature){} + npc_warmage_coldarraAI(Creature* creature) : ScriptedAI(creature) {} uint32 m_uiTimer; //Timer until recast diff --git a/src/server/scripts/Northrend/zone_crystalsong_forest.cpp b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp index d12b5176b15..963778dd802 100644 --- a/src/server/scripts/Northrend/zone_crystalsong_forest.cpp +++ b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp @@ -49,9 +49,12 @@ class npc_warmage_violetstand : public CreatureScript public: npc_warmage_violetstand() : CreatureScript("npc_warmage_violetstand") { } - struct npc_warmage_violetstandAI : public Scripted_NoMovementAI + struct npc_warmage_violetstandAI : public ScriptedAI { - npc_warmage_violetstandAI(Creature* creature) : Scripted_NoMovementAI(creature){} + npc_warmage_violetstandAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } uint64 uiTargetGUID; diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index d16b6fe4588..e988472fe5f 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -55,9 +55,9 @@ class npc_mageguard_dalaran : public CreatureScript public: npc_mageguard_dalaran() : CreatureScript("npc_mageguard_dalaran") { } - struct npc_mageguard_dalaranAI : public Scripted_NoMovementAI + struct npc_mageguard_dalaranAI : public ScriptedAI { - npc_mageguard_dalaranAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_mageguard_dalaranAI(Creature* creature) : ScriptedAI(creature) { creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true); diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 098fa80a3d3..47fb7a86d32 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -264,9 +264,12 @@ class npc_guardian_pavilion : public CreatureScript public: npc_guardian_pavilion() : CreatureScript("npc_guardian_pavilion") { } - struct npc_guardian_pavilionAI : public Scripted_NoMovementAI + struct npc_guardian_pavilionAI : public ScriptedAI { - npc_guardian_pavilionAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + npc_guardian_pavilionAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } void MoveInLineOfSight(Unit* who) { @@ -370,9 +373,12 @@ class npc_tournament_training_dummy : public CreatureScript public: npc_tournament_training_dummy(): CreatureScript("npc_tournament_training_dummy"){} - struct npc_tournament_training_dummyAI : Scripted_NoMovementAI + struct npc_tournament_training_dummyAI : ScriptedAI { - npc_tournament_training_dummyAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + npc_tournament_training_dummyAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } EventMap events; bool isVulnerable; @@ -584,13 +590,15 @@ class npc_blessed_banner : public CreatureScript public: npc_blessed_banner() : CreatureScript("npc_blessed_banner") { } - struct npc_blessed_bannerAI : public Scripted_NoMovementAI + struct npc_blessed_bannerAI : public ScriptedAI { - npc_blessed_bannerAI(Creature* creature) : Scripted_NoMovementAI(creature), Summons(me) + npc_blessed_bannerAI(Creature* creature) : ScriptedAI(creature), Summons(me) { HalofSpawned = false; PhaseCount = 0; Summons.DespawnAll(); + + SetCombatMovement(false); } EventMap events; diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index 6bc6633e49e..90b265e2a65 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -272,9 +272,12 @@ public: return new npc_volcanoAI (creature); } - struct npc_volcanoAI : public Scripted_NoMovementAI + struct npc_volcanoAI : public ScriptedAI { - npc_volcanoAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + npc_volcanoAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } void Reset() { diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp index 788de7753ff..cade8f34cde 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp @@ -78,10 +78,11 @@ public: return new boss_the_lurker_belowAI (creature); } - struct boss_the_lurker_belowAI : public Scripted_NoMovementAI + struct boss_the_lurker_belowAI : public ScriptedAI { - boss_the_lurker_belowAI(Creature* creature) : Scripted_NoMovementAI(creature), Summons(me) + boss_the_lurker_belowAI(Creature* creature) : ScriptedAI(creature), Summons(me) { + SetCombatMovement(false); instance = creature->GetInstanceScript(); } @@ -156,7 +157,6 @@ public: { if (instance) instance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS); - Scripted_NoMovementAI::EnterCombat(who); } void MoveInLineOfSight(Unit* who) @@ -368,10 +368,11 @@ public: return new mob_coilfang_ambusherAI (creature); } - struct mob_coilfang_ambusherAI : public Scripted_NoMovementAI + struct mob_coilfang_ambusherAI : public ScriptedAI { - mob_coilfang_ambusherAI(Creature* creature) : Scripted_NoMovementAI(creature) + mob_coilfang_ambusherAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); } uint32 MultiShotTimer; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 07d563cd762..8d66e0824b9 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1404,9 +1404,12 @@ class mob_kael_flamestrike : public CreatureScript : CreatureScript("mob_kael_flamestrike") { } - struct mob_kael_flamestrikeAI : public Scripted_NoMovementAI + struct mob_kael_flamestrikeAI : public ScriptedAI { - mob_kael_flamestrikeAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + mob_kael_flamestrikeAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + } uint32 Timer; bool Casting; diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 8a3342cf2de..d6a7cbf8e70 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1981,10 +1981,11 @@ class npc_training_dummy : public CreatureScript public: npc_training_dummy() : CreatureScript("npc_training_dummy") { } - struct npc_training_dummyAI : Scripted_NoMovementAI + struct npc_training_dummyAI : ScriptedAI { - npc_training_dummyAI(Creature* creature) : Scripted_NoMovementAI(creature) + npc_training_dummyAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); entry = creature->GetEntry(); } @@ -2015,12 +2016,6 @@ public: damage = 0; } - void EnterCombat(Unit* /*who*/) - { - if (entry != NPC_ADVANCED_TARGET_DUMMY && entry != NPC_TARGET_DUMMY) - return; - } - void UpdateAI(uint32 const diff) { if (!UpdateVictim()) -- cgit v1.2.3 From c4d3b831912b46e836de22e6cd773396b661fa29 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 4 Feb 2013 22:38:20 -0500 Subject: Implemented use of `graveyard_orientation` - You can test it by clicking on "Return to Graveyard" button --- src/server/game/Entities/Player/Player.cpp | 3 ++- src/server/game/Globals/ObjectMgr.cpp | 29 +++++++++++++++++++++++++++++ src/server/game/Globals/ObjectMgr.h | 16 +++++++++++++++- src/server/game/World/World.cpp | 3 +++ 4 files changed, 49 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fdcfee354e2..a3a7b364844 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5499,7 +5499,8 @@ void Player::RepopAtGraveyard() // and don't show spirit healer location if (ClosestGrave) { - TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, GetOrientation()); + float const* orientation = sObjectMgr->GetGraveyardOrientation(ClosestGrave->ID); + TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, orientation ? *orientation : GetOrientation()); if (isDead()) // not send if alive, because it used in TeleportTo() { WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // show spirit healer position on minimap diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 640eef5d651..043afdf4687 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -268,6 +268,7 @@ ObjectMgr::~ObjectMgr() itr->second.Clear(); _cacheTrainerSpellStore.clear(); + _graveyardOrientations.clear(); for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr) for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr) @@ -288,6 +289,34 @@ void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, Str } } +void ObjectMgr::LoadGraveyardOrientations() +{ + uint32 oldMSTime = getMSTime(); + + _graveyardOrientations.clear(); + + QueryResult result = WorldDatabase.Query("SELECT id, orientation FROM graveyard_orientation"); + + if (!result) + return; + + do + { + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + if (!sWorldSafeLocsStore.LookupEntry(id)) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, "Graveyard %u referenced in graveyard_orientation doesn't exist.", id); + continue; + } + _graveyardOrientations[id] = fields[1].GetFloat(); + + } while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %lu graveyard orientations in %u ms", (unsigned long)_graveyardOrientations.size(), GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadCreatureLocales() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index eb56bb09b93..563b218c55c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -561,6 +561,7 @@ struct GraveYardData }; typedef std::multimap GraveYardContainer; +typedef UNORDERED_MAP GraveyardOrientationContainer; typedef std::pair GraveYardMapBounds; typedef std::pair GraveYardMapBoundsNonConst; @@ -867,6 +868,7 @@ class ObjectMgr void LoadDbScriptStrings(); void LoadCreatureClassLevelStats(); void LoadCreatureLocales(); + void LoadGraveyardOrientations(); void LoadCreatureTemplates(); void LoadCreatureTemplateAddons(); void CheckCreatureTemplate(CreatureTemplate const* cInfo); @@ -1116,6 +1118,16 @@ class ObjectMgr return &iter->second; } + + float const* GetGraveyardOrientation(uint32 id) const + { + GraveyardOrientationContainer::const_iterator iter = _graveyardOrientations.find(id); + if (iter != _graveyardOrientations.end()) + return &iter->second; + + return NULL; + } + void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist = true); // for event bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist = true); // for event bool IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type, Player* player = NULL, std::set* skip_vendors = NULL, uint32 ORnpcflag = 0) const; @@ -1151,7 +1163,7 @@ class ObjectMgr // for wintergrasp only GraveYardContainer GraveYardStore; - + static void AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data); static inline void GetLocaleString(const StringVector& data, int loc_idx, std::string& value) { @@ -1313,6 +1325,8 @@ class ObjectMgr CacheVendorItemContainer _cacheVendorItemStore; CacheTrainerSpellContainer _cacheTrainerSpellStore; + + GraveyardOrientationContainer _graveyardOrientations; std::set _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate std::set _hasDifficultyEntries[MAX_DIFFICULTY - 1]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 3bba06a021f..ef0c9b64475 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1547,6 +1547,9 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Graveyard-zone links..."); sObjectMgr->LoadGraveyardZones(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Graveyard Orientations..."); + sObjectMgr->LoadGraveyardOrientations(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading spell pet auras..."); sSpellMgr->LoadSpellPetAuras(); -- cgit v1.2.3 From f210ab0d47a90fb025a51f49df278ac5dcd7ef75 Mon Sep 17 00:00:00 2001 From: Spp Date: Tue, 5 Feb 2013 09:11:56 +0100 Subject: Core/RBAC: Allow custom security levels for commands. (Before this change any command with seclevel > 3 had the same permissions than player commands) Note: This is still a workaround till command system is moved to RBAC --- src/server/game/Chat/Chat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index b8f80fb36ac..26ecd93bcf0 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -137,9 +137,10 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const permission = RBAC_PERM_MODERATOR_COMMANDS; break; case SEC_PLAYER: - default: permission = RBAC_PERM_PLAYER_COMMANDS; break; + default: // Allow custom security levels for commands + return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel) } return m_session->HasPermission(permission); -- cgit v1.2.3 From fedc26a115dc80457528af39ee699e00793eda12 Mon Sep 17 00:00:00 2001 From: Spp Date: Tue, 5 Feb 2013 09:26:52 +0100 Subject: Typo fix --- src/server/game/Chat/Chat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 26ecd93bcf0..3cae9d0f83a 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -140,7 +140,7 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const permission = RBAC_PERM_PLAYER_COMMANDS; break; default: // Allow custom security levels for commands - return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel) + return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel); } return m_session->HasPermission(permission); -- cgit v1.2.3 From dd0658e675d788d345398a9b32a60466720ff487 Mon Sep 17 00:00:00 2001 From: Spp Date: Tue, 5 Feb 2013 11:12:00 +0100 Subject: Warning fix --- src/server/game/Entities/Player/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 18b2a837b5a..35b104476b6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7443,7 +7443,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) } // group update - if (Group* group = GetGroup()) + if (GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_FULL); m_zoneUpdateId = newZone; -- cgit v1.2.3 From ede65fb60c6d9f12a1cb28b92603057c1ed27c27 Mon Sep 17 00:00:00 2001 From: click Date: Tue, 5 Feb 2013 15:45:18 +0100 Subject: Core/Remote: Adjust logentries to accomodate separation of info- vs debug-output, using Info-level as default unless it's REAL debugoutput --- src/server/worldserver/RemoteAccess/RASocket.cpp | 20 +++++++++----------- src/server/worldserver/TCSoap/TCSoap.cpp | 12 ++++++------ 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp index 94950703271..b939f267233 100644 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ b/src/server/worldserver/RemoteAccess/RASocket.cpp @@ -49,14 +49,14 @@ int RASocket::open(void *) return -1; } - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Incoming connection from %s", remote_addr.get_host_addr()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Incoming connection from %s", remote_addr.get_host_addr()); return activate(); } int RASocket::handle_close(ACE_HANDLE, ACE_Reactor_Mask) { - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Closing connection"); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Closing connection"); peer().close_reader(); wait(); destroy(); @@ -142,7 +142,7 @@ int RASocket::process_command(const std::string& command) if (command.length() == 0) return 0; - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Got command: %s", command.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Received command: %s", command.c_str()); // handle quit, exit and logout commands to terminate connection if (command == "quit" || command == "exit" || command == "logout") { @@ -184,15 +184,13 @@ int RASocket::check_access_level(const std::string& user) AccountMgr::normalizeString(safeUser); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS); stmt->setString(0, safeUser); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "User %s does not exist in database", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "User %s does not exist in database", user.c_str()); return -1; } @@ -200,12 +198,12 @@ int RASocket::check_access_level(const std::string& user) if (fields[1].GetUInt8() < _minLevel) { - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "User %s has no privilege to login", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "User %s has no privilege to login", user.c_str()); return -1; } else if (fields[2].GetInt32() != -1) { - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); return -1; } @@ -231,7 +229,7 @@ int RASocket::check_password(const std::string& user, const std::string& pass) if (!result) { - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Wrong password for user: %s", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Wrong password for user: %s", user.c_str()); return -1; } @@ -254,7 +252,7 @@ int RASocket::authenticate() if (recv_line(pass) == -1) return -1; - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Login attempt for user: %s", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Login attempt for user: %s", user.c_str()); if (check_access_level(user) == -1) return -1; @@ -262,7 +260,7 @@ int RASocket::authenticate() if (check_password(user, pass) == -1) return -1; - sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "User login: %s", user.c_str()); + sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "User login: %s", user.c_str()); return 0; } diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp index 5d578a19124..7d460da4f83 100644 --- a/src/server/worldserver/TCSoap/TCSoap.cpp +++ b/src/server/worldserver/TCSoap/TCSoap.cpp @@ -78,33 +78,33 @@ int ns1__executeCommand(soap* soap, char* command, char** result) // security check if (!soap->userid || !soap->passwd) { - sLog->outDebug(LOG_FILTER_SOAP, "Client didn't provide login information"); + sLog->outInfo(LOG_FILTER_SOAP, "Client didn't provide login information"); return 401; } uint32 accountId = AccountMgr::GetId(soap->userid); if (!accountId) { - sLog->outDebug(LOG_FILTER_SOAP, "Client used invalid username '%s'", soap->userid); + sLog->outInfo(LOG_FILTER_SOAP, "Client used invalid username '%s'", soap->userid); return 401; } if (!AccountMgr::CheckPassword(accountId, soap->passwd)) { - sLog->outDebug(LOG_FILTER_SOAP, "Invalid password for account '%s'", soap->userid); + sLog->outInfo(LOG_FILTER_SOAP, "Invalid password for account '%s'", soap->userid); return 401; } if (AccountMgr::GetSecurity(accountId) < SEC_ADMINISTRATOR) { - sLog->outDebug(LOG_FILTER_SOAP, "%s's gmlevel is too low", soap->userid); + sLog->outInfo(LOG_FILTER_SOAP, "%s's gmlevel is too low", soap->userid); return 403; } if (!command || !*command) - return soap_sender_fault(soap, "Command mustn't be empty", "The supplied command was an empty string"); + return soap_sender_fault(soap, "Command can not be empty", "The supplied command was an empty string"); - sLog->outDebug(LOG_FILTER_SOAP, "Got command '%s'", command); + sLog->outInfo(LOG_FILTER_SOAP, "Received command '%s'", command); SOAPCommand connection; // commands are executed in the world thread. We have to wait for them to be completed -- cgit v1.2.3 From 745eb9732e183ceb1784403b7abd97f4577eed2a Mon Sep 17 00:00:00 2001 From: Gacko Date: Tue, 5 Feb 2013 19:39:51 +0100 Subject: Core/Spell: Consider disables for LOS check --- src/server/game/Spells/Spell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4d75aec2cae..18dc6f104a4 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6519,7 +6519,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const break; } - if (IsTriggered() || m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) + if (IsTriggered() || m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS)) return true; // todo: shit below shouldn't be here, but it's temporary -- cgit v1.2.3 From 0b3170c2281a1ce17b3392b8df65b291b49d03f2 Mon Sep 17 00:00:00 2001 From: Nay Date: Wed, 6 Feb 2013 13:16:21 +0000 Subject: Core/Player: Fix a query that was wrongly deleting items CHAR_DEL_ITEM_INSTANCE deletes by item guid but in Player::DeleteFromDB the guid being used was player's guid. That means that if player with guid 100 was deleted, the item with guid 100 would also be deleted. This item could or could not belong to the player. Closes #8883 Closes #9136 Thanks to @vlad852 for finding the issue --- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/shared/Database/Implementation/CharacterDatabase.cpp | 1 + src/server/shared/Database/Implementation/CharacterDatabase.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 35b104476b6..fd17fb908a1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4883,7 +4883,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC stmt->setUInt32(0, guid); trans->Append(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER); stmt->setUInt32(0, guid); trans->Append(stmt); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 52845231490..f4da15aefa3 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -147,6 +147,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomPropertyId = ?, durability = ?, playedTime = ?, text = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 7c064a98e17..4c5f5d27899 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -145,6 +145,7 @@ enum CharacterDatabaseStatements CHAR_UPD_ITEM_INSTANCE, CHAR_UPD_ITEM_INSTANCE_ON_LOAD, CHAR_DEL_ITEM_INSTANCE, + CHAR_DEL_ITEM_INSTANCE_BY_OWNER, CHAR_UPD_GIFT_OWNER, CHAR_DEL_GIFT, CHAR_SEL_CHARACTER_GIFT_BY_ITEM, -- cgit v1.2.3 From be07a7d481bdd6728463cf63ee236d27df45e550 Mon Sep 17 00:00:00 2001 From: Shocker Date: Wed, 6 Feb 2013 22:27:53 +0200 Subject: Core/Spells: Fix SPELL_AURA_MOD_POWER_COST_SCHOOL and SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT --- src/server/game/Spells/SpellInfo.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 652cc34ae5d..6c0913dd2fa 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -2249,7 +2249,15 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c } SpellSchools school = GetFirstSchoolInMask(schoolMask); // Flat mod from caster auras by spell school - powerCost += caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school); + AuraEffectList const& auras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL); + for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + { + if (!((*i)->GetMiscValue() & schoolMask)) + continue; + if (!((*i)->GetMiscValueB() & (1 << PowerType))) + continue; + powerCost += (*i)->GetAmount(); + } // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost) if (AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST) powerCost += caster->GetAttackTime(OFF_ATTACK) / 100; @@ -2261,7 +2269,15 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c powerCost = int32(powerCost / (1.117f * SpellLevel / caster->getLevel() -0.1327f)); // PCT mod from user auras by school - powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school))); + AuraEffectList const& aurasPct = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT); + for (AuraEffectList::const_iterator i = aurasPct.begin(); i != aurasPct.end(); ++i) + { + if (!((*i)->GetMiscValue() & schoolMask)) + continue; + if (!((*i)->GetMiscValueB() & (1 << PowerType))) + continue; + powerCost += CalculatePct(powerCost, (*i)->GetAmount()); + } if (powerCost < 0) powerCost = 0; return powerCost; -- cgit v1.2.3 From 443ea1282706ffe03730fbb51fe9d0738fbf68e2 Mon Sep 17 00:00:00 2001 From: Shocker Date: Wed, 6 Feb 2013 22:42:37 +0200 Subject: Fix build --- src/server/game/Spells/SpellInfo.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 6c0913dd2fa..aadc30e3921 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -2247,10 +2247,10 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c return 0; } } - SpellSchools school = GetFirstSchoolInMask(schoolMask); - // Flat mod from caster auras by spell school - AuraEffectList const& auras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL); - for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + + // Flat mod from caster auras by spell school and power type + Unit::AuraEffectList const& auras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL); + for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) { if (!((*i)->GetMiscValue() & schoolMask)) continue; @@ -2268,9 +2268,9 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION) powerCost = int32(powerCost / (1.117f * SpellLevel / caster->getLevel() -0.1327f)); - // PCT mod from user auras by school - AuraEffectList const& aurasPct = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT); - for (AuraEffectList::const_iterator i = aurasPct.begin(); i != aurasPct.end(); ++i) + // PCT mod from user auras by spell school and power type + Unit::AuraEffectList const& aurasPct = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT); + for (Unit::AuraEffectList::const_iterator i = aurasPct.begin(); i != aurasPct.end(); ++i) { if (!((*i)->GetMiscValue() & schoolMask)) continue; -- cgit v1.2.3 From fdffb3ebd078e4069f0d602af8a9141cca22b011 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 6 Feb 2013 22:18:41 +0100 Subject: Core: Fixed some compile warnings --- src/server/game/Battlefield/Battlefield.cpp | 9 +++++---- src/server/game/Battlefield/Battlefield.h | 2 +- src/server/game/Entities/Vehicle/VehicleDefines.h | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 5f5a14814eb..5b3284b2098 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -161,16 +161,17 @@ bool Battlefield::Update(uint32 diff) // Kick players who chose not to accept invitation to the battle if (m_uiKickDontAcceptTimer <= diff) { + time_t now = time(NULL); for (int team = 0; team < 2; team++) for (PlayerTimerMap::iterator itr = m_InvitedPlayers[team].begin(); itr != m_InvitedPlayers[team].end(); ++itr) - if ((*itr).second <= time(NULL)) - KickPlayerFromBattlefield((*itr).first); + if (itr->second <= now) + KickPlayerFromBattlefield(itr->first); InvitePlayersInZoneToWar(); for (int team = 0; team < 2; team++) for (PlayerTimerMap::iterator itr = m_PlayersWillBeKick[team].begin(); itr != m_PlayersWillBeKick[team].end(); ++itr) - if ((*itr).second <= time(NULL)) - KickPlayerFromBattlefield((*itr).first); + if (itr->second <= now) + KickPlayerFromBattlefield(itr->first); m_uiKickDontAcceptTimer = 1000; } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 7a8d856aa8e..534bfd620f0 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -71,7 +71,7 @@ class BfGraveyard; typedef std::set GuidSet; typedef std::vector GraveyardVect; -typedef std::map PlayerTimerMap; +typedef std::map PlayerTimerMap; class BfCapturePoint { diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index 3d3b43e832c..676b81c4c94 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -78,6 +78,8 @@ typedef std::map SeatMap; class TransportBase { public: + virtual ~TransportBase() { } + /// This method transforms supplied transport offsets into global coordinates virtual void CalculatePassengerPosition(float& x, float& y, float& z, float& o) = 0; -- cgit v1.2.3 From 943c866da97871d382db2f52e965ed38558695b0 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 7 Feb 2013 00:02:22 +0100 Subject: Core: Whitespace cleanup --- src/server/game/Accounts/RBAC.h | 38 +++++++++++----------- src/server/game/Globals/ObjectMgr.cpp | 14 ++++---- src/server/game/Globals/ObjectMgr.h | 10 +++--- src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 +- src/server/game/World/World.cpp | 2 +- src/server/scripts/Commands/cs_rbac.cpp | 6 ++-- .../EasternKingdoms/BaradinHold/boss_alizabal.cpp | 6 ++-- .../EasternKingdoms/zone_western_plaguelands.cpp | 2 +- .../ChamberOfAspects/RubySanctum/boss_halion.cpp | 2 +- src/server/scripts/Northrend/zone_icecrown.cpp | 2 +- .../scripts/Outland/BlackTemple/boss_supremus.cpp | 2 +- .../Outland/TempestKeep/Eye/boss_kaelthas.cpp | 2 +- src/server/scripts/Spells/spell_paladin.cpp | 4 +-- src/server/shared/Logging/AppenderFile.cpp | 2 +- src/server/worldserver/worldserver.conf.dist | 2 +- 15 files changed, 48 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 5420df29d17..d2c76b71801 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -161,10 +161,10 @@ class RBACData: public RBACObject * @name HasPermission * @brief Checks if certain action is allowed * - * Checks if certain action can be performed. + * Checks if certain action can be performed. * * @return grant or deny action - * + * * Example Usage: * @code * bool Player::CanJoinArena(Battleground* bg) @@ -175,7 +175,7 @@ class RBACData: public RBACObject */ bool HasPermission(uint32 permission) { return _globalPerms.test(permission); } - // Functions enabled to be used by command system + // Functions enabled to be used by command system /// Returns all the granted permissions (after computation) RBACPermissionContainer const& GetPermissions() const { return _globalPerms; } /// Returns all the granted permissions @@ -197,12 +197,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if group Id does not exists or group already present - * + * * @param groupId group to be added * @param realmId realm affected * * @return Success or failure (with reason) to add the group - * + * * Example Usage: * @code * // previously defined "RBACData* rbac" with proper initialization @@ -222,12 +222,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if group not present - * + * * @param groupId group to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the group - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 groupId = 2; @@ -245,12 +245,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if role Id does not exists or role already granted or denied - * + * * @param roleId role to be granted * @param realmId realm affected * * @return Success or failure (with reason) to grant the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -268,12 +268,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if role Id does not exists or role already granted or denied - * + * * @param roleId role to be denied * @param realmId realm affected * * @return Success or failure (with reason) to deny the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -292,12 +292,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if role not present - * + * * @param roleId role to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -315,12 +315,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if permission Id does not exists or permission already granted or denied - * + * * @param permissionId permission to be granted * @param realmId realm affected * * @return Success or failure (with reason) to grant the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; @@ -338,12 +338,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if permission Id does not exists or permission already granted or denied - * + * * @param permissionId permission to be denied * @param realmId realm affected * * @return Success or failure (with reason) to deny the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; @@ -362,12 +362,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if permission not present - * + * * @param permissionId permission to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 043afdf4687..8597b6098a9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -292,18 +292,18 @@ void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, Str void ObjectMgr::LoadGraveyardOrientations() { uint32 oldMSTime = getMSTime(); - + _graveyardOrientations.clear(); - + QueryResult result = WorldDatabase.Query("SELECT id, orientation FROM graveyard_orientation"); - + if (!result) return; - + do { Field* fields = result->Fetch(); - + uint32 id = fields[0].GetUInt32(); if (!sWorldSafeLocsStore.LookupEntry(id)) { @@ -311,9 +311,9 @@ void ObjectMgr::LoadGraveyardOrientations() continue; } _graveyardOrientations[id] = fields[1].GetFloat(); - + } while (result->NextRow()); - + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %lu graveyard orientations in %u ms", (unsigned long)_graveyardOrientations.size(), GetMSTimeDiffToNow(oldMSTime)); } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 563b218c55c..8c14f902c1f 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1118,16 +1118,16 @@ class ObjectMgr return &iter->second; } - + float const* GetGraveyardOrientation(uint32 id) const { GraveyardOrientationContainer::const_iterator iter = _graveyardOrientations.find(id); if (iter != _graveyardOrientations.end()) return &iter->second; - + return NULL; } - + void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist = true); // for event bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist = true); // for event bool IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type, Player* player = NULL, std::set* skip_vendors = NULL, uint32 ORnpcflag = 0) const; @@ -1163,7 +1163,7 @@ class ObjectMgr // for wintergrasp only GraveYardContainer GraveYardStore; - + static void AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data); static inline void GetLocaleString(const StringVector& data, int loc_idx, std::string& value) { @@ -1325,7 +1325,7 @@ class ObjectMgr CacheVendorItemContainer _cacheVendorItemStore; CacheTrainerSpellContainer _cacheTrainerSpellStore; - + GraveyardOrientationContainer _graveyardOrientations; std::set _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index f7d876d7aa3..249f25a6353 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -118,7 +118,7 @@ namespace Movement PacketBuilder::WriteMonsterMove(move_spline, data); unit->SendMessageToSet(&data, true); - + return move_spline.Duration(); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index ef0c9b64475..4a1d1566af1 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1548,7 +1548,7 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadGraveyardZones(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Graveyard Orientations..."); - sObjectMgr->LoadGraveyardOrientations(); + sObjectMgr->LoadGraveyardOrientations(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading spell pet auras..."); sSpellMgr->LoadSpellPetAuras(); diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index fb21def4c02..092aabb0045 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -674,7 +674,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); @@ -719,7 +719,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); @@ -765,7 +765,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); } diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp index fe7f3f47161..3c6369003ec 100644 --- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2008-2013 TrinityCore * * This program is free software; you can redistribute it and/or modify it @@ -79,7 +79,7 @@ class boss_alizabal : public CreatureScript { public: boss_alizabal() : CreatureScript("boss_alizabal") { } - + struct boss_alizabalAI : public BossAI { boss_alizabalAI(Creature* creature) : BossAI(creature, DATA_ALIZABAL) @@ -253,7 +253,7 @@ class boss_alizabal : public CreatureScript break; } } - + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index 6fa3401bcc9..c8bc82be245 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -256,7 +256,7 @@ public: struct npc_andorhal_towerAI : public ScriptedAI { - npc_andorhal_towerAI(Creature* creature) : ScriptedAI(creature) + npc_andorhal_towerAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index a9bf8c6ea8f..d84091e3cc7 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -976,7 +976,7 @@ class npc_meteor_strike_initial : public CreatureScript { npc_meteor_strike_initialAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) - { + { SetCombatMovement(false); } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 47fb7a86d32..70210844394 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -266,7 +266,7 @@ public: struct npc_guardian_pavilionAI : public ScriptedAI { - npc_guardian_pavilionAI(Creature* creature) : ScriptedAI(creature) + npc_guardian_pavilionAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index 90b265e2a65..2fac33760e2 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -274,7 +274,7 @@ public: struct npc_volcanoAI : public ScriptedAI { - npc_volcanoAI(Creature* creature) : ScriptedAI(creature) + npc_volcanoAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 8d66e0824b9..c4111f59d65 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1406,7 +1406,7 @@ class mob_kael_flamestrike : public CreatureScript } struct mob_kael_flamestrikeAI : public ScriptedAI { - mob_kael_flamestrikeAI(Creature* creature) : ScriptedAI(creature) + mob_kael_flamestrikeAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index a581a6ee351..ac9b861f584 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -56,7 +56,7 @@ enum PaladinSpells SPELL_PALADIN_DIVINE_SACRIFICE = 64205, SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174, - + SPELL_PALADIN_GLYPH_OF_SALVATION = 63225, SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790, @@ -874,7 +874,7 @@ class spell_pal_templar_s_verdict : public SpellScriptLoader } void ChangeDamage(SpellEffIndex /*effIndex*/) - { + { Unit* caster = GetCaster(); int32 damage = GetHitDamage(); diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index e29459299f7..93d53bcc30d 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -48,7 +48,7 @@ void AppenderFile::_write(LogMessage const& message) snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); logfile = OpenFile(namebuf, mode, backup || exceedMaxSize); } - else if (exceedMaxSize) + else if (exceedMaxSize) logfile = OpenFile(filename, "w", true); if (!logfile) diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 0fc26eae9cd..35d37d97f79 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2674,7 +2674,7 @@ UI.ShowQuestLevelsInDialogs = 0 # Maximum value is 4294967295 (4 gb). Leave blank for no limit. # NOTE: Does not work with dynamic filenames. # Example: 536870912 (512 mb) -# +# Appender.Console=1,3,0 Appender.Server=2,2,0,Server.log,w -- cgit v1.2.3 From 75994b3dd3b36a36390796257fc709a73dde735d Mon Sep 17 00:00:00 2001 From: click Date: Thu, 7 Feb 2013 00:19:19 +0100 Subject: Core: Clean up whitespace, and remove a silly warning in boss_lurker_below.cpp --- src/server/game/Entities/Vehicle/VehicleDefines.h | 2 +- src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp | 2 +- .../scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp | 2 +- src/server/scripts/Northrend/zone_icecrown.cpp | 2 +- src/server/scripts/Outland/BlackTemple/boss_supremus.cpp | 2 +- .../Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp | 2 +- src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp | 2 +- src/server/shared/Logging/AppenderFile.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index 676b81c4c94..4210a663aab 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -79,7 +79,7 @@ class TransportBase { public: virtual ~TransportBase() { } - + /// This method transforms supplied transport offsets into global coordinates virtual void CalculatePassengerPosition(float& x, float& y, float& z, float& o) = 0; diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index 6fa3401bcc9..c8bc82be245 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -256,7 +256,7 @@ public: struct npc_andorhal_towerAI : public ScriptedAI { - npc_andorhal_towerAI(Creature* creature) : ScriptedAI(creature) + npc_andorhal_towerAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index d9fc1282e4c..5b23aa6ffdd 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -977,7 +977,7 @@ class npc_meteor_strike_initial : public CreatureScript { npc_meteor_strike_initialAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) - { + { SetCombatMovement(false); } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 47fb7a86d32..70210844394 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -266,7 +266,7 @@ public: struct npc_guardian_pavilionAI : public ScriptedAI { - npc_guardian_pavilionAI(Creature* creature) : ScriptedAI(creature) + npc_guardian_pavilionAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index 90b265e2a65..2fac33760e2 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -274,7 +274,7 @@ public: struct npc_volcanoAI : public ScriptedAI { - npc_volcanoAI(Creature* creature) : ScriptedAI(creature) + npc_volcanoAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp index cade8f34cde..c9d0ab08e1c 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp @@ -153,7 +153,7 @@ public: Summons.DespawnAll(); } - void EnterCombat(Unit* who) + void EnterCombat(Unit* /*who*/) { if (instance) instance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 8d66e0824b9..c4111f59d65 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1406,7 +1406,7 @@ class mob_kael_flamestrike : public CreatureScript } struct mob_kael_flamestrikeAI : public ScriptedAI { - mob_kael_flamestrikeAI(Creature* creature) : ScriptedAI(creature) + mob_kael_flamestrikeAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); } diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index e29459299f7..93d53bcc30d 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -48,7 +48,7 @@ void AppenderFile::_write(LogMessage const& message) snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); logfile = OpenFile(namebuf, mode, backup || exceedMaxSize); } - else if (exceedMaxSize) + else if (exceedMaxSize) logfile = OpenFile(filename, "w", true); if (!logfile) -- cgit v1.2.3 From 5b45a87da5a9b82c84da2648f1fc544a0f80ad43 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 7 Feb 2013 00:24:00 +0100 Subject: Core: More clean up whitespace --- src/server/game/Accounts/RBAC.h | 38 ++++++++++++++-------------- src/server/scripts/Commands/cs_rbac.cpp | 6 ++--- src/server/worldserver/worldserver.conf.dist | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 5420df29d17..d2c76b71801 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -161,10 +161,10 @@ class RBACData: public RBACObject * @name HasPermission * @brief Checks if certain action is allowed * - * Checks if certain action can be performed. + * Checks if certain action can be performed. * * @return grant or deny action - * + * * Example Usage: * @code * bool Player::CanJoinArena(Battleground* bg) @@ -175,7 +175,7 @@ class RBACData: public RBACObject */ bool HasPermission(uint32 permission) { return _globalPerms.test(permission); } - // Functions enabled to be used by command system + // Functions enabled to be used by command system /// Returns all the granted permissions (after computation) RBACPermissionContainer const& GetPermissions() const { return _globalPerms; } /// Returns all the granted permissions @@ -197,12 +197,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if group Id does not exists or group already present - * + * * @param groupId group to be added * @param realmId realm affected * * @return Success or failure (with reason) to add the group - * + * * Example Usage: * @code * // previously defined "RBACData* rbac" with proper initialization @@ -222,12 +222,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if group not present - * + * * @param groupId group to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the group - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 groupId = 2; @@ -245,12 +245,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if role Id does not exists or role already granted or denied - * + * * @param roleId role to be granted * @param realmId realm affected * * @return Success or failure (with reason) to grant the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -268,12 +268,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if role Id does not exists or role already granted or denied - * + * * @param roleId role to be denied * @param realmId realm affected * * @return Success or failure (with reason) to deny the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -292,12 +292,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if role not present - * + * * @param roleId role to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the role - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 roleId = 2; @@ -315,12 +315,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if permission Id does not exists or permission already granted or denied - * + * * @param permissionId permission to be granted * @param realmId realm affected * * @return Success or failure (with reason) to grant the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; @@ -338,12 +338,12 @@ class RBACData: public RBACObject * No save to db action will be performed. * * Fails if permission Id does not exists or permission already granted or denied - * + * * @param permissionId permission to be denied * @param realmId realm affected * * @return Success or failure (with reason) to deny the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; @@ -362,12 +362,12 @@ class RBACData: public RBACObject * "all realms (-1)" in addition to the realm specified * * Fails if permission not present - * + * * @param permissionId permission to be removed * @param realmId realm affected * * @return Success or failure (with reason) to remove the permission - * + * * Example Usage: * // previously defined "RBACData* rbac" with proper initialization * uint32 permissionId = 2; diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index fb21def4c02..092aabb0045 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -674,7 +674,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str()); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); @@ -719,7 +719,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str()); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); @@ -765,7 +765,7 @@ public: handler->SetSentErrorMessage(true); return false; } - + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); } diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index f6a09667dda..e519a53a5af 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2706,7 +2706,7 @@ UI.ShowQuestLevelsInDialogs = 0 # Maximum value is 4294967295 (4 gb). Leave blank for no limit. # NOTE: Does not work with dynamic filenames. # Example: 536870912 (512 mb) -# +# Appender.Console=1,3,0 Appender.Server=2,2,0,Server.log,w -- cgit v1.2.3 From 82c31e50bbe7b79f7c892099ea5dd9ae780b4b9c Mon Sep 17 00:00:00 2001 From: thomas33 Date: Thu, 7 Feb 2013 16:10:10 +0100 Subject: typo --- .../scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp | 2 +- .../scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp | 6 +++--- .../scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp | 2 +- .../scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp | 2 +- .../scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp | 2 +- .../Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp index 7f6709b34fa..38c409ee706 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp @@ -322,5 +322,5 @@ public: void AddSC_boss_volazj() { - new boss_volazj; + new boss_volazj(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 8f77cc7ec6f..53d0ddd6c19 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -424,7 +424,7 @@ public: void AddSC_boss_taldaram() { - new boss_taldaram; - new mob_taldaram_flamesphere; - new prince_taldaram_sphere; + new boss_taldaram(); + new mob_taldaram_flamesphere(); + new prince_taldaram_sphere(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp index db4959ae670..26a4aeeca01 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp @@ -336,5 +336,5 @@ public: void AddSC_instance_ahnkahet() { - new instance_ahnkahet; + new instance_ahnkahet(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp index 1442ff265f4..06a640be6e4 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp @@ -360,5 +360,5 @@ public: void AddSC_boss_anub_arak() { - new boss_anub_arak; + new boss_anub_arak(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp index 6c707a8388f..e7decdc10fd 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp @@ -198,5 +198,5 @@ public: void AddSC_boss_hadronox() { - new boss_hadronox; + new boss_hadronox(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp index 7873cadd096..875aafe9826 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp @@ -213,5 +213,5 @@ public: void AddSC_instance_azjol_nerub() { - new instance_azjol_nerub; + new instance_azjol_nerub(); } -- cgit v1.2.3 From fb43a92cc2aaffab42efebf025b6a12c01af8fde Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 7 Feb 2013 16:15:23 +0100 Subject: Core/Accounts: sessionkey field in account table is only a temporary storage to pass data from authserver to worldserver and should only be used as such. Clearing sessionkey from database after a successful login to prevent possible exploits. --- sql/base/auth_database.sql | 2 +- sql/updates/auth/2013_02_07_00_auth_account.sql | 3 ++ src/server/game/Accounts/AccountMgr.cpp | 8 +++++ src/server/game/Server/WorldSocket.cpp | 35 ++++++++-------------- .../Database/Implementation/LoginDatabase.cpp | 3 +- .../shared/Database/Implementation/LoginDatabase.h | 1 + 6 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 sql/updates/auth/2013_02_07_00_auth_account.sql (limited to 'src') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 9aaadcb55d5..cdff87c245a 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -26,7 +26,7 @@ CREATE TABLE `account` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier', `username` varchar(32) NOT NULL DEFAULT '', `sha_pass_hash` varchar(40) NOT NULL DEFAULT '', - `sessionkey` varchar(80) NOT NULL DEFAULT '', + `sessionkey` varchar(80) NOT NULL DEFAULT '' COMMENT 'Temporary storage of session key used to pass data from authserver to worldserver', `v` varchar(64) NOT NULL DEFAULT '', `s` varchar(64) NOT NULL DEFAULT '', `email` varchar(254) NOT NULL DEFAULT '', diff --git a/sql/updates/auth/2013_02_07_00_auth_account.sql b/sql/updates/auth/2013_02_07_00_auth_account.sql new file mode 100644 index 00000000000..03bdf8cdcd5 --- /dev/null +++ b/sql/updates/auth/2013_02_07_00_auth_account.sql @@ -0,0 +1,3 @@ +UPDATE `account` SET `sessionkey`=''; +ALTER TABLE `account` +CHANGE `sessionkey` `sessionkey` varchar(80) NOT NULL DEFAULT '' COMMENT 'Temporary storage of session key used to pass data from authserver to worldserver' AFTER `sha_pass_hash`; diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index ce382342de8..b1d0087c32c 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -187,6 +187,14 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass LoginDatabase.Execute(stmt); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS); + + stmt->setString(0, ""); + stmt->setString(1, ""); + stmt->setString(2, username); + + LoginDatabase.Execute(stmt); + return AOR_OK; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 8b102518e84..5260b5f77a9 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -750,7 +750,6 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) uint32 clientBuild; uint32 unk2, unk3, unk5, unk6, unk7; uint64 unk4; - BigNumber v, s, g, N; WorldPacket packet, SendAddonPacked; BigNumber k; @@ -779,6 +778,8 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) clientSeed); // Get the account information from the realmd database + // 0 1 2 3 4 5 6 7 8 + // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); stmt->setString(0, account); @@ -795,27 +796,11 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) Field* fields = result->Fetch(); - uint8 expansion = fields[6].GetUInt8(); + uint8 expansion = fields[4].GetUInt8(); uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION); if (expansion > world_expansion) expansion = world_expansion; - N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword (7); - - v.SetHexStr(fields[4].GetCString()); - s.SetHexStr (fields[5].GetCString()); - - const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free() - const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free() - - sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: (s, v) check s: %s v: %s", - sStr, - vStr); - - OPENSSL_free((void*)sStr); - OPENSSL_free((void*)vStr); - ///- Re-check ip locking (same check as in realmd). if (fields[3].GetUInt8() == 1) // if ip is locked { @@ -831,7 +816,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) k.SetHexStr(fields[1].GetCString()); - int64 mutetime = fields[7].GetInt64(); + int64 mutetime = fields[5].GetInt64(); //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { @@ -845,12 +830,12 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) LoginDatabase.Execute(stmt); } - locale = LocaleConstant (fields[8].GetUInt8()); + locale = LocaleConstant (fields[6].GetUInt8()); if (locale >= TOTAL_LOCALES) locale = LOCALE_enUS; - uint32 recruiter = fields[9].GetUInt32(); - std::string os = fields[10].GetString(); + uint32 recruiter = fields[7].GetUInt32(); + std::string os = fields[8].GetString(); // Must be done before WorldSession is created if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED) && os != "Win" && os != "OSX") @@ -948,6 +933,12 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_CLEAR_SESSIONKEY); + + stmt->setUInt32(0, id); + + LoginDatabase.Execute(stmt); + m_Crypt.Init(&k); m_Session->LoadGlobalAccountData(); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index bbb51cfbde6..747f3ef1dc6 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -35,6 +35,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban', 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_UPD_CLEAR_SESSIONKEY, "UPDATE account SET sessionkey = '' WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); @@ -42,7 +43,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, v, s, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 939cc4b4790..6cd4ec99b79 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -53,6 +53,7 @@ enum LoginDatabaseStatements LOGIN_INS_ACCOUNT_AUTO_BANNED, LOGIN_DEL_ACCOUNT_BANNED, LOGIN_SEL_SESSIONKEY, + LOGIN_UPD_CLEAR_SESSIONKEY, LOGIN_UPD_VS, LOGIN_UPD_LOGONPROOF, LOGIN_SEL_LOGONCHALLENGE, -- cgit v1.2.3 From b6e56e42eaebbe509cb0574829afafdf31ba9d2c Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 8 Feb 2013 01:03:56 +0100 Subject: Core/Auth: Reverted part of fb43a92cc2aaffab42efebf025b6a12c01af8fde - session key is still needed after logging in to be able to switch realms --- sql/base/auth_database.sql | 2 +- sql/updates/auth/2013_02_08_00_auth_account.sql | 1 + src/server/authserver/Server/AuthSocket.cpp | 2 +- src/server/game/Server/WorldSocket.cpp | 6 ------ src/server/shared/Database/Implementation/LoginDatabase.cpp | 1 - src/server/shared/Database/Implementation/LoginDatabase.h | 1 - 6 files changed, 3 insertions(+), 10 deletions(-) create mode 100644 sql/updates/auth/2013_02_08_00_auth_account.sql (limited to 'src') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index cdff87c245a..9aaadcb55d5 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -26,7 +26,7 @@ CREATE TABLE `account` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier', `username` varchar(32) NOT NULL DEFAULT '', `sha_pass_hash` varchar(40) NOT NULL DEFAULT '', - `sessionkey` varchar(80) NOT NULL DEFAULT '' COMMENT 'Temporary storage of session key used to pass data from authserver to worldserver', + `sessionkey` varchar(80) NOT NULL DEFAULT '', `v` varchar(64) NOT NULL DEFAULT '', `s` varchar(64) NOT NULL DEFAULT '', `email` varchar(254) NOT NULL DEFAULT '', diff --git a/sql/updates/auth/2013_02_08_00_auth_account.sql b/sql/updates/auth/2013_02_08_00_auth_account.sql new file mode 100644 index 00000000000..49948781444 --- /dev/null +++ b/sql/updates/auth/2013_02_08_00_auth_account.sql @@ -0,0 +1 @@ +ALTER TABLE `account` CHANGE `sessionkey` `sessionkey` varchar(80) NOT NULL DEFAULT '' AFTER `sha_pass_hash`; diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index b0bce520d4f..32ddf029f1c 100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -207,7 +207,7 @@ AuthSocket::AuthSocket(RealmSocket& socket) : pPatch(NULL), socket_(socket) // Close patch file descriptor before leaving AuthSocket::~AuthSocket(void) {} -// Accept the connection and set the s random value for SRP6 +// Accept the connection void AuthSocket::OnAccept(void) { sLog->outDebug(LOG_FILTER_AUTHSERVER, "'%s:%d' Accepting connection", socket().getRemoteAddress().c_str(), socket().getRemotePort()); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 5260b5f77a9..b2534bfbb0c 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -933,12 +933,6 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_CLEAR_SESSIONKEY); - - stmt->setUInt32(0, id); - - LoginDatabase.Execute(stmt); - m_Crypt.Init(&k); m_Session->LoadGlobalAccountData(); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 747f3ef1dc6..a23294a038c 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -35,7 +35,6 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban', 1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_CLEAR_SESSIONKEY, "UPDATE account SET sessionkey = '' WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 6cd4ec99b79..939cc4b4790 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -53,7 +53,6 @@ enum LoginDatabaseStatements LOGIN_INS_ACCOUNT_AUTO_BANNED, LOGIN_DEL_ACCOUNT_BANNED, LOGIN_SEL_SESSIONKEY, - LOGIN_UPD_CLEAR_SESSIONKEY, LOGIN_UPD_VS, LOGIN_UPD_LOGONPROOF, LOGIN_SEL_LOGONCHALLENGE, -- cgit v1.2.3 From d6c0afa71c43b7534f71e127c07d213933bbaf00 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 8 Feb 2013 14:15:24 +0100 Subject: Core/AI: Fixed merge error --- src/server/game/AI/CreatureAISelector.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index 920c1c25533..a09feb6e00f 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -132,16 +132,12 @@ namespace FactorySelector const GameObjectAICreator* ai_factory = NULL; GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance()); + // scriptname in db if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go)) return scriptedAI; ai_factory = ai_registry.GetRegistryItem(go->GetAIName()); - // scriptname in db - if (!ai_factory) - if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go)) - return scriptedAI; - //future goAI types go here std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key(); -- cgit v1.2.3 From 97e876209ea7d097c010c2baef50970fee93d89c Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 8 Feb 2013 18:18:26 +0100 Subject: Core/Players: Fixed crash when mute expired while player was ingame --- src/server/game/Entities/Player/Player.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fd17fb908a1..37502d69456 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1575,7 +1575,9 @@ void Player::Update(uint32 p_time) GetSession()->m_muteTime = 0; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); // Set the mute time to 0 - stmt->setUInt32(1, GetSession()->GetAccountId()); + stmt->setString(1, ""); + stmt->setString(2, ""); + stmt->setUInt32(3, GetSession()->GetAccountId()); LoginDatabase.Execute(stmt); } -- cgit v1.2.3 From f902362ad1fb5681305a9eaac14e1c0ec55449e9 Mon Sep 17 00:00:00 2001 From: Nay Date: Fri, 8 Feb 2013 23:06:00 +0000 Subject: Core/DBLayer: Avoid a crash when calling mysql_get_server_version if connection was not open --- src/server/shared/Database/DatabaseWorkerPool.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 9f93e99ab26..fa02b1d369a 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -77,7 +77,8 @@ class DatabaseWorkerPool { T* t = new T(_queue, _connectionInfo); res &= t->Open(); - WPFatal (mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "TrinityCore does not support MySQL versions below 5.1"); + if (res) // only check mysql version if connection is valid + WPFatal(mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "TrinityCore does not support MySQL versions below 5.1"); _connections[IDX_ASYNC][i] = t; ++_connectionCount[IDX_ASYNC]; } -- cgit v1.2.3 From a7eef6a598d0db01d12cd6f3703b302fea2d9cbb Mon Sep 17 00:00:00 2001 From: Gacko Date: Sat, 9 Feb 2013 16:24:31 +0100 Subject: Script/Quest: Kodo Roundup Closes #943 --- src/server/scripts/Kalimdor/zone_desolace.cpp | 108 +++++++------------------- 1 file changed, 26 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 8f55bb6102c..8dbeb989140 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -39,7 +39,6 @@ EndContentData */ enum DyingKodo { - // signed for 9999 SAY_SMEED_HOME = 0, QUEST_KODO = 5561, @@ -51,7 +50,7 @@ enum DyingKodo NPC_TAMED_KODO = 11627, SPELL_KODO_KOMBO_ITEM = 18153, - SPELL_KODO_KOMBO_PLAYER_BUFF = 18172, //spells here have unclear function, but using them at least for visual parts and checks + SPELL_KODO_KOMBO_PLAYER_BUFF = 18172, SPELL_KODO_KOMBO_DESPAWN_BUFF = 18377, SPELL_KODO_KOMBO_GOSSIP = 18362 @@ -66,110 +65,55 @@ public: { if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) { - //the expected quest objective - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - + player->TalkedToCreature(creature->GetEntry(), 0); player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF); - creature->GetMotionMaster()->MoveIdle(); } player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); return true; } - bool EffectDummyCreature(Unit* pCaster, uint32 spellId, uint32 effIndex, Creature* creatureTarget) - { - //always check spellid and effectindex - if (spellId == SPELL_KODO_KOMBO_ITEM && effIndex == 0) - { - //no effect if player/creature already have aura from spells - if (pCaster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || creatureTarget->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - return true; - - if (creatureTarget->GetEntry() == NPC_AGED_KODO || - creatureTarget->GetEntry() == NPC_DYING_KODO || - creatureTarget->GetEntry() == NPC_ANCIENT_KODO) - { - pCaster->CastSpell(pCaster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); - - creatureTarget->UpdateEntry(NPC_TAMED_KODO); - creatureTarget->CastSpell(creatureTarget, SPELL_KODO_KOMBO_DESPAWN_BUFF, false); - - if (creatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - creatureTarget->GetMotionMaster()->MoveIdle(); - - creatureTarget->GetMotionMaster()->MoveFollow(pCaster, PET_FOLLOW_DIST, creatureTarget->GetFollowAngle()); - } - - //always return true when we are handling this spell and effect - return true; - } - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_aged_dying_ancient_kodoAI(creature); - } - struct npc_aged_dying_ancient_kodoAI : public ScriptedAI { - npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { Reset(); } - - uint32 DespawnTimer; + npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) {} - void Reset() + void MoveInLineOfSight(Unit* who) { - DespawnTimer = 0; + if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP)) + { + me->GetMotionMaster()->Clear(); + DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); + if (Creature* smeed = who->ToCreature()) + smeed->AI()->Talk(SAY_SMEED_HOME); + } } - void MoveInLineOfSight(Unit* who) + void SpellHit(Unit* caster, SpellInfo const* spell) { - if (who->GetEntry() == NPC_SMEED) + if (spell->Id == SPELL_KODO_KOMBO_ITEM) { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return; - - if (me->IsWithinDistInMap(who, 10.0f)) + if (!(caster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || me->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) + && (me->GetEntry() == NPC_AGED_KODO || me->GetEntry() == NPC_DYING_KODO || me->GetEntry() == NPC_ANCIENT_KODO)) { - if (Creature* talker = who->ToCreature()) - talker->AI()->Talk(SAY_SMEED_HOME); + caster->CastSpell(caster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); + DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true); - //spell have no implemented effect (dummy), so useful to notify spellHit - DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); + me->UpdateEntry(NPC_TAMED_KODO); + me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); } } - } - - void SpellHit(Unit* /*pCaster*/, SpellInfo const* pSpell) - { - if (pSpell->Id == SPELL_KODO_KOMBO_GOSSIP) + else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) { me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DespawnTimer = 60000; + me->DespawnOrUnsummon(60000); } } - - void UpdateAI(const uint32 diff) - { - //timer should always be == 0 unless we already updated entry of creature. Then not expect this updated to ever be in combat. - if (DespawnTimer && DespawnTimer <= diff) - { - if (!me->getVictim() && me->isAlive()) - { - Reset(); - me->setDeathState(JUST_DIED); - me->Respawn(); - return; - } - } else DespawnTimer -= diff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_aged_dying_ancient_kodoAI(creature); + } }; -- cgit v1.2.3 From 985de41421f33178cffd2247ab14369334e801ee Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 9 Feb 2013 17:57:27 +0100 Subject: Core/SAI: Rewrite SmartAI::RemoveAuras in a safer way --- src/server/game/AI/SmartScripts/SmartAI.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index e568a36abc4..501bc35b77a 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -430,13 +430,14 @@ void SmartAI::MovementInform(uint32 MovementType, uint32 Data) void SmartAI::RemoveAuras() { - // Only loop throught the applied auras, because here is where all auras on the current unit are stored - Unit::AuraApplicationMap appliedAuras = me->GetAppliedAuras(); - for (Unit::AuraApplicationMap::iterator iter = appliedAuras.begin(); iter != appliedAuras.end(); ++iter) + Unit::AuraApplicationMap& appliedAuras = me->GetAppliedAuras(); + for (Unit::AuraApplicationMap::iterator iter = appliedAuras.begin(); iter != appliedAuras.end();) { Aura const* aura = iter->second->GetBase(); - if (!aura->GetSpellInfo()->IsPassive() && !aura->GetSpellInfo()->HasAura(SPELL_AURA_CONTROL_VEHICLE) && aura->GetCaster() != me) - me->RemoveAurasDueToSpell(aura->GetId()); + if (!aura->IsPassive() && !aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE) && aura->GetCasterGUID() != me->GetGUID()) + me->RemoveAura(iter); + else + ++iter; } } -- cgit v1.2.3