mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
Merge branch 'master' into 310
Conflicts: src/game/Level2.cpp src/game/PetHandler.cpp src/game/Player.cpp src/game/Player.h src/game/SkillHandler.cpp
This commit is contained in:
commit
31b3ee95ad
163 changed files with 5278 additions and 3233 deletions
|
|
@ -12,10 +12,15 @@ cmake_minimum_required (VERSION 2.6)
|
|||
project (MANGOS_MAP_EXTRACTOR)
|
||||
|
||||
add_subdirectory (libmpq)
|
||||
add_subdirectory (loadlib)
|
||||
|
||||
include_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq)
|
||||
link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq)
|
||||
include_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/loadlib)
|
||||
|
||||
add_executable (ad adt.cpp dbcfile.cpp mpq_libmpq.cpp System.cpp)
|
||||
link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq)
|
||||
link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/loadlib)
|
||||
|
||||
add_executable (ad dbcfile.cpp mpq_libmpq.cpp System.cpp)
|
||||
|
||||
target_link_libraries (ad libmpq)
|
||||
target_link_libraries (ad loadlib)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
#include "dbcfile.h"
|
||||
#include "mpq_libmpq.h"
|
||||
|
||||
extern unsigned int iRes;
|
||||
extern ArchiveSet gOpenArchives;
|
||||
#include "loadlib/adt.h"
|
||||
#include "loadlib/wdt.h"
|
||||
|
||||
bool ConvertADT(char*, char*);
|
||||
extern ArchiveSet gOpenArchives;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -25,10 +25,6 @@ typedef struct
|
|||
uint32 id;
|
||||
} map_id;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
map_id *map_ids;
|
||||
uint16 *areas;
|
||||
uint16 *LiqType;
|
||||
|
|
@ -36,18 +32,44 @@ char output_path[128] = ".";
|
|||
char input_path[128] = ".";
|
||||
uint32 maxAreaId = 0;
|
||||
|
||||
//**************************************************
|
||||
// Extractor options
|
||||
//**************************************************
|
||||
enum Extract
|
||||
{
|
||||
EXTRACT_MAP = 1,
|
||||
EXTRACT_DBC = 2
|
||||
};
|
||||
int extract = EXTRACT_MAP | EXTRACT_DBC;
|
||||
|
||||
// Select data for extract
|
||||
int CONF_extract = EXTRACT_MAP | EXTRACT_DBC;
|
||||
// This option allow limit minimum height to some value (Allow save some memory)
|
||||
bool CONF_allow_height_limit = true;
|
||||
float CONF_use_minHeight = -500.0f;
|
||||
|
||||
// This option allow use float to int conversion
|
||||
bool CONF_allow_float_to_int = true;
|
||||
float CONF_float_to_int8_limit = 2.0f; // Max accuracy = val/256
|
||||
float CONF_float_to_int16_limit = 2048.0f; // Max accuracy = val/65536
|
||||
float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - surface is flat
|
||||
float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat
|
||||
|
||||
// List MPQ for extract from
|
||||
char *CONF_mpq_list[]={
|
||||
"common.MPQ",
|
||||
"common-2.MPQ",
|
||||
"lichking.MPQ",
|
||||
"expansion.MPQ",
|
||||
"patch.MPQ",
|
||||
"patch-2.MPQ",
|
||||
"patch-3.MPQ",
|
||||
"patch-4.MPQ",
|
||||
"patch-5.MPQ",
|
||||
};
|
||||
|
||||
static char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
|
||||
#define LANG_COUNT 12
|
||||
|
||||
#define ADT_RES 64
|
||||
|
||||
void CreateDir( const std::string& Path )
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
|
@ -70,7 +92,14 @@ bool FileExists( const char* FileName )
|
|||
|
||||
void Usage(char* prg)
|
||||
{
|
||||
printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", prg, prg);
|
||||
printf(
|
||||
"Usage:\n"\
|
||||
"%s -[var] [value]\n"\
|
||||
"-i set input path\n"\
|
||||
"-o set output path\n"\
|
||||
"-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\
|
||||
"-f height stored as int (less map size but lost some accuracy) 1 by default\n"\
|
||||
"Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -80,8 +109,9 @@ void HandleArgs(int argc, char * arg[])
|
|||
{
|
||||
// i - input path
|
||||
// o - output path
|
||||
// r - resolution, array of (r * r) heights will be created
|
||||
// e - extract only MAP(1)/DBC(2) - standard both(3)
|
||||
// f - use float to int conversion
|
||||
// h - limit minimum height
|
||||
if(arg[c][0] != '-')
|
||||
Usage(arg[0]);
|
||||
|
||||
|
|
@ -99,11 +129,17 @@ void HandleArgs(int argc, char * arg[])
|
|||
else
|
||||
Usage(arg[0]);
|
||||
break;
|
||||
case 'f':
|
||||
if(c + 1 < argc) // all ok
|
||||
CONF_allow_float_to_int=atoi(arg[(c++) + 1])!=0;
|
||||
else
|
||||
Usage(arg[0]);
|
||||
break;
|
||||
case 'e':
|
||||
if(c + 1 < argc) // all ok
|
||||
{
|
||||
extract=atoi(arg[(c++) + 1]);
|
||||
if(!(extract > 0 && extract < 4))
|
||||
CONF_extract=atoi(arg[(c++) + 1]);
|
||||
if(!(CONF_extract > 0 && CONF_extract < 4))
|
||||
Usage(arg[0]);
|
||||
}
|
||||
else
|
||||
|
|
@ -165,10 +201,603 @@ void ReadLiquidTypeTableDBC()
|
|||
printf("Done! (%u LiqTypes loaded)\n", LiqType_count);
|
||||
}
|
||||
|
||||
//
|
||||
// Adt file convertor function and data
|
||||
//
|
||||
|
||||
// Map file format data
|
||||
#define MAP_MAGIC 'SPAM'
|
||||
#define MAP_VERSION_MAGIC '0.1w'
|
||||
#define MAP_AREA_MAGIC 'AERA'
|
||||
#define MAP_HEIGTH_MAGIC 'TGHM'
|
||||
#define MAP_LIQUID_MAGIC 'QILM'
|
||||
|
||||
struct map_fileheader{
|
||||
uint32 mapMagic;
|
||||
uint32 versionMagic;
|
||||
uint32 areaMapOffset;
|
||||
uint32 areaMapSize;
|
||||
uint32 heightMapOffset;
|
||||
uint32 heightMapSize;
|
||||
uint32 liquidMapOffset;
|
||||
uint32 liquidMapSize;
|
||||
};
|
||||
|
||||
#define MAP_AREA_NO_AREA 0x0001
|
||||
struct map_areaHeader{
|
||||
uint32 fourcc;
|
||||
uint16 flags;
|
||||
uint16 gridArea;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HIGHT 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_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
|
||||
|
||||
|
||||
#define MAP_LIQUID_NO_TYPE 0x0001
|
||||
#define MAP_LIQUID_NO_HIGHT 0x0002
|
||||
|
||||
struct map_liquidHeader{
|
||||
uint32 fourcc;
|
||||
uint16 flags;
|
||||
uint16 liquidType;
|
||||
uint8 offsetX;
|
||||
uint8 offsetY;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
float liquidLevel;
|
||||
};
|
||||
|
||||
float selectUInt8StepStore(float maxDiff)
|
||||
{
|
||||
return 255 / maxDiff;
|
||||
}
|
||||
|
||||
float selectUInt16StepStore(float maxDiff)
|
||||
{
|
||||
return 65535 / maxDiff;
|
||||
}
|
||||
// Temporary grid data store
|
||||
uint16 area_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
|
||||
float V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
float V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
uint16 uint16_V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
uint16 uint16_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
uint8 uint8_V8[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
uint8 uint8_V9[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
|
||||
uint8 liquid_type[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE];
|
||||
float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
|
||||
|
||||
bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
|
||||
{
|
||||
ADT_file adt;
|
||||
|
||||
if (!adt.loadFile(filename))
|
||||
return false;
|
||||
|
||||
adt_MCIN *cells = adt.a_grid->getMCIN();
|
||||
if (!cells)
|
||||
{
|
||||
printf("Can't find cells in '%s'\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(liquid_show, 0, sizeof(liquid_show));
|
||||
memset(liquid_type, 0, sizeof(liquid_type));
|
||||
|
||||
// Prepare map header
|
||||
map_fileheader map;
|
||||
map.mapMagic = MAP_MAGIC;
|
||||
map.versionMagic = MAP_VERSION_MAGIC;
|
||||
|
||||
// Get area flags data
|
||||
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);
|
||||
uint32 areaid = cell->areaid;
|
||||
if(areaid && areaid <= maxAreaId)
|
||||
{
|
||||
if(areas[areaid] != 0xffff)
|
||||
{
|
||||
area_flags[i][j] = areas[areaid];
|
||||
continue;
|
||||
}
|
||||
printf("File: filename\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy);
|
||||
}
|
||||
area_flags[i][j] = 0xffff;
|
||||
}
|
||||
}
|
||||
//============================================
|
||||
// Try pack area data
|
||||
//============================================
|
||||
bool fullAreaData = false;
|
||||
uint32 areaflag = area_flags[0][0];
|
||||
for (int y=0;y<ADT_CELLS_PER_GRID;y++)
|
||||
{
|
||||
for(int x=0;x<ADT_CELLS_PER_GRID;x++)
|
||||
{
|
||||
if(area_flags[y][x]!=areaflag)
|
||||
{
|
||||
fullAreaData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.areaMapOffset = sizeof(map);
|
||||
map.areaMapSize = sizeof(map_areaHeader);
|
||||
|
||||
map_areaHeader areaHeader;
|
||||
areaHeader.fourcc = MAP_AREA_MAGIC;
|
||||
areaHeader.flags = 0;
|
||||
if (fullAreaData)
|
||||
{
|
||||
areaHeader.gridArea = 0;
|
||||
map.areaMapSize+=sizeof(area_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
areaHeader.flags |= MAP_AREA_NO_AREA;
|
||||
areaHeader.gridArea = (uint16)areaflag;
|
||||
}
|
||||
|
||||
//
|
||||
// Get Height map from grid
|
||||
//
|
||||
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;
|
||||
// Height values for triangles stored in order:
|
||||
// 1 2 3 4 5 6 7 8 9
|
||||
// 10 11 12 13 14 15 16 17
|
||||
// 18 19 20 21 22 23 24 25 26
|
||||
// 27 28 29 30 31 32 33 34
|
||||
// . . . . . . . .
|
||||
// For better get height values merge it to V9 and V8 map
|
||||
// V9 height map:
|
||||
// 1 2 3 4 5 6 7 8 9
|
||||
// 18 19 20 21 22 23 24 25 26
|
||||
// . . . . . . . .
|
||||
// V8 height map:
|
||||
// 10 11 12 13 14 15 16 17
|
||||
// 27 28 29 30 31 32 33 34
|
||||
// . . . . . . . .
|
||||
|
||||
// Set map height as grid height
|
||||
for (int y=0; y <= ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x <= ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
V9[cy][cx]=cell->ypos;
|
||||
}
|
||||
}
|
||||
for (int y=0; y < ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x < ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
V8[cy][cx]=cell->ypos;
|
||||
}
|
||||
}
|
||||
// Get custom height
|
||||
adt_MCVT *v = cell->getMCVT();
|
||||
if (!v)
|
||||
continue;
|
||||
// get V9 height map
|
||||
for (int y=0; y <= ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x <= ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
V9[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+x];
|
||||
}
|
||||
}
|
||||
// get V8 height map
|
||||
for (int y=0; y < ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x < ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
V8[cy][cx]+=v->height_map[y*(ADT_CELL_SIZE*2+1)+ADT_CELL_SIZE+1+x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//============================================
|
||||
// Try pack height data
|
||||
//============================================
|
||||
float maxHeight = -20000;
|
||||
float minHeight = 20000;
|
||||
for (int y=0; y<ADT_GRID_SIZE; y++)
|
||||
{
|
||||
for(int x=0;x<ADT_GRID_SIZE;x++)
|
||||
{
|
||||
float h = V8[y][x];
|
||||
if (maxHeight < h) maxHeight = h;
|
||||
if (minHeight > h) minHeight = h;
|
||||
}
|
||||
}
|
||||
for (int y=0; y<=ADT_GRID_SIZE; y++)
|
||||
{
|
||||
for(int x=0;x<=ADT_GRID_SIZE;x++)
|
||||
{
|
||||
float h = V9[y][x];
|
||||
if (maxHeight < h) maxHeight = h;
|
||||
if (minHeight > h) minHeight = h;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for allow limit minimum height (not store height in deep ochean - allow save some memory)
|
||||
if (CONF_allow_height_limit && minHeight < CONF_use_minHeight)
|
||||
{
|
||||
for (int y=0; y<ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<ADT_GRID_SIZE;x++)
|
||||
if (V8[y][x] < CONF_use_minHeight)
|
||||
V8[y][x] = CONF_use_minHeight;
|
||||
for (int y=0; y<=ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<=ADT_GRID_SIZE;x++)
|
||||
if (V9[y][x] < CONF_use_minHeight)
|
||||
V9[y][x] = CONF_use_minHeight;
|
||||
if (minHeight < CONF_use_minHeight)
|
||||
minHeight = CONF_use_minHeight;
|
||||
if (maxHeight < CONF_use_minHeight)
|
||||
maxHeight = CONF_use_minHeight;
|
||||
}
|
||||
|
||||
map.heightMapOffset = map.areaMapOffset + map.areaMapSize;
|
||||
map.heightMapSize = sizeof(map_heightHeader);
|
||||
|
||||
map_heightHeader heightHeader;
|
||||
heightHeader.fourcc = MAP_HEIGTH_MAGIC;
|
||||
heightHeader.flags = 0;
|
||||
heightHeader.gridHeight = minHeight;
|
||||
heightHeader.gridMaxHeight = maxHeight;
|
||||
|
||||
if (maxHeight == minHeight)
|
||||
heightHeader.flags |=MAP_HEIGHT_NO_HIGHT;
|
||||
|
||||
// Not need store if flat surface
|
||||
if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit)
|
||||
heightHeader.flags |=MAP_HEIGHT_NO_HIGHT;
|
||||
|
||||
// Try store as packed in uint16 or uint8 values
|
||||
if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT))
|
||||
{
|
||||
float step;
|
||||
// Try Store as uint values
|
||||
if (CONF_allow_float_to_int)
|
||||
{
|
||||
float diff = maxHeight - minHeight;
|
||||
if (diff < CONF_float_to_int8_limit) // As uint8 (max accuracy = CONF_float_to_int8_limit/256)
|
||||
{
|
||||
heightHeader.flags|=MAP_HEIGHT_AS_INT8;
|
||||
step = selectUInt8StepStore(diff);
|
||||
}
|
||||
else if (diff<CONF_float_to_int16_limit) // As uint16 (max accuracy = CONF_float_to_int16_limit/65536)
|
||||
{
|
||||
heightHeader.flags|=MAP_HEIGHT_AS_INT16;
|
||||
step = selectUInt16StepStore(diff);
|
||||
}
|
||||
}
|
||||
|
||||
// Pack it to int values if need
|
||||
if (heightHeader.flags&MAP_HEIGHT_AS_INT8)
|
||||
{
|
||||
for (int y=0; y<ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<ADT_GRID_SIZE;x++)
|
||||
uint8_V8[y][x] = uint8((V8[y][x] - minHeight) * step + 0.5f);
|
||||
for (int y=0; y<=ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<=ADT_GRID_SIZE;x++)
|
||||
uint8_V9[y][x] = uint8((V9[y][x] - minHeight) * step + 0.5f);
|
||||
map.heightMapSize+= sizeof(uint8_V9) + sizeof(uint8_V8);
|
||||
}
|
||||
else if (heightHeader.flags&MAP_HEIGHT_AS_INT16)
|
||||
{
|
||||
for (int y=0; y<ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<ADT_GRID_SIZE;x++)
|
||||
uint16_V8[y][x] = uint16((V8[y][x] - minHeight) * step + 0.5f);
|
||||
for (int y=0; y<=ADT_GRID_SIZE; y++)
|
||||
for(int x=0;x<=ADT_GRID_SIZE;x++)
|
||||
uint16_V9[y][x] = uint16((V9[y][x] - minHeight) * step + 0.5f);
|
||||
map.heightMapSize+= sizeof(uint16_V9) + sizeof(uint16_V8);
|
||||
}
|
||||
else
|
||||
map.heightMapSize+= sizeof(V9) + sizeof(V8);
|
||||
}
|
||||
|
||||
// Get liquid map for grid (in WOTLK used MH2O chunk)
|
||||
adt_MH2O * h2o = adt.a_grid->getMH2O();
|
||||
if (h2o)
|
||||
{
|
||||
for (int i=0;i<ADT_CELLS_PER_GRID;i++)
|
||||
{
|
||||
for(int j=0;j<ADT_CELLS_PER_GRID;j++)
|
||||
{
|
||||
adt_liquid_header *h = h2o->getLiquidData(i,j);
|
||||
if (!h)
|
||||
continue;
|
||||
|
||||
int count = 0;
|
||||
uint64 show = h2o->getLiquidShowMap(h);
|
||||
for (int y=0; y < h->height;y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y + h->yOffset;
|
||||
for (int x=0; x < h->width; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x + h->xOffset;
|
||||
if (show & 1)
|
||||
{
|
||||
liquid_show[cy][cx] = true;
|
||||
++count;
|
||||
}
|
||||
show>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 type = LiqType[h->liquidType];
|
||||
switch (type)
|
||||
{
|
||||
case LIQUID_TYPE_WATER: liquid_type[i][j] |= MAP_LIQUID_TYPE_WATER; break;
|
||||
case LIQUID_TYPE_OCEAN: liquid_type[i][j] |= MAP_LIQUID_TYPE_OCEAN; break;
|
||||
case LIQUID_TYPE_MAGMA: liquid_type[i][j] |= MAP_LIQUID_TYPE_MAGMA; break;
|
||||
case LIQUID_TYPE_SLIME: liquid_type[i][j] |= MAP_LIQUID_TYPE_SLIME; break;
|
||||
default:
|
||||
printf("\nCan't find Liquid type %u for map %s\nchunk %d,%d\n", h->liquidType, filename, i, j);
|
||||
break;
|
||||
}
|
||||
// Dark water detect
|
||||
if (type == LIQUID_TYPE_OCEAN)
|
||||
{
|
||||
uint8 *lm = h2o->getLiquidLightMap(h);
|
||||
if (!lm)
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
|
||||
}
|
||||
|
||||
if (!count && liquid_type[i][j])
|
||||
printf("Wrong liquid detect in MH2O chunk");
|
||||
|
||||
float *height = h2o->getLiquidHeightMap(h);
|
||||
int pos = 0;
|
||||
for (int y=0; y<=h->height;y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y + h->yOffset;
|
||||
for (int x=0; x<= h->width; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x + h->xOffset;
|
||||
if (height)
|
||||
liquid_height[cy][cx] = height[pos];
|
||||
else
|
||||
liquid_height[cy][cx] = h->heightLevel1;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get from MCLQ chunk (old)
|
||||
for (int i=0;i<ADT_CELLS_PER_GRID;i++)
|
||||
{
|
||||
for(int j=0;j<ADT_CELLS_PER_GRID;j++)
|
||||
{
|
||||
adt_MCNK *cell = cells->getMCNK(i, j);
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
adt_MCLQ *liquid = cell->getMCLQ();
|
||||
int count = 0;
|
||||
if (!liquid || cell->sizeMCLQ <= 8)
|
||||
continue;
|
||||
|
||||
for (int y=0; y < ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x < ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
if (liquid->flags[y][x] != 0x0F)
|
||||
{
|
||||
liquid_show[cy][cx] = true;
|
||||
if (liquid->flags[y][x]&(1<<7))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_DARK_WATER;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 c_flag = cell->flags;
|
||||
if(c_flag & (1<<2))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_WATER; // water
|
||||
if(c_flag & (1<<3))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_OCEAN; // ochean
|
||||
if(c_flag & (1<<4))
|
||||
liquid_type[i][j]|=MAP_LIQUID_TYPE_MAGMA; // magma/slime
|
||||
|
||||
if (!count && liquid_type[i][j])
|
||||
printf("Wrong liquid detect in MCLQ chunk");
|
||||
|
||||
for (int y=0; y <= ADT_CELL_SIZE; y++)
|
||||
{
|
||||
int cy = i*ADT_CELL_SIZE + y;
|
||||
for (int x=0; x<= ADT_CELL_SIZE; x++)
|
||||
{
|
||||
int cx = j*ADT_CELL_SIZE + x;
|
||||
liquid_height[cy][cx] = liquid->liquid[y][x].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
// Pack liquid data
|
||||
//============================================
|
||||
uint8 type = liquid_type[0][0];
|
||||
bool fullType = false;
|
||||
for (int y=0;y<ADT_CELLS_PER_GRID;y++)
|
||||
{
|
||||
for(int x=0;x<ADT_CELLS_PER_GRID;x++)
|
||||
{
|
||||
if (liquid_type[y][x]!=type)
|
||||
{
|
||||
fullType = true;
|
||||
y = ADT_CELLS_PER_GRID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map_liquidHeader liquidHeader;
|
||||
|
||||
// no water data (if all grid have 0 liquid type)
|
||||
if (type == 0 && !fullType)
|
||||
{
|
||||
// No liquid data
|
||||
map.liquidMapOffset = 0;
|
||||
map.liquidMapSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int minX = 255, minY = 255;
|
||||
int maxX = 0, maxY = 0;
|
||||
maxHeight = -20000;
|
||||
minHeight = 20000;
|
||||
for (int y=0; y<ADT_GRID_SIZE; y++)
|
||||
{
|
||||
for(int x=0; x<ADT_GRID_SIZE; x++)
|
||||
{
|
||||
if (liquid_show[y][x])
|
||||
{
|
||||
if (minX > x) minX = x;
|
||||
if (maxX < x) maxX = x;
|
||||
if (minY > y) minY = y;
|
||||
if (maxY < y) maxY = y;
|
||||
float h = liquid_height[y][x];
|
||||
if (maxHeight < h) maxHeight = h;
|
||||
if (minHeight > h) minHeight = h;
|
||||
}
|
||||
else
|
||||
liquid_height[y][x] = CONF_use_minHeight;
|
||||
}
|
||||
}
|
||||
map.liquidMapOffset = map.heightMapOffset + map.heightMapSize;
|
||||
map.liquidMapSize = sizeof(map_liquidHeader);
|
||||
liquidHeader.fourcc = MAP_LIQUID_MAGIC;
|
||||
liquidHeader.flags = 0;
|
||||
liquidHeader.liquidType = 0;
|
||||
liquidHeader.offsetX = minX;
|
||||
liquidHeader.offsetY = minY;
|
||||
liquidHeader.width = maxX - minX + 1;
|
||||
liquidHeader.height = maxY - minY + 1;
|
||||
liquidHeader.liquidLevel = minHeight;
|
||||
|
||||
if (maxHeight == minHeight)
|
||||
liquidHeader.flags|=MAP_LIQUID_NO_HIGHT;
|
||||
|
||||
// Not need store if flat surface
|
||||
if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit)
|
||||
liquidHeader.flags|=MAP_LIQUID_NO_HIGHT;
|
||||
|
||||
if (!fullType)
|
||||
liquidHeader.flags|=MAP_LIQUID_NO_TYPE;
|
||||
|
||||
if (liquidHeader.flags&MAP_LIQUID_NO_TYPE)
|
||||
liquidHeader.liquidType = type;
|
||||
else
|
||||
map.liquidMapSize+=sizeof(liquid_type);
|
||||
|
||||
if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT))
|
||||
map.liquidMapSize+=sizeof(float)*liquidHeader.width*liquidHeader.height;
|
||||
}
|
||||
|
||||
// Ok all data prepared - store it
|
||||
FILE *output=fopen(filename2, "wb");
|
||||
if(!output)
|
||||
{
|
||||
printf("Can't create the output file '%s'\n", filename2);
|
||||
return false;
|
||||
}
|
||||
fwrite(&map, sizeof(map), 1, output);
|
||||
// Store area data
|
||||
fwrite(&areaHeader, sizeof(areaHeader), 1, output);
|
||||
if (!(areaHeader.flags&MAP_AREA_NO_AREA))
|
||||
fwrite(area_flags, sizeof(area_flags), 1, output);
|
||||
|
||||
// Store height data
|
||||
fwrite(&heightHeader, sizeof(heightHeader), 1, output);
|
||||
if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT))
|
||||
{
|
||||
if (heightHeader.flags&MAP_HEIGHT_AS_INT16)
|
||||
{
|
||||
fwrite(uint16_V9, sizeof(uint16_V9), 1, output);
|
||||
fwrite(uint16_V8, sizeof(uint16_V8), 1, output);
|
||||
}
|
||||
else if (heightHeader.flags&MAP_HEIGHT_AS_INT8)
|
||||
{
|
||||
fwrite(uint8_V9, sizeof(uint8_V9), 1, output);
|
||||
fwrite(uint8_V8, sizeof(uint8_V8), 1, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(V9, sizeof(V9), 1, output);
|
||||
fwrite(V8, sizeof(V8), 1, output);
|
||||
}
|
||||
}
|
||||
|
||||
// Store liquid data if need
|
||||
if (map.liquidMapOffset)
|
||||
{
|
||||
fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
|
||||
if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE))
|
||||
fwrite(liquid_type, sizeof(liquid_type), 1, output);
|
||||
if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT))
|
||||
{
|
||||
for (int y=0; y<liquidHeader.height;y++)
|
||||
fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
|
||||
}
|
||||
}
|
||||
fclose(output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExtractMapsFromMpq()
|
||||
{
|
||||
char mpq_filename[1024];
|
||||
char output_filename[1024];
|
||||
char mpq_map_name[1024];
|
||||
|
||||
printf("Extracting maps...\n");
|
||||
|
||||
|
|
@ -177,35 +806,41 @@ void ExtractMapsFromMpq()
|
|||
ReadAreaTableDBC();
|
||||
ReadLiquidTypeTableDBC();
|
||||
|
||||
unsigned int total = map_count * ADT_RES * ADT_RES;
|
||||
unsigned int done = 0;
|
||||
|
||||
std::string path = output_path;
|
||||
path += "/maps/";
|
||||
CreateDir(path);
|
||||
|
||||
for(uint32 x = 0; x < ADT_RES; ++x)
|
||||
printf("Convert map files\n");
|
||||
for(uint32 z = 0; z < map_count; ++z)
|
||||
{
|
||||
for(uint32 y = 0; y < ADT_RES; ++y)
|
||||
printf("Extract %s (%d/%d) \n", map_ids[z].name, z+1, map_count);
|
||||
// Loadup map grid data
|
||||
sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name);
|
||||
WDT_file wdt;
|
||||
if (!wdt.loadFile(mpq_map_name, false))
|
||||
{
|
||||
for(uint32 z = 0; z < map_count; ++z)
|
||||
// printf("Error loading %s map wdt data\n", map_ids[z].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(uint32 y = 0; y < WDT_MAP_SIZE; ++y)
|
||||
{
|
||||
for(uint32 x = 0; x < WDT_MAP_SIZE; ++x)
|
||||
{
|
||||
if (!wdt.main->adt_list[y][x].exist)
|
||||
continue;
|
||||
sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y);
|
||||
sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x);
|
||||
ConvertADT(mpq_filename, output_filename);
|
||||
done++;
|
||||
ConvertADT(mpq_filename, output_filename, y, x);
|
||||
}
|
||||
// draw progress bar
|
||||
printf("Processing........................%d%%\r", (100 * done) / total);
|
||||
printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] areas;
|
||||
delete [] map_ids;
|
||||
}
|
||||
|
||||
//bool WMO(char* filename);
|
||||
|
||||
void ExtractDBCFiles(int locale, bool basicLocale)
|
||||
{
|
||||
printf("Extracting dbc files...\n");
|
||||
|
|
@ -277,21 +912,10 @@ void LoadLocaleMPQFiles(int const locale)
|
|||
void LoadCommonMPQFiles()
|
||||
{
|
||||
char filename[512];
|
||||
|
||||
sprintf(filename,"%s/Data/common-2.MPQ", input_path);
|
||||
new MPQArchive(filename);
|
||||
sprintf(filename,"%s/Data/lichking.MPQ", input_path);
|
||||
new MPQArchive(filename);
|
||||
sprintf(filename,"%s/Data/expansion.MPQ", input_path);
|
||||
new MPQArchive(filename);
|
||||
|
||||
for(int i = 1; i < 5; ++i)
|
||||
int count = sizeof(CONF_mpq_list)/sizeof(char*);
|
||||
for(int i = 0; i < count; ++i)
|
||||
{
|
||||
char ext[3] = "";
|
||||
if(i > 1)
|
||||
sprintf(ext, "-%i", i);
|
||||
|
||||
sprintf(filename, "%s/Data/patch%s.MPQ", input_path, ext);
|
||||
sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]);
|
||||
if(FileExists(filename))
|
||||
new MPQArchive(filename);
|
||||
}
|
||||
|
|
@ -323,7 +947,7 @@ int main(int argc, char * arg[])
|
|||
//Open MPQs
|
||||
LoadLocaleMPQFiles(i);
|
||||
|
||||
if((extract & EXTRACT_DBC) == 0)
|
||||
if((CONF_extract & EXTRACT_DBC) == 0)
|
||||
{
|
||||
FirstLocale = i;
|
||||
break;
|
||||
|
|
@ -349,7 +973,7 @@ int main(int argc, char * arg[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (extract & EXTRACT_MAP)
|
||||
if (CONF_extract & EXTRACT_MAP)
|
||||
{
|
||||
printf("Using locale: %s\n", langs[FirstLocale]);
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,15 @@
|
|||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\adt.cpp"
|
||||
RelativePath=".\loadlib\loadlib.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\adt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\wdt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
|
|
|||
|
|
@ -218,13 +218,17 @@
|
|||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\adt.cpp"
|
||||
RelativePath=".\loadlib\adt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dbcfile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\loadlib.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mpq_libmpq.cpp"
|
||||
>
|
||||
|
|
@ -253,6 +257,10 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\wdt.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="libmpq"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -216,7 +216,15 @@
|
|||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\adt.cpp"
|
||||
RelativePath=".\loadlib\loadlib.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\adt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loadlib\wdt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,380 +0,0 @@
|
|||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "adt.h"
|
||||
#include "mpq_libmpq.h"
|
||||
|
||||
extern uint16 *areas;
|
||||
extern uint16 *LiqType;
|
||||
extern uint32 maxAreaId;
|
||||
|
||||
vec wmoc;
|
||||
|
||||
Cell *cell;
|
||||
mcell *mcells;
|
||||
int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
|
||||
int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
|
||||
|
||||
bool LoadADT(char* filename)
|
||||
{
|
||||
size_t size;
|
||||
MPQFile mf(filename);
|
||||
|
||||
if(mf.isEof())
|
||||
{
|
||||
//printf("No such file %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
MapLiqFlag = new uint8[256];
|
||||
for(uint32 j = 0; j < 256; ++j)
|
||||
MapLiqFlag[j] = 0; // no water
|
||||
|
||||
MapLiqHeight = new float[16384];
|
||||
for(uint32 j = 0; j < 16384; ++j)
|
||||
MapLiqHeight[j] = -999999; // no water
|
||||
|
||||
mcells = new mcell;
|
||||
|
||||
wmoc.x = 65 * TILESIZE;
|
||||
wmoc.z = 65 * TILESIZE;
|
||||
|
||||
size_t mcnk_offsets[256], mcnk_sizes[256];
|
||||
|
||||
chunk_num = 0;
|
||||
k = 0;
|
||||
m = 0;
|
||||
while (!mf.isEof())
|
||||
{
|
||||
uint32 fourcc;
|
||||
mf.read(&fourcc, 4);
|
||||
mf.read(&size, 4);
|
||||
|
||||
size_t nextpos = mf.getPos() + size;
|
||||
|
||||
//if(fourcc==0x4d484452) // MHDR header
|
||||
//if(fourcc==0x4d564552) // MVER
|
||||
if(fourcc == 0x4d43494e) // MCIN
|
||||
{
|
||||
for (uint32 i = 0; i < 256; ++i)
|
||||
{
|
||||
mf.read(&mcnk_offsets[i], 4);
|
||||
mf.read(&mcnk_sizes[i], 4);
|
||||
mf.seekRelative(8);
|
||||
}
|
||||
}
|
||||
//if(fourcc == 0x4d544558) // MTEX textures (strings)
|
||||
//if(fourcc == 0x4d4d4458) // MMDX m2 models (strings)
|
||||
//if(fourcc == 0x4d4d4944) // MMID offsets for strings in MMDX
|
||||
//if(fourcc == 0x4d574d4f) // MWMO
|
||||
//if(fourcc == 0x4d574944) // MWID offsets for strings in MWMO
|
||||
//if(fourcc == 0x4d444446) // MDDF
|
||||
//if(fourcc == 0x4d4f4446) // MODF
|
||||
if(fourcc == 0x4d48324f) // MH2O new in WotLK
|
||||
{
|
||||
// çäåñü íàäî çàïîìíèòü áàçîâóþ ïîçèöèþ â ôàéëå òê âñå ñìåùåíèÿ áóäóò îò íåãî
|
||||
uint32 base_pos = mf.getPos();
|
||||
uint32 header_pos = 0;
|
||||
MH2O_offsData *LiqOffsData = new MH2O_offsData;
|
||||
MH2O_Data1 *LiqChunkData1 = new MH2O_Data1;
|
||||
float *ChunkLiqHeight = new float[81];
|
||||
for(chunk_num = 0; chunk_num < 256; ++chunk_num)
|
||||
{
|
||||
mf.read(LiqOffsData, 0x0C);
|
||||
header_pos = mf.getPos();
|
||||
if(LiqOffsData->offsData1 != 0) // åñëè äàííûå â Data1 î âîäå åñòü, òî èõ íàäî êîíâåðòèðîâàòü
|
||||
{
|
||||
// ïåðåõîäèì ïî ñìåùåíèþ èç offsData1 ÎÒ ÍÀ×ÀËÀ êóñêà
|
||||
mf.seek(base_pos + LiqOffsData->offsData1);
|
||||
mf.read(LiqChunkData1, 0x18); // ñ÷èòûâàåì ñàìè äàííûå â ñòðóêòóðó òèïà MH2O_Data1
|
||||
// çàíîñèì äàííûå ôëàãà äëÿ êóñêà
|
||||
if(LiqType[LiqChunkData1->LiquidTypeId] == 0xffff)
|
||||
printf("\nCan't find Liquid type for map %s\nchunk %d\n", filename, chunk_num);
|
||||
else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_WATER || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_OCEAN)
|
||||
MapLiqFlag[chunk_num] |= 1; // water/ocean
|
||||
else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_MAGMA || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_SLIME)
|
||||
MapLiqFlag[chunk_num] |= 2; // magma/slime
|
||||
// ïðåäâàðèòåëüíî çàïîëíÿåì âåñü êóñîê äàííûìè - íåò âîäû
|
||||
for(int j = 0; j < 81; ++j)
|
||||
{
|
||||
ChunkLiqHeight[j] = -999999; // no liquid/water
|
||||
}
|
||||
// òåïåðü âû÷èñëÿåì òå ÷òî ñ âîäîé è ïåðåçàïèñûâàåì èõ â êóñêå
|
||||
for(int b = 0; b <= LiqChunkData1->height; ++b)
|
||||
{
|
||||
for(int c = LiqChunkData1->xOffset; c <= (LiqChunkData1->xOffset + LiqChunkData1->width); ++c)
|
||||
{
|
||||
int n = (9 * (LiqChunkData1->yOffset + b)) + c;
|
||||
ChunkLiqHeight[n] = LiqChunkData1->heightLevel1;
|
||||
}
|
||||
}
|
||||
mf.seek(header_pos); // è íå çàáûòü âåðíóòüñÿ íà èñõîäíóþ ïîçèöèþ èìåííî Â ÕÈÄÅÐÅ
|
||||
}
|
||||
else // åñëè äàííûõ â Data1 íåò, òî íàäî çàïîëíèòü âåñü êóñîê, íî äàííûìè - íåò âîäû
|
||||
{
|
||||
for(int j = 0; j < 81; ++j)
|
||||
ChunkLiqHeight[j] = -999999; // no liquid/water
|
||||
}
|
||||
|
||||
if(!(chunk_num % 16))
|
||||
m = 1024 * (chunk_num / 16); // ñìåùåíèå ïî ðÿäàì êóñêîâ ñ ïåðåêðûòèåì = 1024
|
||||
k = m + (chunk_num % 16) * 8; // óñòàíàâëèâàåìñÿ íà íà÷àëüíûé èíäåêñ äëÿ çàïîëíåíèÿ ðÿäà
|
||||
// çàíîñèì äàííûå êóñêà â ìàññèâ äëÿ êàðòû, ñ ïåðåêðûòèåì è îáðåçàíèåì êóñêîâ òê äàííûõ 81
|
||||
// ýòî àíàëîã ñòàðîãî îáðåçàíèÿ ãðàíè÷íûõ ïðàâûõ-áîêîâûõ è íèæíèõ äàííûõ
|
||||
for(int p = 0; p < 72; p += 9) // íèæíèå 8 íå çàíîñèì òê îíè äóáëèðóåòñÿ ñëåä êóñêîì
|
||||
{
|
||||
for(int s = 0; s < 8; ++s) // 9 çíà÷åíèå â ñòðîêå íå çàíîñèì òê îíî äóáëèðóåòñÿ ñëåä êóñêîì, à â ïðàâûõ-áîêîâûõ îáðåçàåòñÿ äëÿ 128õ128
|
||||
{
|
||||
MapLiqHeight[k] = ChunkLiqHeight[p + s];
|
||||
++k;
|
||||
}
|
||||
k = k + 120;
|
||||
}
|
||||
}
|
||||
delete LiqOffsData;
|
||||
delete LiqChunkData1;
|
||||
delete []ChunkLiqHeight;
|
||||
|
||||
}
|
||||
//case 0x4d434e4b: // MCNK
|
||||
//case 0x4d46424f: // MFBO new in BC
|
||||
//case 0x4d545846: // MTXF new in WotLK
|
||||
mf.seek(nextpos);
|
||||
}
|
||||
|
||||
//printf("Loading chunks info\n");
|
||||
// read individual map chunks
|
||||
chunk_num = 0;
|
||||
k = 0;
|
||||
m = 0;
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
mf.seek((int)mcnk_offsets[j * 16 + i]);
|
||||
LoadMapChunk(mf, &(mcells->ch[i][j]));
|
||||
++chunk_num;
|
||||
}
|
||||
}
|
||||
mf.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isHole(int holes, int i, int j)
|
||||
{
|
||||
int testi = i / 2;
|
||||
int testj = j / 4;
|
||||
if(testi > 3) testi = 3;
|
||||
if(testj > 3) testj = 3;
|
||||
return (holes & holetab_h[testi] & holetab_v[testj]) != 0;
|
||||
}
|
||||
|
||||
inline void LoadMapChunk(MPQFile &mf, chunk *_chunk)
|
||||
{
|
||||
float h;
|
||||
uint32 fourcc;
|
||||
uint32 size;
|
||||
MapChunkHeader header;
|
||||
|
||||
mf.seekRelative(4);
|
||||
mf.read(&size, 4);
|
||||
|
||||
size_t lastpos = mf.getPos() + size;
|
||||
mf.read(&header, 0x80); // what if header size got changed?
|
||||
_chunk->area_id = header.areaid;
|
||||
|
||||
float xbase = header.xpos;
|
||||
float ybase = header.ypos;
|
||||
float zbase = header.zpos;
|
||||
zbase = TILESIZE * 32 - zbase;
|
||||
xbase = TILESIZE * 32 - xbase;
|
||||
if(wmoc.x > xbase) wmoc.x = xbase;
|
||||
if(wmoc.z > zbase) wmoc.z = zbase;
|
||||
int chunkflags = header.flags;
|
||||
//printf("LMC: flags %X\n", chunkflags);
|
||||
float zmin = 999999999.0f;
|
||||
float zmax = -999999999.0f;
|
||||
// must be there, bl!zz uses some crazy format
|
||||
while (mf.getPos() < lastpos)
|
||||
{
|
||||
mf.read(&fourcc, 4);
|
||||
mf.read(&size, 4);
|
||||
size_t nextpos = mf.getPos() + size;
|
||||
if(fourcc == 0x4d435654) // MCVT
|
||||
{
|
||||
for (int j = 0; j < 17; ++j)
|
||||
{
|
||||
for (int i = 0; i < ((j % 2) ? 8 : 9); ++i)
|
||||
{
|
||||
mf.read(&h, 4);
|
||||
float z = h + ybase;
|
||||
if (j % 2)
|
||||
{
|
||||
if(isHole(header.holes, i, j))
|
||||
_chunk->v8[i][j / 2] = -1000;
|
||||
else
|
||||
_chunk->v8[i][j / 2] = z;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isHole(header.holes, i, j))
|
||||
_chunk->v9[i][j / 2] = -1000;
|
||||
else
|
||||
_chunk->v9[i][j / 2] = z;
|
||||
}
|
||||
|
||||
if(z > zmax) zmax = z;
|
||||
//if(z < zmin) zmin = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(fourcc == 0x4d434e52) // MCNR
|
||||
{
|
||||
nextpos = mf.getPos() + 0x1C0; // size fix
|
||||
}
|
||||
else if(fourcc == 0x4d434c51) // íå áóäåì ó÷èòûâàòü åñëè óæå áûëè äàííûå â MH2O, ïåðåñòðàõîâêà :) // MCLQ
|
||||
{
|
||||
// liquid / water level
|
||||
char fcc1[5];
|
||||
mf.read(fcc1, 4);
|
||||
flipcc(fcc1);
|
||||
fcc1[4] = 0;
|
||||
float *ChunkLiqHeight = new float[81];
|
||||
|
||||
if (!strcmp(fcc1, "MCSE"))
|
||||
{
|
||||
for(int j = 0; j < 81; ++j)
|
||||
{
|
||||
ChunkLiqHeight[j] = -999999; // no liquid/water
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float maxheight;
|
||||
mf.read(&maxheight, 4);
|
||||
for(int j = 0; j < 81; ++j)
|
||||
{
|
||||
LiqData liq;
|
||||
mf.read(&liq, 8);
|
||||
|
||||
if(liq.height > maxheight)
|
||||
ChunkLiqHeight[j] = -999999;
|
||||
else
|
||||
ChunkLiqHeight[j] = h;
|
||||
}
|
||||
|
||||
if(chunkflags & 4 || chunkflags & 8)
|
||||
MapLiqFlag[chunk_num] |= 1; // water
|
||||
if(chunkflags & 16)
|
||||
MapLiqFlag[chunk_num] |= 2; // magma/slime
|
||||
}
|
||||
// çàïîëíåì òàê æå êàê â MH2O
|
||||
if(!(chunk_num % 16))
|
||||
m = 1024 * (chunk_num / 16);
|
||||
k = m + (chunk_num % 16) * 8;
|
||||
|
||||
for(int p = 0; p < 72; p += 9)
|
||||
{
|
||||
for(int s = 0; s < 8; ++s)
|
||||
{
|
||||
MapLiqHeight[k] = ChunkLiqHeight[p + s];
|
||||
++k;
|
||||
}
|
||||
k = k + 120;
|
||||
}
|
||||
delete []ChunkLiqHeight;
|
||||
break;
|
||||
}
|
||||
mf.seek(nextpos);
|
||||
}
|
||||
}
|
||||
|
||||
inline void TransformData()
|
||||
{
|
||||
cell = new Cell;
|
||||
|
||||
for(uint32 x = 0; x < 128; ++x)
|
||||
{
|
||||
for(uint32 y = 0; y < 128; ++y)
|
||||
{
|
||||
cell->v8[y][x] = (float)mcells->ch[x / 8][y / 8].v8[x % 8][y % 8];
|
||||
cell->v9[y][x] = (float)mcells->ch[x / 8][y / 8].v9[x % 8][y % 8];
|
||||
}
|
||||
|
||||
// extra 1 point on bounds
|
||||
cell->v9[128][x] = (float)mcells->ch[x / 8][15].v9[x % 8][8];
|
||||
// x == y
|
||||
cell->v9[x][128] = (float)mcells->ch[15][x / 8].v9[8][x % 8];
|
||||
|
||||
}
|
||||
|
||||
// and the last 1
|
||||
cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8];
|
||||
|
||||
delete mcells;
|
||||
}
|
||||
|
||||
const char MAP_MAGIC[] = "MAP_3.00";
|
||||
|
||||
bool ConvertADT(char *filename, char *filename2)
|
||||
{
|
||||
if(!LoadADT(filename))
|
||||
return false;
|
||||
|
||||
FILE *output=fopen(filename2, "wb");
|
||||
if(!output)
|
||||
{
|
||||
printf("Can't create the output file '%s'\n", filename2);
|
||||
delete [] MapLiqHeight;
|
||||
delete [] MapLiqFlag;
|
||||
return false;
|
||||
}
|
||||
|
||||
// write magic header
|
||||
fwrite(MAP_MAGIC, 1, 8, output);
|
||||
|
||||
for(uint32 x = 0; x < 16; ++x)
|
||||
{
|
||||
for(uint32 y = 0; y < 16; ++y)
|
||||
{
|
||||
if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id <= maxAreaId)
|
||||
{
|
||||
if(areas[mcells->ch[y][x].area_id] == 0xffff)
|
||||
printf("\nCan't find area flag for areaid %u.\n", mcells->ch[y][x].area_id);
|
||||
|
||||
fwrite(&areas[mcells->ch[y][x].area_id], 1, 2, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16 flag = 0xffff;
|
||||
fwrite(&flag, 1, 2, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(MapLiqFlag, 1, 256, output);
|
||||
delete [] MapLiqFlag;
|
||||
|
||||
fwrite(MapLiqHeight, sizeof(float), 16384, output);
|
||||
delete [] MapLiqHeight;
|
||||
|
||||
TransformData();
|
||||
|
||||
fwrite(&cell->v9, 1, sizeof(cell->v9), output);
|
||||
fwrite(&cell->v8, 1, sizeof(cell->v8), output);
|
||||
fclose(output);
|
||||
delete cell;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
#ifndef ADT_H
|
||||
#define ADT_H
|
||||
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
#define UNITSIZE (CHUNKSIZE / 8.0f)
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
class Liquid;
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} svec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} vec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec v[3];
|
||||
} triangle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float v9[16 * 8 + 1][16 * 8 + 1];
|
||||
float v8[16 * 8][16 * 8];
|
||||
} Cell;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double v9[9][9];
|
||||
double v8[8][8];
|
||||
uint16 area_id;
|
||||
} chunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
chunk ch[16][16];
|
||||
} mcell;
|
||||
|
||||
struct MapChunkHeader
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 ix;
|
||||
uint32 iy;
|
||||
uint32 nLayers;
|
||||
uint32 nDoodadRefs;
|
||||
uint32 ofsHeight;
|
||||
uint32 ofsNormal;
|
||||
uint32 ofsLayer;
|
||||
uint32 ofsRefs;
|
||||
uint32 ofsAlpha;
|
||||
uint32 sizeAlpha;
|
||||
uint32 ofsShadow;
|
||||
uint32 sizeShadow;
|
||||
uint32 areaid;
|
||||
uint32 nMapObjRefs;
|
||||
uint32 holes;
|
||||
uint16 s1;
|
||||
uint16 s2;
|
||||
uint32 d1;
|
||||
uint32 d2;
|
||||
uint32 d3;
|
||||
uint32 predTex;
|
||||
uint32 nEffectDoodad;
|
||||
uint32 ofsSndEmitters;
|
||||
uint32 nSndEmitters;
|
||||
uint32 ofsLiquid; // not use in WotLK
|
||||
uint32 sizeLiquid; // not use in WotLK
|
||||
float zpos;
|
||||
float xpos;
|
||||
float ypos;
|
||||
uint32 textureId; // new offsColorValues in WotLK
|
||||
uint32 props;
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 offsData1;
|
||||
uint32 used;
|
||||
uint32 offsData2;
|
||||
} MH2O_offsData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 LiquidTypeId;
|
||||
uint16 type;
|
||||
float heightLevel1;
|
||||
float heightLevel2;
|
||||
uint8 xOffset;
|
||||
uint8 yOffset;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
uint32 ofsData2a;
|
||||
uint32 ofsData2b;
|
||||
} MH2O_Data1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 unk1;
|
||||
uint16 unk2;
|
||||
float height;
|
||||
} LiqData;
|
||||
|
||||
enum LiquidType
|
||||
{
|
||||
LIQUID_TYPE_WATER = 0,
|
||||
LIQUID_TYPE_OCEAN = 1,
|
||||
LIQUID_TYPE_MAGMA = 2,
|
||||
LIQUID_TYPE_SLIME = 3
|
||||
};
|
||||
|
||||
class MPQFile;
|
||||
|
||||
float *MapLiqHeight;
|
||||
uint8 *MapLiqFlag;
|
||||
uint32 k, m, chunk_num;
|
||||
void LoadMapChunk(MPQFile &, chunk*);
|
||||
#endif
|
||||
13
contrib/extractor/loadlib/CMakeLists.txt
Normal file
13
contrib/extractor/loadlib/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
|
||||
#
|
||||
# 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.
|
||||
|
||||
add_library (loadlib loadlib.cpp adt.cpp wdt.cpp)
|
||||
# link loadlib with zlib
|
||||
target_link_libraries (loadlib z)
|
||||
131
contrib/extractor/loadlib/adt.cpp
Normal file
131
contrib/extractor/loadlib/adt.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "adt.h"
|
||||
|
||||
// Helper
|
||||
int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
|
||||
int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
|
||||
|
||||
bool isHole(int holes, int i, int j)
|
||||
{
|
||||
int testi = i / 2;
|
||||
int testj = j / 4;
|
||||
if(testi > 3) testi = 3;
|
||||
if(testj > 3) testj = 3;
|
||||
return (holes & holetab_h[testi] & holetab_v[testj]) != 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Adt file loader class
|
||||
//
|
||||
ADT_file::ADT_file()
|
||||
{
|
||||
a_grid = 0;
|
||||
}
|
||||
|
||||
ADT_file::~ADT_file()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
void ADT_file::free()
|
||||
{
|
||||
a_grid = 0;
|
||||
FileLoader::free();
|
||||
}
|
||||
|
||||
//
|
||||
// Adt file check function
|
||||
//
|
||||
bool ADT_file::prepareLoadedData()
|
||||
{
|
||||
// Check parent
|
||||
if (!FileLoader::prepareLoadedData())
|
||||
return false;
|
||||
|
||||
// Check and prepare MHDR
|
||||
a_grid = (adt_MHDR *)(GetData()+8+version->size);
|
||||
if (!a_grid->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MHDR::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MHDR')
|
||||
return false;
|
||||
|
||||
if (size!=sizeof(adt_MHDR)-8)
|
||||
return false;
|
||||
|
||||
// Check and prepare MCIN
|
||||
if (offsMCIN && !getMCIN()->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
// Check and prepare MH2O
|
||||
if (offsMH2O && !getMH2O()->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MCIN::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MCIN')
|
||||
return false;
|
||||
|
||||
// Check cells data
|
||||
for (int i=0; i<ADT_CELLS_PER_GRID;i++)
|
||||
for (int j=0; j<ADT_CELLS_PER_GRID;j++)
|
||||
if (cells[i][j].offsMCNK && !getMCNK(i,j)->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MH2O::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MH2O')
|
||||
return false;
|
||||
|
||||
// Check liquid data
|
||||
// for (int i=0; i<ADT_CELLS_PER_GRID;i++)
|
||||
// for (int j=0; j<ADT_CELLS_PER_GRID;j++)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MCNK::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MCNK')
|
||||
return false;
|
||||
|
||||
// Check height map
|
||||
if (offsMCVT && !getMCVT()->prepareLoadedData())
|
||||
return false;
|
||||
// Check liquid data
|
||||
if (offsMCLQ && !getMCLQ()->prepareLoadedData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MCVT::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MCVT')
|
||||
return false;
|
||||
|
||||
if (size != sizeof(adt_MCVT)-8)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adt_MCLQ::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MCLQ')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
289
contrib/extractor/loadlib/adt.h
Normal file
289
contrib/extractor/loadlib/adt.h
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
#ifndef ADT_H
|
||||
#define ADT_H
|
||||
|
||||
#include "loadlib.h"
|
||||
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
#define UNITSIZE (CHUNKSIZE / 8.0f)
|
||||
|
||||
enum LiquidType
|
||||
{
|
||||
LIQUID_TYPE_WATER = 0,
|
||||
LIQUID_TYPE_OCEAN = 1,
|
||||
LIQUID_TYPE_MAGMA = 2,
|
||||
LIQUID_TYPE_SLIME = 3
|
||||
};
|
||||
|
||||
//**************************************************************************************
|
||||
// ADT file class
|
||||
//**************************************************************************************
|
||||
#define ADT_CELLS_PER_GRID 16
|
||||
#define ADT_CELL_SIZE 8
|
||||
#define ADT_GRID_SIZE (ADT_CELLS_PER_GRID*ADT_CELL_SIZE)
|
||||
|
||||
//
|
||||
// Adt file height map chunk
|
||||
//
|
||||
class adt_MCVT
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
float height_map[(ADT_CELL_SIZE+1)*(ADT_CELL_SIZE+1)+ADT_CELL_SIZE*ADT_CELL_SIZE];
|
||||
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file liquid map chunk (old)
|
||||
//
|
||||
class adt_MCLQ
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
float height1;
|
||||
float height2;
|
||||
struct liquid_data{
|
||||
uint32 light;
|
||||
float height;
|
||||
} liquid[ADT_CELL_SIZE+1][ADT_CELL_SIZE+1];
|
||||
|
||||
// 1<<0 - ochen
|
||||
// 1<<1 - lava/slime
|
||||
// 1<<2 - water
|
||||
// 1<<6 - all water
|
||||
// 1<<7 - dark water
|
||||
// == 0x0F - not show liquid
|
||||
uint8 flags[ADT_CELL_SIZE][ADT_CELL_SIZE];
|
||||
uint8 data[84];
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file cell chunk
|
||||
//
|
||||
class adt_MCNK
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
uint32 flags;
|
||||
uint32 ix;
|
||||
uint32 iy;
|
||||
uint32 nLayers;
|
||||
uint32 nDoodadRefs;
|
||||
uint32 offsMCVT; // height map
|
||||
uint32 offsMCNR; // Normal vectors for each vertex
|
||||
uint32 offsMCLY; // Texture layer definitions
|
||||
uint32 offsMCRF; // A list of indices into the parent file's MDDF chunk
|
||||
uint32 offsMCAL; // Alpha maps for additional texture layers
|
||||
uint32 sizeMCAL;
|
||||
uint32 offsMCSH; // Shadow map for static shadows on the terrain
|
||||
uint32 sizeMCSH;
|
||||
uint32 areaid;
|
||||
uint32 nMapObjRefs;
|
||||
uint32 holes;
|
||||
uint16 s[2];
|
||||
uint32 data1;
|
||||
uint32 data2;
|
||||
uint32 data3;
|
||||
uint32 predTex;
|
||||
uint32 nEffectDoodad;
|
||||
uint32 offsMCSE;
|
||||
uint32 nSndEmitters;
|
||||
uint32 offsMCLQ; // Liqid level (old)
|
||||
uint32 sizeMCLQ; //
|
||||
float zpos;
|
||||
float xpos;
|
||||
float ypos;
|
||||
uint32 offsMCCV; // offsColorValues in WotLK
|
||||
uint32 props;
|
||||
uint32 effectId;
|
||||
|
||||
bool prepareLoadedData();
|
||||
adt_MCVT *getMCVT()
|
||||
{
|
||||
if (offsMCVT)
|
||||
return (adt_MCVT *)((uint8 *)this + offsMCVT);
|
||||
return 0;
|
||||
}
|
||||
adt_MCLQ *getMCLQ()
|
||||
{
|
||||
if (offsMCLQ)
|
||||
return (adt_MCLQ *)((uint8 *)this + offsMCLQ);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file grid chunk
|
||||
//
|
||||
class adt_MCIN
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
public:
|
||||
struct adt_CELLS{
|
||||
uint32 offsMCNK;
|
||||
uint32 size;
|
||||
uint32 flags;
|
||||
uint32 asyncId;
|
||||
} cells[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
|
||||
bool prepareLoadedData();
|
||||
// offset from begin file (used this-84)
|
||||
adt_MCNK *getMCNK(int x, int y)
|
||||
{
|
||||
if (cells[x][y].offsMCNK)
|
||||
return (adt_MCNK *)((uint8 *)this + cells[x][y].offsMCNK - 84);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#define ADT_LIQUID_HEADER_FULL_LIGHT 0x01
|
||||
#define ADT_LIQUID_HEADER_NO_HIGHT 0x02
|
||||
|
||||
struct adt_liquid_header{
|
||||
uint16 liquidType; // Index from LiquidType.dbc
|
||||
uint16 formatFlags;
|
||||
float heightLevel1;
|
||||
float heightLevel2;
|
||||
uint8 xOffset;
|
||||
uint8 yOffset;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
uint32 offsData2a;
|
||||
uint32 offsData2b;
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file liquid data chunk (new)
|
||||
//
|
||||
class adt_MH2O
|
||||
{
|
||||
public:
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
|
||||
struct adt_LIQUID{
|
||||
uint32 offsData1;
|
||||
uint32 used;
|
||||
uint32 offsData2;
|
||||
} liquid[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
|
||||
bool prepareLoadedData();
|
||||
|
||||
adt_liquid_header *getLiquidData(int x, int y)
|
||||
{
|
||||
if (liquid[x][y].used && liquid[x][y].offsData1)
|
||||
return (adt_liquid_header *)((uint8*)this + 8 + liquid[x][y].offsData1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float *getLiquidHeightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
return (float *)((uint8*)this + 8 + h->offsData2b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 *getLiquidLightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT)
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return (uint8 *)((uint8*)this + 8 + h->offsData2b);
|
||||
return (uint8 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 *getLiquidFullLightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (!(h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT))
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return (uint32 *)((uint8*)this + 8 + h->offsData2b);
|
||||
return (uint32 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 getLiquidShowMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->offsData2a)
|
||||
return *((uint64 *)((uint8*)this + 8 + h->offsData2a));
|
||||
else
|
||||
return 0xFFFFFFFFFFFFFFFFLL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file header chunk
|
||||
//
|
||||
class adt_MHDR
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
|
||||
uint32 pad;
|
||||
uint32 offsMCIN; // MCIN
|
||||
uint32 offsTex; // MTEX
|
||||
uint32 offsModels; // MMDX
|
||||
uint32 offsModelsIds; // MMID
|
||||
uint32 offsMapObejcts; // MWMO
|
||||
uint32 offsMapObejctsIds; // MWID
|
||||
uint32 offsDoodsDef; // MDDF
|
||||
uint32 offsObjectsDef; // MODF
|
||||
uint32 offsMFBO; // MFBO
|
||||
uint32 offsMH2O; // MH2O
|
||||
uint32 data1;
|
||||
uint32 data2;
|
||||
uint32 data3;
|
||||
uint32 data4;
|
||||
uint32 data5;
|
||||
public:
|
||||
bool prepareLoadedData();
|
||||
adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);}
|
||||
adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;}
|
||||
|
||||
};
|
||||
|
||||
class ADT_file : public FileLoader{
|
||||
public:
|
||||
bool prepareLoadedData();
|
||||
ADT_file();
|
||||
~ADT_file();
|
||||
void free();
|
||||
|
||||
adt_MHDR *a_grid;
|
||||
};
|
||||
|
||||
#endif
|
||||
64
contrib/extractor/loadlib/loadlib.cpp
Normal file
64
contrib/extractor/loadlib/loadlib.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "loadlib.h"
|
||||
#include "../mpq_libmpq.h"
|
||||
|
||||
class MPQFile;
|
||||
|
||||
FileLoader::FileLoader()
|
||||
{
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
version = 0;
|
||||
}
|
||||
|
||||
FileLoader::~FileLoader()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
bool FileLoader::loadFile(char *filename, bool log)
|
||||
{
|
||||
free();
|
||||
MPQFile mf(filename);
|
||||
if(mf.isEof())
|
||||
{
|
||||
if (log)
|
||||
printf("No such file %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
data_size = mf.getSize();
|
||||
|
||||
data = new uint8 [data_size];
|
||||
if (data)
|
||||
{
|
||||
mf.read(data, data_size);
|
||||
mf.close();
|
||||
if (prepareLoadedData())
|
||||
return true;
|
||||
}
|
||||
printf("Error loading %s", filename);
|
||||
mf.close();
|
||||
free();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileLoader::prepareLoadedData()
|
||||
{
|
||||
// Check version
|
||||
version = (file_MVER *) data;
|
||||
if (version->fcc != 'MVER')
|
||||
return false;
|
||||
if (version->ver != FILE_FORMAT_VERSION)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileLoader::free()
|
||||
{
|
||||
if (data) delete[] data;
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
version = 0;
|
||||
}
|
||||
57
contrib/extractor/loadlib/loadlib.h
Normal file
57
contrib/extractor/loadlib/loadlib.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef LOAD_LIB_H
|
||||
#define LOAD_LIB_H
|
||||
|
||||
#ifdef WIN32
|
||||
typedef __int64 int64;
|
||||
typedef long int32;
|
||||
typedef short int16;
|
||||
typedef char int8;
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned long uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#ifndef uint64_t
|
||||
#include <linux/types.h>
|
||||
#endif
|
||||
typedef int64_t int64;
|
||||
typedef long int32;
|
||||
typedef short int16;
|
||||
typedef char int8;
|
||||
typedef uint64_t uint64;
|
||||
typedef unsigned long uint32;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
#endif
|
||||
|
||||
#define FILE_FORMAT_VERSION 18
|
||||
|
||||
//
|
||||
// File version chunk
|
||||
//
|
||||
struct file_MVER
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
uint32 ver;
|
||||
};
|
||||
|
||||
class FileLoader{
|
||||
uint8 *data;
|
||||
uint32 data_size;
|
||||
public:
|
||||
virtual bool prepareLoadedData();
|
||||
uint8 *GetData() {return data;}
|
||||
uint32 GetDataSize() {return data_size;}
|
||||
|
||||
file_MVER *version;
|
||||
FileLoader();
|
||||
~FileLoader();
|
||||
bool loadFile(char *filename, bool log = true);
|
||||
virtual void free();
|
||||
};
|
||||
#endif
|
||||
62
contrib/extractor/loadlib/wdt.cpp
Normal file
62
contrib/extractor/loadlib/wdt.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "wdt.h"
|
||||
|
||||
bool wdt_MWMO::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MWMO')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wdt_MPHD::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MPHD')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wdt_MAIN::prepareLoadedData()
|
||||
{
|
||||
if (fcc != 'MAIN')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
WDT_file::WDT_file()
|
||||
{
|
||||
mphd = 0;
|
||||
main = 0;
|
||||
wmo = 0;
|
||||
}
|
||||
|
||||
WDT_file::~WDT_file()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
void WDT_file::free()
|
||||
{
|
||||
mphd = 0;
|
||||
main = 0;
|
||||
wmo = 0;
|
||||
FileLoader::free();
|
||||
}
|
||||
|
||||
bool WDT_file::prepareLoadedData()
|
||||
{
|
||||
// Check parent
|
||||
if (!FileLoader::prepareLoadedData())
|
||||
return false;
|
||||
|
||||
mphd = (wdt_MPHD *)((uint8*)version+version->size+8);
|
||||
if (!mphd->prepareLoadedData())
|
||||
return false;
|
||||
main = (wdt_MAIN *)((uint8*)mphd + mphd->size+8);
|
||||
if (!main->prepareLoadedData())
|
||||
return false;
|
||||
wmo = (wdt_MWMO *)((uint8*)main+ main->size+8);
|
||||
if (!wmo->prepareLoadedData())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
68
contrib/extractor/loadlib/wdt.h
Normal file
68
contrib/extractor/loadlib/wdt.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef WDT_H
|
||||
#define WDT_H
|
||||
#include "loadlib.h"
|
||||
|
||||
//**************************************************************************************
|
||||
// WDT file class and structures
|
||||
//**************************************************************************************
|
||||
#define WDT_MAP_SIZE 64
|
||||
|
||||
class wdt_MWMO{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
class wdt_MPHD{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
|
||||
uint32 data1;
|
||||
uint32 data2;
|
||||
uint32 data3;
|
||||
uint32 data4;
|
||||
uint32 data5;
|
||||
uint32 data6;
|
||||
uint32 data7;
|
||||
uint32 data8;
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
class wdt_MAIN{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
|
||||
struct adtData{
|
||||
uint32 exist;
|
||||
uint32 data1;
|
||||
} adt_list[64][64];
|
||||
|
||||
bool prepareLoadedData();
|
||||
};
|
||||
|
||||
class WDT_file : public FileLoader{
|
||||
public:
|
||||
bool prepareLoadedData();
|
||||
|
||||
WDT_file();
|
||||
~WDT_file();
|
||||
void free();
|
||||
|
||||
wdt_MPHD *mphd;
|
||||
wdt_MAIN *main;
|
||||
wdt_MWMO *wmo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#ifndef MPQ_H
|
||||
#define MPQ_H
|
||||
|
||||
#include "loadlib/loadlib.h"
|
||||
#include "libmpq/mpq.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
|
@ -13,7 +14,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
class MPQArchive
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
DROP TABLE IF EXISTS `db_version`;
|
||||
CREATE TABLE `db_version` (
|
||||
`version` varchar(120) default NULL,
|
||||
`required_7382_01_mangos_creature_template` bit(1) default NULL
|
||||
`required_7439_01_mangos_mangos_string` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -135,6 +135,7 @@ CREATE TABLE `areatrigger_teleport` (
|
|||
`heroic_key` mediumint(8) unsigned NOT NULL default '0',
|
||||
`heroic_key2` mediumint(8) unsigned NOT NULL default '0',
|
||||
`required_quest_done` int(11) unsigned NOT NULL default '0',
|
||||
`required_quest_done_heroic` int(11) unsigned NOT NULL default '0',
|
||||
`required_failed_text` text,
|
||||
`target_map` smallint(5) unsigned NOT NULL default '0',
|
||||
`target_position_x` float NOT NULL default '0',
|
||||
|
|
@ -1071,6 +1072,7 @@ CREATE TABLE `game_event` (
|
|||
`end_time` timestamp NOT NULL default '0000-00-00 00:00:00' COMMENT 'Absolute end date, the event will never start afler',
|
||||
`occurence` bigint(20) unsigned NOT NULL default '86400' COMMENT 'Delay in hours between occurences of the event',
|
||||
`length` bigint(20) unsigned NOT NULL default '43200' COMMENT 'Length in hours of the event',
|
||||
`holiday` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Client side holiday id',
|
||||
`description` varchar(255) default NULL COMMENT 'Description of the event displayed in console',
|
||||
PRIMARY KEY (`entry`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
|
@ -2407,6 +2409,7 @@ INSERT INTO `mangos_string` VALUES
|
|||
(172,'server console command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(173,'You changed runic power of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(174,'%s changed your runic power to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(175,'Liquid level: %f, ground: %f, type: %d, status: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(200,'No selection.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(201,'Object GUID is: lowpart %u highpart %X',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(202,'The name was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
@ -2812,7 +2815,6 @@ INSERT INTO `mangos_string` VALUES
|
|||
(723,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(724,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(725,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(726,'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(727,'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(728,'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(729,'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
@ -2833,6 +2835,11 @@ INSERT INTO `mangos_string` VALUES
|
|||
(744,'Modifying played count, arena points etc. for loaded arena teams, sending updated stats to online players...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(745,'Modification done.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(746,'Done flushing Arena points.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(750,'Not enough players. This game will close in %u mins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(751,'Not enough players. This game will close in %u seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(753,'The battle for Warsong Gulch begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(754,'The battle for Arathi Basin begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(755,'The battle for Eye of the Storm begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
@ -2843,6 +2850,11 @@ INSERT INTO `mangos_string` VALUES
|
|||
(808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(810,'|Hplayer:$N|h[$N]|h has earned the achievement $a!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(811,'Guild Master',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(812,'Officer',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(813,'Veteran',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(814,'Member',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(815,'Initiate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1000,'Exiting daemon...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1001,'Account deleted: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1002,'Account %s NOT deleted (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
|
|||
5
sql/updates/7388_01_mangos_mangos_string.sql
Normal file
5
sql/updates/7388_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7382_01_mangos_creature_template required_7388_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry IN (750,751);
|
||||
INSERT INTO mangos_string VALUES (750,'Not enough players. This game will close in %u mins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO mangos_string VALUES (751,'Not enough players. This game will close in %u seconds.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
4
sql/updates/7390_01_mangos_areatrigger_teleport.sql
Normal file
4
sql/updates/7390_01_mangos_areatrigger_teleport.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7388_01_mangos_mangos_string required_7390_01_mangos_areatrigger_teleport bit;
|
||||
|
||||
ALTER TABLE areatrigger_teleport
|
||||
ADD COLUMN required_quest_done_heroic int(11) unsigned NOT NULL default '0' AFTER required_quest_done;
|
||||
4
sql/updates/7393_01_mangos_game_event.sql
Normal file
4
sql/updates/7393_01_mangos_game_event.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7390_01_mangos_areatrigger_teleport required_7393_01_mangos_game_event bit;
|
||||
|
||||
ALTER TABLE game_event
|
||||
ADD COLUMN holiday mediumint(8) unsigned NOT NULL default '0' COMMENT 'Client side holiday id' AFTER length;
|
||||
6
sql/updates/7399_01_mangos_mangos_string.sql
Normal file
6
sql/updates/7399_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7393_01_mangos_game_event required_7399_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry in (753, 754, 755);
|
||||
INSERT INTO mangos_string VALUES (753,'The battle for Warsong Gulch begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO mangos_string VALUES (754,'The battle for Arathi Basin begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO mangos_string VALUES (755,'The battle for Eye of the Storm begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
9
sql/updates/7422_01_mangos_mangos_string.sql
Normal file
9
sql/updates/7422_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7399_01_mangos_mangos_string required_7422_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry in (811, 812, 813, 814, 815);
|
||||
INSERT INTO mangos_string VALUES
|
||||
(811,'Guild Master',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(812,'Officer',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(813,'Veteran',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(814,'Member',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(815,'Initiate',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
5
sql/updates/7439_01_mangos_mangos_string.sql
Normal file
5
sql/updates/7439_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7422_01_mangos_mangos_string required_7439_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry in (175);
|
||||
INSERT INTO mangos_string VALUES
|
||||
(175,'Liquid level: %f, ground: %f, type: %d, status: %d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
|
|
@ -191,6 +191,12 @@ pkgdata_DATA = \
|
|||
7369_01_mangos_quest_template.sql \
|
||||
7376_01_mangos_spell_area.sql \
|
||||
7382_01_mangos_creature_template.sql \
|
||||
7388_01_mangos_mangos_string.sql \
|
||||
7390_01_mangos_areatrigger_teleport.sql \
|
||||
7393_01_mangos_game_event.sql \
|
||||
7399_01_mangos_mangos_string.sql \
|
||||
7422_01_mangos_mangos_string.sql \
|
||||
7439_01_mangos_mangos_string.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -362,4 +368,10 @@ EXTRA_DIST = \
|
|||
7369_01_mangos_quest_template.sql \
|
||||
7376_01_mangos_spell_area.sql \
|
||||
7382_01_mangos_creature_template.sql \
|
||||
7388_01_mangos_mangos_string.sql \
|
||||
7390_01_mangos_areatrigger_teleport.sql \
|
||||
7393_01_mangos_game_event.sql \
|
||||
7399_01_mangos_mangos_string.sql \
|
||||
7422_01_mangos_mangos_string.sql \
|
||||
7439_01_mangos_mangos_string.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
# define MANGOS_GET_PROC_ADDR dlsym
|
||||
# if defined(__APPLE_CC__) && defined(BIG_ENDIAN)
|
||||
# define MANGOS_IMPORT __attribute__ ((longcall))
|
||||
# elif defined(__x86_64__)
|
||||
# define MANGOS_IMPORT
|
||||
# else
|
||||
# define MANGOS_IMPORT __attribute__ ((cdecl))
|
||||
# endif //__APPLE_CC__ && BIG_ENDIAN
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@
|
|||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Database/DBCEnums.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Guild.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GameEvent.h"
|
||||
#include "World.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "ArenaTeam.h"
|
||||
|
|
@ -308,7 +308,10 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
|
|||
|
||||
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
|
||||
{
|
||||
sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
|
||||
#ifdef MANGOS_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
|
||||
sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
|
||||
#endif
|
||||
|
||||
if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()))
|
||||
{
|
||||
|
|
@ -392,7 +395,8 @@ static const uint32 achievIdForDangeon[][4] =
|
|||
*/
|
||||
void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
|
||||
{
|
||||
sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
|
||||
if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
|
||||
sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
|
||||
return;
|
||||
|
|
@ -455,6 +459,54 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
continue;
|
||||
if(achievementCriteria->kill_creature.creatureID != miscvalue1)
|
||||
continue;
|
||||
|
||||
// LOT achievement->ID required special custom checks
|
||||
switch(achievement->ID)
|
||||
{
|
||||
// Just heroic
|
||||
case 489: case 490: case 491: case 492: case 493: case 494: case 495:
|
||||
case 496: case 497: case 498: case 499: case 500: case 563: case 565:
|
||||
case 567: case 569: case 573: case 575: case 577: case 623: case 625:
|
||||
case 667: case 668: case 669: case 670: case 671: case 672: case 673:
|
||||
case 674: case 675: case 676: case 677: case 678: case 679: case 680:
|
||||
case 681: case 682: case 1367: case 1368: case 1378: case 1379:
|
||||
case 1380: case 1381: case 1382: case 1383: case 1384: case 1385:
|
||||
case 1386: case 1387: case 1388: case 1389: case 1390: case 1393:
|
||||
case 1394: case 1400: case 1402: case 1504: case 1505: case 1506:
|
||||
case 1507: case 1508: case 1509: case 1510: case 1511: case 1512:
|
||||
case 1513: case 1514: case 1515: case 1721: case 1754: case 1756:
|
||||
case 1768: case 1817: case 1865:
|
||||
if(GetPlayer()->GetDifficulty()!=DIFFICULTY_HEROIC)
|
||||
continue;
|
||||
break;
|
||||
// Heroic + other
|
||||
case 579: case 1296: case 1297: case 1816: case 1834: case 1857: case 1859:
|
||||
case 1860: case 1861: case 1862: case 1864: case 1866: case 1867: case 1868:
|
||||
case 1870: case 1871: case 1872: case 1873: case 1875: case 1877: case 1919:
|
||||
case 2036: case 2037: case 2038: case 2039: case 2040: case 2041: case 2042:
|
||||
case 2043: case 2044: case 2045: case 2046: case 2048: case 2052: case 2053:
|
||||
case 2054: case 2056: case 2057: case 2058: case 2139: case 2140: case 2147:
|
||||
case 2149: case 2150: case 2151: case 2152: case 2154: case 2155: case 2156:
|
||||
case 2157: case 2179: case 2181: case 2183: case 2185: case 2186:
|
||||
if(GetPlayer()->GetDifficulty()!=DIFFICULTY_HEROIC)
|
||||
continue;
|
||||
// FIX ME: mark as fail always until implement
|
||||
continue;
|
||||
// Normal + other
|
||||
case 578: case 624: case 1790: case 1856: case 1858: case 1869: case 1874:
|
||||
case 1996: case 1997: case 2047: case 2049: case 2050: case 2051: case 2146:
|
||||
case 2148: case 2153: case 2178: case 2180: case 2182: case 2184: case 2187:
|
||||
if(GetPlayer()->GetDifficulty()!=DIFFICULTY_NORMAL)
|
||||
continue;
|
||||
// FIX ME: mark as fail always until implement
|
||||
continue;
|
||||
// Just Normal
|
||||
default:
|
||||
if(GetPlayer()->GetDifficulty()!=DIFFICULTY_NORMAL)
|
||||
continue;
|
||||
break;
|
||||
};
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
|
|
@ -606,8 +658,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
{
|
||||
if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED)
|
||||
continue;
|
||||
// TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc?
|
||||
if(!gameeventmgr.IsActiveEvent(26))
|
||||
if(!IsHolidayActive(HOLIDAY_BREWFEST))
|
||||
continue;
|
||||
}
|
||||
// miscvalue1 is the ingame fallheight*100 as stored in dbc
|
||||
|
|
@ -730,6 +781,31 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
{
|
||||
// miscvalue1 = emote
|
||||
// miscvalue2 = achievement->ID for special requirement
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(miscvalue1 != achievementCriteria->do_emote.emoteID)
|
||||
continue;
|
||||
if(achievementCriteria->do_emote.count)
|
||||
{
|
||||
// harcoded case
|
||||
if(achievement->ID==247)
|
||||
{
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER ||
|
||||
unit->isAlive() || ((Player*)unit)->GetDeathTimer() == 0)
|
||||
continue;
|
||||
}
|
||||
// expected as scripted case
|
||||
else if(!miscvalue2 || !achievement->ID != miscvalue2)
|
||||
continue;
|
||||
}
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
{
|
||||
uint32 spellCount = 0;
|
||||
|
|
@ -798,7 +874,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
|
||||
|
|
@ -927,6 +1002,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
|
||||
return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
return progress->counter >= achievementCriteria->do_emote.count;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
|
||||
return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
|
||||
|
|
@ -998,7 +1075,9 @@ AchievementCompletionState AchievementMgr::GetAchievementCompletionState(Achieve
|
|||
|
||||
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
|
||||
{
|
||||
sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue);
|
||||
if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0)
|
||||
sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue);
|
||||
|
||||
CriteriaProgress *progress = NULL;
|
||||
|
||||
CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
|
||||
|
|
@ -1024,8 +1103,12 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
|
|||
newValue = changeValue;
|
||||
break;
|
||||
case PROGRESS_ACCUMULATE:
|
||||
newValue = progress->counter + changeValue;
|
||||
{
|
||||
// avoid overflow
|
||||
uint32 max_value = std::numeric_limits<uint32>::max();
|
||||
newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value;
|
||||
break;
|
||||
}
|
||||
case PROGRESS_HIGHEST:
|
||||
newValue = progress->counter < changeValue ? changeValue : progress->counter;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "AggressorAI.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "VMapFactory.h"
|
||||
#include "World.h"
|
||||
|
|
|
|||
|
|
@ -575,6 +575,28 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
|
|||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
|
||||
{
|
||||
// called for offline player after ending rated arena match!
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == guid)
|
||||
{
|
||||
// update personal rating
|
||||
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
|
||||
int32 mod = (int32)ceil(32.0f * (0.0f - chance));
|
||||
if (int32(itr->personal_rating) + mod < 0)
|
||||
itr->personal_rating = 0;
|
||||
else
|
||||
itr->personal_rating += mod;
|
||||
// update personal played stats
|
||||
itr->games_week +=1;
|
||||
itr->games_season +=1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
|
||||
{
|
||||
// called for each participant after winning a match
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ class ArenaTeam
|
|||
void MemberWon(Player * plr, uint32 againstRating);
|
||||
int32 LostAgainst(uint32 againstRating);
|
||||
void MemberLost(Player * plr, uint32 againstRating);
|
||||
void OfflineMemberLost(uint64 guid, uint32 againstRating);
|
||||
|
||||
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Language.h"
|
||||
|
||||
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
#include "ObjectMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "UpdateData.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
Bag::Bag( ): Item()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "Language.h"
|
||||
#include "Chat.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
|
|
@ -31,12 +30,105 @@
|
|||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Util.h"
|
||||
#include "Formulas.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
namespace MaNGOS
|
||||
{
|
||||
class BattleGroundChatBuilder
|
||||
{
|
||||
public:
|
||||
BattleGroundChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, va_list* args = NULL)
|
||||
: i_msgtype(msgtype), i_textId(textId), i_source(source), i_args(args) {}
|
||||
void operator()(WorldPacket& data, int32 loc_idx)
|
||||
{
|
||||
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
|
||||
|
||||
if(i_args)
|
||||
{
|
||||
// we need copy va_list before use or original va_list will corrupted
|
||||
va_list ap;
|
||||
va_copy(ap,*i_args);
|
||||
|
||||
char str [2048];
|
||||
vsnprintf(str,2048,text, ap );
|
||||
va_end(ap);
|
||||
|
||||
do_helper(data,&str[0]);
|
||||
}
|
||||
else
|
||||
do_helper(data,text);
|
||||
}
|
||||
private:
|
||||
void do_helper(WorldPacket& data, char const* text)
|
||||
{
|
||||
uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
|
||||
|
||||
data << uint8(i_msgtype);
|
||||
data << uint32(LANG_UNIVERSAL);
|
||||
data << uint64(target_guid); // there 0 for BG messages
|
||||
data << uint32(0); // can be chat msg group or something
|
||||
data << uint64(target_guid);
|
||||
data << uint32(strlen(text)+1);
|
||||
data << text;
|
||||
data << uint8(i_source ? i_source->chatTag() : uint8(0));
|
||||
}
|
||||
|
||||
ChatMsg i_msgtype;
|
||||
int32 i_textId;
|
||||
Player const* i_source;
|
||||
va_list* i_args;
|
||||
};
|
||||
|
||||
class BattleGround2ChatBuilder
|
||||
{
|
||||
public:
|
||||
BattleGround2ChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, int32 arg1, int32 arg2)
|
||||
: i_msgtype(msgtype), i_textId(textId), i_source(source), i_arg1(arg1), i_arg2(arg2) {}
|
||||
void operator()(WorldPacket& data, int32 loc_idx)
|
||||
{
|
||||
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
|
||||
char const* arg1str = i_arg1 ? objmgr.GetMangosString(i_arg1,loc_idx) : "";
|
||||
char const* arg2str = i_arg2 ? objmgr.GetMangosString(i_arg2,loc_idx) : "";
|
||||
|
||||
char str [2048];
|
||||
snprintf(str,2048,text, arg1str, arg2str );
|
||||
|
||||
uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
|
||||
|
||||
data << uint8(i_msgtype);
|
||||
data << uint32(LANG_UNIVERSAL);
|
||||
data << uint64(target_guid); // there 0 for BG messages
|
||||
data << uint32(0); // can be chat msg group or something
|
||||
data << uint64(target_guid);
|
||||
data << uint32(strlen(str)+1);
|
||||
data << str;
|
||||
data << uint8(i_source ? i_source->chatTag() : uint8(0));
|
||||
}
|
||||
private:
|
||||
|
||||
ChatMsg i_msgtype;
|
||||
int32 i_textId;
|
||||
Player const* i_source;
|
||||
int32 i_arg1;
|
||||
int32 i_arg2;
|
||||
};
|
||||
} // namespace MaNGOS
|
||||
|
||||
template<class Do>
|
||||
void BattleGround::BroadcastWorker(Do& _do)
|
||||
{
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
if(Player *plr = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
|
||||
_do(plr);
|
||||
}
|
||||
|
||||
BattleGround::BattleGround()
|
||||
{
|
||||
m_TypeID = BattleGroundTypeId(0);
|
||||
m_InstanceID = 0;
|
||||
m_Status = STATUS_NONE;
|
||||
m_ClientInstanceID = 0;
|
||||
m_EndTime = 0;
|
||||
m_LastResurrectTime = 0;
|
||||
m_QueueId = QUEUE_ID_MAX_LEVEL_19;
|
||||
|
|
@ -88,6 +180,16 @@ BattleGround::BattleGround()
|
|||
|
||||
m_PrematureCountDown = false;
|
||||
m_PrematureCountDown = 0;
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_2M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set to some default existing values
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGround::~BattleGround()
|
||||
|
|
@ -126,50 +228,30 @@ BattleGround::~BattleGround()
|
|||
|
||||
void BattleGround::Update(uint32 diff)
|
||||
{
|
||||
if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize())
|
||||
if(!GetPlayersSize() && !GetReviveQueueSize())
|
||||
//BG is empty
|
||||
return;
|
||||
|
||||
if(GetRemovedPlayersSize())
|
||||
// remove offline players from bg after 5 minutes
|
||||
if( !m_OfflineQueue.empty() )
|
||||
{
|
||||
for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr)
|
||||
BattleGroundPlayerMap::iterator itr = m_Players.find(*(m_OfflineQueue.begin()));
|
||||
if( itr != m_Players.end() )
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
switch(itr->second)
|
||||
if( itr->second.OfflineRemoveTime <= sWorld.GetGameTime() )
|
||||
{
|
||||
case 1: // currently in bg and was removed from bg
|
||||
if(plr)
|
||||
RemovePlayerAtLeave(itr->first, true, true);
|
||||
else
|
||||
RemovePlayerAtLeave(itr->first, false, false);
|
||||
break;
|
||||
case 2: // revive queue
|
||||
RemovePlayerFromResurrectQueue(itr->first);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("BattleGround: Unknown remove player case!");
|
||||
RemovePlayerAtLeave(itr->first, true, true);// remove player from BG
|
||||
m_OfflineQueue.pop_front(); // remove from offline queue
|
||||
//do not use itr for anything, because it is erased in RemovePlayerAtLeave()
|
||||
}
|
||||
}
|
||||
m_RemovedPlayers.clear();
|
||||
}
|
||||
|
||||
// remove offline players from bg after ~5 minutes
|
||||
if(GetPlayersSize())
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
itr->second.LastOnlineTime += diff;
|
||||
/*********************************************************/
|
||||
/*** BATTLEGROUND RESSURECTION SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
if(plr)
|
||||
itr->second.LastOnlineTime = 0; // update last online time
|
||||
else
|
||||
if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes
|
||||
m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
|
||||
}
|
||||
}
|
||||
|
||||
//this should be handled by spell system:
|
||||
//this should be handled by spell system
|
||||
m_LastResurrectTime += diff;
|
||||
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
|
||||
{
|
||||
|
|
@ -219,6 +301,10 @@ void BattleGround::Update(uint32 diff)
|
|||
m_ResurrectQueue.clear();
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** BATTLEGROUND BALLANCE SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
// if less then minimum players are in on one side, then start premature finish timer
|
||||
if(GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
|
||||
{
|
||||
|
|
@ -226,39 +312,137 @@ void BattleGround::Update(uint32 diff)
|
|||
{
|
||||
m_PrematureCountDown = true;
|
||||
m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime();
|
||||
SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
|
||||
}
|
||||
else if(m_PrematureCountDownTimer < diff)
|
||||
{
|
||||
// time's up!
|
||||
EndBattleGround(0); // noone wins
|
||||
uint32 winner = 0;
|
||||
if( GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam() )
|
||||
winner = ALLIANCE;
|
||||
else if( GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam() )
|
||||
winner = HORDE;
|
||||
|
||||
EndBattleGround(winner);
|
||||
m_PrematureCountDown = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 newtime = m_PrematureCountDownTimer - diff;
|
||||
// announce every minute
|
||||
if(m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / 60000 != m_PrematureCountDownTimer / 60000)
|
||||
SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
|
||||
if( newtime > (MINUTE * IN_MILISECONDS) )
|
||||
{
|
||||
if( newtime / (MINUTE * IN_MILISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS) )
|
||||
PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//announce every 15 seconds
|
||||
if( newtime / (15 * IN_MILISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILISECONDS) )
|
||||
PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILISECONDS));
|
||||
}
|
||||
m_PrematureCountDownTimer = newtime;
|
||||
}
|
||||
}
|
||||
else if (m_PrematureCountDown)
|
||||
m_PrematureCountDown = false;
|
||||
|
||||
/*********************************************************/
|
||||
/*** BATTLEGROUND STARTING SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if (!(m_Events & BG_STARTING_EVENT_1))
|
||||
{
|
||||
m_Events |= BG_STARTING_EVENT_1;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
StartingEventCloseDoors();
|
||||
SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FIRST]);
|
||||
//first start warning - 2 or 1 minute
|
||||
SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
// After 1 minute or 30 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2))
|
||||
{
|
||||
m_Events |= BG_STARTING_EVENT_2;
|
||||
SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
// After 30 or 15 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3))
|
||||
{
|
||||
m_Events |= BG_STARTING_EVENT_3;
|
||||
SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
// delay expired (atfer 2 or 1 minute)
|
||||
else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4))
|
||||
{
|
||||
m_Events |= BG_STARTING_EVENT_4;
|
||||
|
||||
StartingEventOpenDoors();
|
||||
|
||||
SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FOURTH]);
|
||||
|
||||
//remove preparation
|
||||
if( isArena() )
|
||||
{
|
||||
//TODO : add arena sound PlaySoundToAll(SOUND_ARENA_START);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
PlaySoundToAll(SOUND_BG_START);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player* plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
|
||||
//Announce BG starting
|
||||
if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) )
|
||||
{
|
||||
sWorld.SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** BATTLEGROUND ENDING SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
if(GetStatus() == STATUS_WAIT_LEAVE)
|
||||
{
|
||||
// remove all players from battleground after 2 minutes
|
||||
m_EndTime += diff;
|
||||
if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
BattleGroundPlayerMap::iterator itr, next;
|
||||
for(itr = m_Players.begin(); itr != m_Players.end(); itr = next)
|
||||
{
|
||||
m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
|
||||
next = itr;
|
||||
++next;
|
||||
//itr is erased here!
|
||||
RemovePlayerAtLeave(itr->first, true, true);// remove player from BG
|
||||
// do not change any battleground's private variables
|
||||
}
|
||||
// do not change any battleground's private variables
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
|
||||
|
|
@ -272,7 +456,7 @@ void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, flo
|
|||
|
||||
void BattleGround::SendPacketToAll(WorldPacket *packet)
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
if(plr)
|
||||
|
|
@ -284,7 +468,7 @@ void BattleGround::SendPacketToAll(WorldPacket *packet)
|
|||
|
||||
void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender, bool self)
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -316,7 +500,7 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
|
|||
{
|
||||
WorldPacket data;
|
||||
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -339,7 +523,7 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
|
|||
|
||||
void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -359,7 +543,7 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
|
|||
|
||||
void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
|
||||
{
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -384,7 +568,7 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
|
|||
if(!factionEntry)
|
||||
return;
|
||||
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -425,15 +609,11 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
uint32 loser_rating = 0;
|
||||
uint32 winner_rating = 0;
|
||||
WorldPacket data;
|
||||
Player *Source = NULL;
|
||||
const char *winmsg = "";
|
||||
int32 winmsg_id = 0;
|
||||
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
if(isBattleGround())
|
||||
winmsg = GetMangosString(LANG_BG_A_WINS);
|
||||
else
|
||||
winmsg = GetMangosString(LANG_ARENA_GOLD_WINS);
|
||||
winmsg_id = isBattleGround() ? LANG_BG_A_WINS : LANG_ARENA_GOLD_WINS;
|
||||
|
||||
PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound
|
||||
|
||||
|
|
@ -441,10 +621,7 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
}
|
||||
else if(winner == HORDE)
|
||||
{
|
||||
if(isBattleGround())
|
||||
winmsg = GetMangosString(LANG_BG_H_WINS);
|
||||
else
|
||||
winmsg = GetMangosString(LANG_ARENA_GREEN_WINS);
|
||||
winmsg_id = isBattleGround() ? LANG_BG_H_WINS : LANG_ARENA_GREEN_WINS;
|
||||
|
||||
PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound
|
||||
|
||||
|
|
@ -461,33 +638,17 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
// arena rating calculation
|
||||
if(isArena() && isRated())
|
||||
{
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
}
|
||||
else if(winner == HORDE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
}
|
||||
if(winner_arena_team && loser_arena_team)
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(winner));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));
|
||||
if( winner_arena_team && loser_arena_team )
|
||||
{
|
||||
loser_rating = loser_arena_team->GetStats().rating;
|
||||
winner_rating = winner_arena_team->GetStats().rating;
|
||||
int32 winner_change = winner_arena_team->WonAgainst(loser_rating);
|
||||
int32 loser_change = loser_arena_team->LostAgainst(winner_rating);
|
||||
sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner change: %u, Losser change: %u ---", winner_rating, loser_rating, winner_change, loser_change);
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change);
|
||||
SetArenaTeamRatingChangeForTeam(HORDE, loser_change);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetArenaTeamRatingChangeForTeam(HORDE, winner_change);
|
||||
SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change);
|
||||
}
|
||||
SetArenaTeamRatingChangeForTeam(winner, winner_change);
|
||||
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loser_change);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -496,11 +657,21 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
}
|
||||
}
|
||||
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
uint32 team = itr->second.Team;
|
||||
|
||||
if(!plr)
|
||||
{
|
||||
//if rated arena match - make member lost!
|
||||
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
|
||||
{
|
||||
if(team == winner)
|
||||
winner_arena_team->OfflineMemberLost(itr->first, loser_rating);
|
||||
else
|
||||
loser_arena_team->OfflineMemberLost(itr->first, winner_rating);
|
||||
}
|
||||
sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -515,8 +686,8 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
plr->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
uint32 team = itr->second.Team;
|
||||
if(!team) team = plr->GetTeam();
|
||||
//this line is obsolete - team is set ALWAYS
|
||||
//if(!team) team = plr->GetTeam();
|
||||
|
||||
// per player calculation
|
||||
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
|
||||
|
|
@ -529,10 +700,7 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
|
||||
if(team == winner)
|
||||
{
|
||||
if(!Source)
|
||||
Source = plr;
|
||||
RewardMark(plr,ITEM_WINNER_COUNT);
|
||||
UpdatePlayerScore(plr, SCORE_BONUS_HONOR, 20);
|
||||
RewardQuest(plr);
|
||||
}
|
||||
else
|
||||
|
|
@ -548,7 +716,7 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
plr->GetSession()->SendPacket(&data);
|
||||
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
|
||||
}
|
||||
|
|
@ -570,11 +738,14 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
// inform invited players about the removal
|
||||
sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
|
||||
if(Source)
|
||||
{
|
||||
ChatHandler(Source).FillMessageData(&data, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, Source->GetGUID(), winmsg);
|
||||
SendPacketToAll(&data);
|
||||
}
|
||||
if(winmsg_id)
|
||||
SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetBonusHonorFromKill(uint32 kills) const
|
||||
{
|
||||
//variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill)
|
||||
return MaNGOS::Honor::hk_honor_at_level(GetMaxLevel(), kills);
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetBattlemasterEntry() const
|
||||
|
|
@ -723,10 +894,10 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
|||
uint32 team = GetPlayerTeam(guid);
|
||||
bool participant = false;
|
||||
// Remove from lists/maps
|
||||
std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid);
|
||||
BattleGroundPlayerMap::iterator itr = m_Players.find(guid);
|
||||
if(itr != m_Players.end())
|
||||
{
|
||||
UpdatePlayersCountByTeam(team, true); // -1 player
|
||||
UpdatePlayersCountByTeam(team, true); // -1 player
|
||||
m_Players.erase(itr);
|
||||
// check if the player was a participant of the match, or only entered through gm command (goname)
|
||||
participant = true;
|
||||
|
|
@ -755,21 +926,21 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
|||
|
||||
RemovePlayer(plr, guid); // BG subclass specific code
|
||||
|
||||
if(plr)
|
||||
if(participant) // if the player was a match participant, remove auras, calc rating, update queue
|
||||
{
|
||||
plr->ClearAfkReports();
|
||||
|
||||
if(participant) // if the player was a match participant, remove auras, calc rating, update queue
|
||||
BattleGroundTypeId bgTypeId = GetTypeID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
if(plr)
|
||||
{
|
||||
plr->ClearAfkReports();
|
||||
|
||||
if(!team) team = plr->GetTeam();
|
||||
|
||||
BattleGroundTypeId bgTypeId = GetTypeID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
// if arena, remove the specific arena auras
|
||||
if(isArena())
|
||||
{
|
||||
plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out
|
||||
bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
|
||||
plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out
|
||||
bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
|
||||
|
||||
// summon old pet if there was one and there isn't a current pet
|
||||
if(!plr->GetPet() && plr->GetTemporaryUnsummonedPetNumber())
|
||||
|
|
@ -784,65 +955,64 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
|||
if(isRated() && GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
//left a rated match while the encounter was in progress, consider as loser
|
||||
ArenaTeam * winner_arena_team = 0;
|
||||
ArenaTeam * loser_arena_team = 0;
|
||||
if(team == HORDE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
}
|
||||
else
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
}
|
||||
ArenaTeam * winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
|
||||
ArenaTeam * loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
|
||||
if(winner_arena_team && loser_arena_team)
|
||||
{
|
||||
loser_arena_team->MemberLost(plr,winner_arena_team->GetRating());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
if(SendPacket)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0);
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
|
||||
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
DecreaseInvitedCount(team);
|
||||
//we should update battleground queue, but only if bg isn't ending
|
||||
if (GetStatus() < STATUS_WAIT_LEAVE)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId());
|
||||
|
||||
Group * group = plr->GetGroup();
|
||||
// remove from raid group if exist
|
||||
if(group && group == GetBgRaid(team))
|
||||
}
|
||||
else
|
||||
// removing offline participant
|
||||
{
|
||||
if(isRated() && GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
if(!group->RemoveMember(guid, 0)) // group was disbanded
|
||||
{
|
||||
SetBgRaid(team, NULL);
|
||||
delete group;
|
||||
}
|
||||
//left a rated match while the encounter was in progress, consider as loser
|
||||
ArenaTeam * others_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
|
||||
ArenaTeam * players_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
|
||||
if( others_arena_team && players_arena_team )
|
||||
players_arena_team->OfflineMemberLost(guid, others_arena_team->GetRating());
|
||||
}
|
||||
|
||||
// Let others know
|
||||
sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr);
|
||||
SendPacketToTeam(team, &data, plr, false);
|
||||
}
|
||||
|
||||
// remove from raid group if player is member
|
||||
if(Group *group = GetBgRaid(team))
|
||||
{
|
||||
if( !group->RemoveMember(guid, 0) ) // group was disbanded
|
||||
{
|
||||
SetBgRaid(team, NULL);
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
DecreaseInvitedCount(team);
|
||||
//we should update battleground queue, but only if bg isn't ending
|
||||
if( isBattleGround() && GetStatus() < STATUS_WAIT_LEAVE )
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId());
|
||||
// Let others know
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, guid);
|
||||
SendPacketToTeam(team, &data, plr, false);
|
||||
}
|
||||
|
||||
if( plr )
|
||||
{
|
||||
// Do next only if found in battleground
|
||||
plr->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
|
||||
plr->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
|
||||
// reset destination bg team
|
||||
plr->SetBGTeam(0);
|
||||
|
||||
if(Transport)
|
||||
plr->TeleportTo(plr->GetBattleGroundEntryPoint());
|
||||
|
||||
// Log
|
||||
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +1070,7 @@ void BattleGround::AddPlayer(Player *plr)
|
|||
uint32 team = plr->GetBGTeam();
|
||||
|
||||
BattleGroundPlayer bp;
|
||||
bp.LastOnlineTime = 0;
|
||||
bp.OfflineRemoveTime = 0;
|
||||
bp.Team = team;
|
||||
|
||||
// Add to list/maps
|
||||
|
|
@ -963,7 +1133,7 @@ void BattleGround::AddPlayer(Player *plr)
|
|||
}
|
||||
|
||||
// setup BG group membership
|
||||
PlayerRelogin(plr);
|
||||
PlayerAddedToBGCheckIfBGIsRunning(plr);
|
||||
AddOrSetPlayerToCorrectBgGroup(plr, guid, team);
|
||||
|
||||
// Log
|
||||
|
|
@ -992,6 +1162,38 @@ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid,
|
|||
}
|
||||
}
|
||||
|
||||
// This method should be called when player logs into running battleground
|
||||
void BattleGround::EventPlayerLoggedIn(Player* player, uint64 plr_guid)
|
||||
{
|
||||
// player is correct pointer
|
||||
for(std::deque<uint64>::iterator itr = m_OfflineQueue.begin(); itr != m_OfflineQueue.end(); ++itr)
|
||||
{
|
||||
if( *itr == plr_guid )
|
||||
{
|
||||
m_OfflineQueue.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_Players[plr_guid].OfflineRemoveTime = 0;
|
||||
PlayerAddedToBGCheckIfBGIsRunning(player);
|
||||
// if battleground is starting, then add preparation aura
|
||||
// we don't have to do that, because preparation aura isn't removed when player logs out
|
||||
}
|
||||
|
||||
// This method should be called when player logs out from running battleground
|
||||
void BattleGround::EventPlayerLoggedOut(Player* player)
|
||||
{
|
||||
// player is correct pointer, it is checked in WorldSession::LogoutPlayer()
|
||||
m_OfflineQueue.push_back(player->GetGUID());
|
||||
m_Players[player->GetGUID()].OfflineRemoveTime = sWorld.GetGameTime() + MAX_OFFLINE_TIME;
|
||||
if( GetStatus() == STATUS_IN_PROGRESS )
|
||||
{
|
||||
if( isBattleGround() )
|
||||
EventPlayerDroppedFlag(player);
|
||||
else
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
}
|
||||
|
||||
/* This method should be called only once ... it adds pointer to queue */
|
||||
void BattleGround::AddToBGFreeSlotQueue()
|
||||
|
|
@ -1024,7 +1226,7 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
|
|||
// returns the number how many players can join battleground to MaxPlayersPerTeam
|
||||
uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
|
||||
{
|
||||
//if BG is starting ... invite anyone
|
||||
//return free slot count to MaxPlayerPerTeam
|
||||
if (GetStatus() == STATUS_WAIT_JOIN || GetStatus() == STATUS_IN_PROGRESS)
|
||||
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
|
||||
|
||||
|
|
@ -1357,19 +1559,30 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
|
|||
return true;
|
||||
}
|
||||
|
||||
void BattleGround::SendMessageToAll(char const* text)
|
||||
void BattleGround::SendMessageToAll(int32 entry, ChatMsg type, Player const* source)
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL);
|
||||
SendPacketToAll(&data);
|
||||
MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source);
|
||||
MaNGOS::LocalizedPacketDo<MaNGOS::BattleGroundChatBuilder> bg_do(bg_builder);
|
||||
BroadcastWorker(bg_do);
|
||||
}
|
||||
|
||||
void BattleGround::SendMessageToAll(int32 entry)
|
||||
void BattleGround::PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...)
|
||||
{
|
||||
char const* text = GetMangosString(entry);
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, text, NULL);
|
||||
SendPacketToAll(&data);
|
||||
va_list ap;
|
||||
va_start(ap, source);
|
||||
|
||||
MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source, &ap);
|
||||
MaNGOS::LocalizedPacketDo<MaNGOS::BattleGroundChatBuilder> bg_do(bg_builder);
|
||||
BroadcastWorker(bg_do);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void BattleGround::SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 arg1, int32 arg2)
|
||||
{
|
||||
MaNGOS::BattleGround2ChatBuilder bg_builder(type, entry, source, arg1, arg2);
|
||||
MaNGOS::LocalizedPacketDo<MaNGOS::BattleGround2ChatBuilder> bg_do(bg_builder);
|
||||
BroadcastWorker(bg_do);
|
||||
}
|
||||
|
||||
void BattleGround::EndNow()
|
||||
|
|
@ -1381,13 +1594,6 @@ void BattleGround::EndNow()
|
|||
sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
}
|
||||
|
||||
// Battleground messages are localized using the dbc lang, they are not client language dependent
|
||||
const char *BattleGround::GetMangosString(int32 entry)
|
||||
{
|
||||
// FIXME: now we have different DBC locales and need localized message for each target client
|
||||
return objmgr.GetMangosStringForDBCLocale(entry);
|
||||
}
|
||||
|
||||
/*
|
||||
important notice:
|
||||
buffs aren't spawned/despawned when players captures anything
|
||||
|
|
@ -1441,7 +1647,7 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer )
|
|||
UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);
|
||||
UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1);
|
||||
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
|
||||
|
|
@ -1461,21 +1667,26 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer )
|
|||
// used in same faction arena matches mainly
|
||||
uint32 BattleGround::GetPlayerTeam(uint64 guid)
|
||||
{
|
||||
std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
|
||||
BattleGroundPlayerMap::const_iterator itr = m_Players.find(guid);
|
||||
if(itr!=m_Players.end())
|
||||
return itr->second.Team;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetOtherTeam(uint32 teamId)
|
||||
{
|
||||
return (teamId) ? ((teamId == ALLIANCE) ? HORDE : ALLIANCE) : 0;
|
||||
}
|
||||
|
||||
bool BattleGround::IsPlayerInBattleGround(uint64 guid)
|
||||
{
|
||||
std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
|
||||
if(itr!=m_Players.end())
|
||||
BattleGroundPlayerMap::const_iterator itr = m_Players.find(guid);
|
||||
if(itr != m_Players.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BattleGround::PlayerRelogin(Player* plr)
|
||||
void BattleGround::PlayerAddedToBGCheckIfBGIsRunning(Player* plr)
|
||||
{
|
||||
if(GetStatus() != STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
|
@ -1488,14 +1699,14 @@ void BattleGround::PlayerRelogin(Player* plr)
|
|||
sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
|
||||
{
|
||||
int count = 0;
|
||||
for(std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
if(itr->second.Team == Team)
|
||||
{
|
||||
|
|
@ -1507,6 +1718,14 @@ uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
|
|||
return count;
|
||||
}
|
||||
|
||||
void BattleGround::CheckArenaWinConditions()
|
||||
{
|
||||
if( !GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE) )
|
||||
EndBattleGround(HORDE);
|
||||
else if( GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE) )
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
|
||||
void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid )
|
||||
{
|
||||
Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE];
|
||||
|
|
@ -1518,4 +1737,4 @@ void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid )
|
|||
WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard( Player* player )
|
||||
{
|
||||
return objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam() );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,15 +89,19 @@ enum BattleGroundTimeIntervals
|
|||
INVITATION_REMIND_TIME = 60000, // ms
|
||||
INVITE_ACCEPT_WAIT_TIME = 80000, // ms
|
||||
TIME_TO_AUTOREMOVE = 120000, // ms
|
||||
MAX_OFFLINE_TIME = 300000, // ms
|
||||
START_DELAY0 = 120000, // ms
|
||||
START_DELAY1 = 60000, // ms
|
||||
START_DELAY2 = 30000, // ms
|
||||
START_DELAY3 = 15000, // ms used only in arena
|
||||
MAX_OFFLINE_TIME = 300, // secs
|
||||
RESPAWN_ONE_DAY = 86400, // secs
|
||||
RESPAWN_IMMEDIATELY = 0, // secs
|
||||
BUFF_RESPAWN_TIME = 180, // secs
|
||||
BG_HONOR_SCORE_TICKS = 330 // points
|
||||
};
|
||||
|
||||
enum BattleGroundStartTimeIntervals
|
||||
{
|
||||
BG_START_DELAY_2M = 120000, // ms (2 minutes)
|
||||
BG_START_DELAY_1M = 60000, // ms (1 minute)
|
||||
BG_START_DELAY_30S = 30000, // ms (30 seconds)
|
||||
BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena
|
||||
BG_START_DELAY_NONE = 0, // ms
|
||||
};
|
||||
|
||||
enum BattleGroundBuffObjects
|
||||
|
|
@ -120,7 +124,7 @@ enum BattleGroundStatus
|
|||
|
||||
struct BattleGroundPlayer
|
||||
{
|
||||
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
uint32 Team; // Player's team
|
||||
};
|
||||
|
||||
|
|
@ -214,6 +218,24 @@ enum BattleGroundTeamId
|
|||
};
|
||||
#define BG_TEAMS_COUNT 2
|
||||
|
||||
enum BattleGroundStartingEvents
|
||||
{
|
||||
BG_STARTING_EVENT_NONE = 0x00,
|
||||
BG_STARTING_EVENT_1 = 0x01,
|
||||
BG_STARTING_EVENT_2 = 0x02,
|
||||
BG_STARTING_EVENT_3 = 0x04,
|
||||
BG_STARTING_EVENT_4 = 0x08
|
||||
};
|
||||
|
||||
enum BattleGroundStartingEventsIds
|
||||
{
|
||||
BG_STARTING_EVENT_FIRST = 0,
|
||||
BG_STARTING_EVENT_SECOND = 1,
|
||||
BG_STARTING_EVENT_THIRD = 2,
|
||||
BG_STARTING_EVENT_FOURTH = 3
|
||||
};
|
||||
#define BG_STARTING_EVENT_COUNT 4
|
||||
|
||||
enum BattleGroundJoinError
|
||||
{
|
||||
BG_JOIN_ERR_OK = 0,
|
||||
|
|
@ -266,6 +288,8 @@ class BattleGround
|
|||
return true;
|
||||
}
|
||||
virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass
|
||||
virtual void StartingEventCloseDoors() {}
|
||||
virtual void StartingEventOpenDoors() {}
|
||||
|
||||
/* Battleground */
|
||||
// Get methods:
|
||||
|
|
@ -274,6 +298,7 @@ class BattleGround
|
|||
BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; }
|
||||
uint32 GetInstanceID() const { return m_InstanceID; }
|
||||
BattleGroundStatus GetStatus() const { return m_Status; }
|
||||
uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
|
||||
uint32 GetStartTime() const { return m_StartTime; }
|
||||
uint32 GetEndTime() const { return m_EndTime; }
|
||||
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
|
||||
|
|
@ -290,6 +315,7 @@ class BattleGround
|
|||
uint8 GetArenaType() const { return m_ArenaType; }
|
||||
uint8 GetWinner() const { return m_Winner; }
|
||||
uint32 GetBattlemasterEntry() const;
|
||||
uint32 GetBonusHonorFromKill(uint32 kills) const;
|
||||
|
||||
// Set methods:
|
||||
void SetName(char const* Name) { m_Name = Name; }
|
||||
|
|
@ -303,6 +329,7 @@ class BattleGround
|
|||
}
|
||||
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
|
||||
void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
|
||||
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
|
||||
void SetStartTime(uint32 Time) { m_StartTime = Time; }
|
||||
void SetEndTime(uint32 Time) { m_EndTime = Time; }
|
||||
void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; }
|
||||
|
|
@ -342,7 +369,6 @@ class BattleGround
|
|||
typedef std::map<uint64, BattleGroundPlayer> BattleGroundPlayerMap;
|
||||
BattleGroundPlayerMap const& GetPlayers() const { return m_Players; }
|
||||
uint32 GetPlayersSize() const { return m_Players.size(); }
|
||||
uint32 GetRemovedPlayersSize() const { return m_RemovedPlayers.size(); }
|
||||
|
||||
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); }
|
||||
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); }
|
||||
|
|
@ -374,6 +400,10 @@ class BattleGround
|
|||
virtual void FillInitialWorldStates(WorldPacket& /*data*/) {}
|
||||
void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true);
|
||||
void SendPacketToAll(WorldPacket *packet);
|
||||
|
||||
template<class Do>
|
||||
void BroadcastWorker(Do& _do);
|
||||
|
||||
void PlaySoundToTeam(uint32 SoundID, uint32 TeamID);
|
||||
void PlaySoundToAll(uint32 SoundID);
|
||||
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
|
||||
|
|
@ -387,8 +417,11 @@ class BattleGround
|
|||
void EndBattleGround(uint32 winner);
|
||||
void BlockMovement(Player *plr);
|
||||
|
||||
void SendMessageToAll(char const* text);
|
||||
void SendMessageToAll(int32 entry);
|
||||
void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL);
|
||||
void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ... );
|
||||
|
||||
// specialized version with 2 string id args
|
||||
void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0);
|
||||
|
||||
/* Raid Group */
|
||||
Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
|
||||
|
|
@ -409,9 +442,10 @@ class BattleGround
|
|||
|
||||
// used for rated arena battles
|
||||
void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; }
|
||||
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
|
||||
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
|
||||
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
|
||||
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
|
||||
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
|
||||
void CheckArenaWinConditions();
|
||||
|
||||
/* Triggers handle */
|
||||
// must be implemented in BG subclass
|
||||
|
|
@ -420,10 +454,11 @@ class BattleGround
|
|||
virtual void HandleKillPlayer(Player *player, Player *killer);
|
||||
|
||||
/* Battleground events */
|
||||
/* these functions will return true event is possible, but false if player is bugger */
|
||||
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
|
||||
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {}
|
||||
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
|
||||
void EventPlayerLoggedIn(Player* player, uint64 plr_guid);
|
||||
void EventPlayerLoggedOut(Player* player);
|
||||
|
||||
/* Death related */
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
|
@ -452,20 +487,20 @@ class BattleGround
|
|||
|
||||
void DoorOpen(uint32 type);
|
||||
void DoorClose(uint32 type);
|
||||
const char *GetMangosString(int32 entry);
|
||||
|
||||
virtual bool HandlePlayerUnderMap(Player * /*plr*/) { return false; }
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
uint32 GetPlayerTeam(uint64 guid);
|
||||
uint32 GetOtherTeam(uint32 teamId);
|
||||
bool IsPlayerInBattleGround(uint64 guid);
|
||||
void PlayerRelogin(Player* plr);
|
||||
|
||||
void SetDeleteThis() {m_SetDeleteThis = true;}
|
||||
|
||||
protected:
|
||||
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
|
||||
void EndNow();
|
||||
void PlayerAddedToBGCheckIfBGIsRunning(Player* plr);
|
||||
|
||||
/* Scorekeeping */
|
||||
// Player scores
|
||||
|
|
@ -479,9 +514,12 @@ class BattleGround
|
|||
std::map<uint64, std::vector<uint64> > m_ReviveQueue;
|
||||
|
||||
/*
|
||||
this is important variable used for invitation messages
|
||||
these are important variables used for starting messages
|
||||
*/
|
||||
uint8 m_Events;
|
||||
BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT];
|
||||
//this must be filled in constructors!
|
||||
uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT];
|
||||
|
||||
bool m_BuffChange;
|
||||
|
||||
|
|
@ -490,6 +528,7 @@ class BattleGround
|
|||
BattleGroundTypeId m_TypeID;
|
||||
uint32 m_InstanceID; //BattleGround Instance's GUID!
|
||||
BattleGroundStatus m_Status;
|
||||
uint32 m_ClientInstanceID; //the instance-id which is sent to the client and without any other internal use
|
||||
uint32 m_StartTime;
|
||||
uint32 m_EndTime;
|
||||
uint32 m_LastResurrectTime;
|
||||
|
|
@ -507,7 +546,7 @@ class BattleGround
|
|||
|
||||
/* Player lists */
|
||||
std::vector<uint64> m_ResurrectQueue; // Player GUID
|
||||
std::map<uint64, uint8> m_RemovedPlayers; // uint8 is remove type (0 - bgqueue, 1 - bg, 2 - resurrect queue)
|
||||
std::deque<uint64> m_OfflineQueue; // Player GUID
|
||||
|
||||
/* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */
|
||||
/* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */
|
||||
|
|
|
|||
|
|
@ -19,10 +19,20 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundAA.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundAA::BattleGroundAA()
|
||||
{
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundAA::~BattleGroundAA()
|
||||
|
|
@ -35,6 +45,14 @@ void BattleGroundAA::Update(uint32 diff)
|
|||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundAA::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAA::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class BattleGroundAA : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
#include "BattleGround.h"
|
||||
#include "BattleGroundAB.h"
|
||||
#include "Creature.h"
|
||||
#include "Chat.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "Language.h"
|
||||
#include "Util.h"
|
||||
#include "WorldPacket.h"
|
||||
|
|
@ -33,6 +31,11 @@ BattleGroundAB::BattleGroundAB()
|
|||
m_BuffChange = true;
|
||||
m_BgObjects.resize(BG_AB_OBJECT_MAX);
|
||||
m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT);
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundAB::~BattleGroundAB()
|
||||
|
|
@ -43,81 +46,7 @@ void BattleGroundAB::Update(uint32 diff)
|
|||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if( GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize() )
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if( !(m_Events & 0x01) )
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("Arathi Basin: entering state STATUS_WAIT_JOIN ...");
|
||||
|
||||
// despawn banners, auras and buffs
|
||||
for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj)
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
|
||||
|
||||
// Starting doors
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
|
||||
DoorClose(BG_AB_OBJECT_GATE_A);
|
||||
DoorClose(BG_AB_OBJECT_GATE_H);
|
||||
|
||||
// Starting base spirit guides
|
||||
_NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
|
||||
_NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
|
||||
|
||||
SetStartDelayTime(START_DELAY0);
|
||||
}
|
||||
// After 1 minute, warning is signalled
|
||||
else if( GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04) )
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_AB_ONEMINTOSTART));
|
||||
}
|
||||
// After 1,5 minute, warning is signalled
|
||||
else if( GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08) )
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_AB_HALFMINTOSTART));
|
||||
}
|
||||
// After 2 minutes, gates OPEN ! x)
|
||||
else if( GetStartDelayTime() < 0 && !(m_Events & 0x10) )
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_AB_STARTED));
|
||||
|
||||
// spawn neutral banners
|
||||
for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
|
||||
SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
//randomly select buff to spawn
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
DoorOpen(BG_AB_OBJECT_GATE_A);
|
||||
DoorOpen(BG_AB_OBJECT_GATE_H);
|
||||
|
||||
PlaySoundToAll(SOUND_BG_START);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player* plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
|
||||
}
|
||||
|
||||
}
|
||||
else if( GetStatus() == STATUS_IN_PROGRESS )
|
||||
if( GetStatus() == STATUS_IN_PROGRESS )
|
||||
{
|
||||
int team_points[2] = { 0, 0 };
|
||||
|
||||
|
|
@ -154,13 +83,19 @@ void BattleGroundAB::Update(uint32 diff)
|
|||
_SendNodeUpdate(node);
|
||||
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
|
||||
// Message to chatlog
|
||||
char buf[256];
|
||||
uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE), _GetNodeName(node));
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL);
|
||||
SendPacketToAll(&data);
|
||||
PlaySoundToAll((teamIndex == 0) ? SOUND_NODE_CAPTURED_ALLIANCE : SOUND_NODE_CAPTURED_HORDE);
|
||||
|
||||
if(teamIndex == 0)
|
||||
{
|
||||
// FIXME: team and node names not localized
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE,NULL,LANG_BG_AB_ALLY,_GetNodeNameId(node));
|
||||
PlaySoundToAll(SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: team and node names not localized
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE,NULL,LANG_BG_AB_HORDE,_GetNodeNameId(node));
|
||||
PlaySoundToAll(SOUND_NODE_CAPTURED_HORDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,22 +117,22 @@ void BattleGroundAB::Update(uint32 diff)
|
|||
m_TeamScores[team] += BG_AB_TickPoints[points];
|
||||
m_HonorScoreTics[team] += BG_AB_TickPoints[points];
|
||||
m_ReputationScoreTics[team] += BG_AB_TickPoints[points];
|
||||
if( m_ReputationScoreTics[team] >= 200 )
|
||||
if( m_ReputationScoreTics[team] >= m_ReputationTics )
|
||||
{
|
||||
(team == BG_TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
|
||||
m_ReputationScoreTics[team] -= 200;
|
||||
m_ReputationScoreTics[team] -= m_ReputationTics;
|
||||
}
|
||||
if( m_HonorScoreTics[team] >= BG_HONOR_SCORE_TICKS )
|
||||
if( m_HonorScoreTics[team] >= m_HonorTics )
|
||||
{
|
||||
(team == BG_TEAM_ALLIANCE) ? RewardHonorToTeam(20, ALLIANCE) : RewardHonorToTeam(20, HORDE);
|
||||
m_HonorScoreTics[team] -= BG_HONOR_SCORE_TICKS;
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == BG_TEAM_ALLIANCE) ? ALLIANCE : HORDE);
|
||||
m_HonorScoreTics[team] -= m_HonorTics;
|
||||
}
|
||||
if( !m_IsInformedNearVictory && m_TeamScores[team] > 1800 )
|
||||
{
|
||||
if( team == BG_TEAM_ALLIANCE )
|
||||
SendMessageToAll(GetMangosString(LANG_BG_AB_A_NEAR_VICTORY));
|
||||
SendMessageToAll(LANG_BG_AB_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
else
|
||||
SendMessageToAll(GetMangosString(LANG_BG_AB_H_NEAR_VICTORY));
|
||||
SendMessageToAll(LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(SOUND_NEAR_VICTORY);
|
||||
m_IsInformedNearVictory = true;
|
||||
}
|
||||
|
|
@ -219,6 +154,40 @@ void BattleGroundAB::Update(uint32 diff)
|
|||
}
|
||||
}
|
||||
|
||||
void BattleGroundAB::StartingEventCloseDoors()
|
||||
{
|
||||
// despawn banners, auras and buffs
|
||||
for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj)
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
|
||||
|
||||
// Starting doors
|
||||
DoorClose(BG_AB_OBJECT_GATE_A);
|
||||
DoorClose(BG_AB_OBJECT_GATE_H);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
// Starting base spirit guides
|
||||
_NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
|
||||
_NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
|
||||
}
|
||||
|
||||
void BattleGroundAB::StartingEventOpenDoors()
|
||||
{
|
||||
// spawn neutral banners
|
||||
for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
|
||||
SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
//randomly select buff to spawn
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
DoorOpen(BG_AB_OBJECT_GATE_A);
|
||||
DoorOpen(BG_AB_OBJECT_GATE_H);
|
||||
}
|
||||
|
||||
void BattleGroundAB::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
@ -303,24 +272,19 @@ void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex)
|
|||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
const char* BattleGroundAB::_GetNodeName(uint8 node)
|
||||
int32 BattleGroundAB::_GetNodeNameId(uint8 node)
|
||||
{
|
||||
switch (node)
|
||||
{
|
||||
case BG_AB_NODE_STABLES:
|
||||
return GetMangosString(LANG_BG_AB_NODE_STABLES);
|
||||
case BG_AB_NODE_BLACKSMITH:
|
||||
return GetMangosString(LANG_BG_AB_NODE_BLACKSMITH);
|
||||
case BG_AB_NODE_FARM:
|
||||
return GetMangosString(LANG_BG_AB_NODE_FARM);
|
||||
case BG_AB_NODE_LUMBER_MILL:
|
||||
return GetMangosString(LANG_BG_AB_NODE_LUMBER_MILL);
|
||||
case BG_AB_NODE_GOLD_MINE:
|
||||
return GetMangosString(LANG_BG_AB_NODE_GOLD_MINE);
|
||||
case BG_AB_NODE_STABLES: return LANG_BG_AB_NODE_STABLES;
|
||||
case BG_AB_NODE_BLACKSMITH: return LANG_BG_AB_NODE_BLACKSMITH;
|
||||
case BG_AB_NODE_FARM: return LANG_BG_AB_NODE_FARM;
|
||||
case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL;
|
||||
case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
return "";
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
|
||||
|
|
@ -451,10 +415,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
|
|||
|
||||
uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam());
|
||||
|
||||
// Message to chatlog
|
||||
char buf[256];
|
||||
uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
|
||||
// Check if player really could use this banner, not cheated
|
||||
if( !(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2) )
|
||||
return;
|
||||
|
|
@ -473,7 +433,13 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
|
|||
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_CLAIMED), _GetNodeName(node), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE));
|
||||
|
||||
// FIXME: team and node names not localized
|
||||
if(teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY);
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE);
|
||||
|
||||
sound = SOUND_NODE_CLAIMED;
|
||||
}
|
||||
// If node is contested
|
||||
|
|
@ -491,7 +457,12 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
|
|||
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node));
|
||||
|
||||
// FIXME: node names not localized
|
||||
if(teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
}
|
||||
// If contested, change back to occupied
|
||||
else
|
||||
|
|
@ -506,7 +477,12 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
|
|||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = 0;
|
||||
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_DEFENDED), _GetNodeName(node));
|
||||
|
||||
// FIXME: node names not localized
|
||||
if(teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
}
|
||||
sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
|
|
@ -523,18 +499,24 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
|
|||
_SendNodeUpdate(node);
|
||||
_NodeDeOccupied(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_ASSAULTED), _GetNodeName(node));
|
||||
|
||||
// FIXME: node names not localized
|
||||
if(teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
|
||||
sound = (teamIndex == 0) ? SOUND_NODE_ASSAULTED_ALLIANCE : SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, source->GetSession(), type, LANG_UNIVERSAL, NULL, source->GetGUID(), buf, NULL);
|
||||
SendPacketToAll(&data);
|
||||
|
||||
// If node is occupied again, send "X has taken the Y" msg.
|
||||
if( m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED )
|
||||
{
|
||||
sprintf(buf, GetMangosString(LANG_BG_AB_NODE_TAKEN), (teamIndex == 0) ? GetMangosString(LANG_BG_AB_ALLY) : GetMangosString(LANG_BG_AB_HORDE), _GetNodeName(node));
|
||||
ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL);
|
||||
SendPacketToAll(&data);
|
||||
// FIXME: team and node names not localized
|
||||
if(teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node));
|
||||
}
|
||||
PlaySoundToAll(sound);
|
||||
}
|
||||
|
|
@ -591,6 +573,10 @@ void BattleGroundAB::Reset()
|
|||
m_ReputationScoreTics[BG_TEAM_ALLIANCE] = 0;
|
||||
m_ReputationScoreTics[BG_TEAM_HORDE] = 0;
|
||||
m_IsInformedNearVictory = false;
|
||||
bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
|
||||
m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks;
|
||||
m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
|
||||
|
||||
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
m_Nodes[i] = 0;
|
||||
|
|
@ -604,6 +590,20 @@ void BattleGroundAB::Reset()
|
|||
DelCreature(i);
|
||||
}
|
||||
|
||||
void BattleGroundAB::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if( winner == ALLIANCE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if( winner == HORDE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
//complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam());
|
||||
|
|
|
|||
|
|
@ -170,6 +170,11 @@ enum BG_AB_Sounds
|
|||
SOUND_NEAR_VICTORY = 8456
|
||||
};
|
||||
|
||||
#define BG_AB_NotABBGWeekendHonorTicks 330
|
||||
#define BG_AB_ABBGWeekendHonorTicks 200
|
||||
#define BG_AB_NotABBGWeekendReputationTicks 200
|
||||
#define BG_AB_ABBGWeekendReputationTicks 150
|
||||
|
||||
// x, y, z, o
|
||||
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
|
||||
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
|
||||
|
|
@ -238,10 +243,13 @@ class BattleGroundAB : public BattleGround
|
|||
|
||||
void Update(uint32 diff);
|
||||
void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
virtual bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void EndBattleGround(uint32 winner);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
||||
/* Scorekeeping */
|
||||
|
|
@ -263,7 +271,7 @@ class BattleGroundAB : public BattleGround
|
|||
void _NodeOccupied(uint8 node,Team team);
|
||||
void _NodeDeOccupied(uint8 node);
|
||||
|
||||
const char* _GetNodeName(uint8 node);
|
||||
int32 _GetNodeNameId(uint8 node);
|
||||
|
||||
/* Nodes info:
|
||||
0: neutral
|
||||
|
|
@ -271,14 +279,18 @@ class BattleGroundAB : public BattleGround
|
|||
2: horde contested
|
||||
3: ally occupied
|
||||
4: horde occupied */
|
||||
uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
int32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint32 m_TeamScores[2];
|
||||
uint32 m_lastTick[2];
|
||||
uint32 m_HonorScoreTics[2];
|
||||
uint32 m_ReputationScoreTics[2];
|
||||
bool m_IsInformedNearVictory;
|
||||
uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
int32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint32 m_TeamScores[2];
|
||||
uint32 m_lastTick[2];
|
||||
uint32 m_HonorScoreTics[2];
|
||||
uint32 m_ReputationScoreTics[2];
|
||||
bool m_IsInformedNearVictory;
|
||||
uint32 m_HonorTics;
|
||||
uint32 m_ReputationTics;
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundAV.h"
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundAV::BattleGroundAV()
|
||||
{
|
||||
|
||||
//TODO FIX ME!
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundAV::~BattleGroundAV()
|
||||
|
|
@ -39,6 +42,14 @@ void BattleGroundAV::Update(uint32 diff)
|
|||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundAV::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAV::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAV::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ class BattleGroundAV : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
|
|
|||
|
|
@ -20,15 +20,23 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundBE.h"
|
||||
#include "Creature.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundBE::BattleGroundBE()
|
||||
{
|
||||
m_BgObjects.resize(BG_BE_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundBE::~BattleGroundBE()
|
||||
|
|
@ -40,73 +48,30 @@ void BattleGroundBE::Update(uint32 diff)
|
|||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
// after bg start we get there
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if (!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
|
||||
SetStartDelayTime(START_DELAY1);
|
||||
SendMessageToAll(LANG_ARENA_ONE_MINUTE);
|
||||
}
|
||||
// After 30 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
|
||||
}
|
||||
// After 15 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
|
||||
}
|
||||
// delay expired (1 minute)
|
||||
else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
|
||||
for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
SendMessageToAll(LANG_ARENA_BEGUN);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(0);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
/*if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundBE::StartingEventCloseDoors()
|
||||
{
|
||||
for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattleGroundBE::StartingEventOpenDoors()
|
||||
{
|
||||
for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundBE::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
@ -127,10 +92,7 @@ void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
|||
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
|
@ -149,16 +111,7 @@ void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
|
|||
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ class BattleGroundBE : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,20 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundDS.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundDS::BattleGroundDS()
|
||||
{
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundDS::~BattleGroundDS()
|
||||
|
|
@ -35,6 +45,14 @@ void BattleGroundDS::Update(uint32 diff)
|
|||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundDS::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundDS::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundDS::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class BattleGroundDS : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
#include "BattleGround.h"
|
||||
#include "BattleGroundEY.h"
|
||||
#include "Creature.h"
|
||||
#include "Chat.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "Language.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Util.h"
|
||||
|
|
@ -37,6 +35,11 @@ BattleGroundEY::BattleGroundEY()
|
|||
m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
|
||||
m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
|
||||
m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundEY::~BattleGroundEY()
|
||||
|
|
@ -46,71 +49,8 @@ BattleGroundEY::~BattleGroundEY()
|
|||
void BattleGroundEY::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
// after bg start we get there (once)
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if(!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
// SpawnBGCreature(EY_SPIRIT_MAIN_ALLIANCE, RESPAWN_IMMEDIATELY);
|
||||
// SpawnBGCreature(EY_SPIRIT_MAIN_HORDE, RESPAWN_IMMEDIATELY);
|
||||
for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
|
||||
SetStartDelayTime(START_DELAY0);
|
||||
}
|
||||
// After 1 minute, warning is signalled
|
||||
else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_EY_ONE_MINUTE));
|
||||
}
|
||||
// After 1,5 minute, warning is signalled
|
||||
else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_EY_HALF_MINUTE));
|
||||
}
|
||||
// After 2 minutes, gates OPEN ! x)
|
||||
else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
|
||||
|
||||
for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
//randomly spawn buff
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
SendMessageToAll(GetMangosString(LANG_BG_EY_BEGIN));
|
||||
|
||||
PlaySoundToAll(SOUND_BG_START);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
|
||||
}
|
||||
}
|
||||
else if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
if( GetStatus() == STATUS_IN_PROGRESS )
|
||||
{
|
||||
m_PointAddingTimer -= diff;
|
||||
if(m_PointAddingTimer <= 0)
|
||||
|
|
@ -152,15 +92,39 @@ void BattleGroundEY::Update(uint32 diff)
|
|||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::StartingEventCloseDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattleGroundEY::StartingEventOpenDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
|
||||
|
||||
for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
//randomly spawn buff
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
|
||||
{
|
||||
uint8 team_index = GetTeamIndexByTeamId(Team);
|
||||
m_TeamScores[team_index] += Points;
|
||||
m_HonorScoreTics[team_index] += Points;
|
||||
if (m_HonorScoreTics[team_index] >= BG_HONOR_SCORE_TICKS)
|
||||
if (m_HonorScoreTics[team_index] >= m_HonorTics )
|
||||
{
|
||||
RewardHonorToTeam(20, Team);
|
||||
m_HonorScoreTics[team_index] -= BG_HONOR_SCORE_TICKS;
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
|
||||
m_HonorScoreTics[team_index] -= m_HonorTics;
|
||||
}
|
||||
UpdateTeamScore(Team);
|
||||
}
|
||||
|
|
@ -183,7 +147,7 @@ void BattleGroundEY::CheckSomeoneJoinedPoint()
|
|||
++j;
|
||||
continue;
|
||||
}
|
||||
if (plr->isAllowUseBattleGroundObject() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
if (plr->CanCaptureTowerPoint() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
{
|
||||
//player joined point!
|
||||
//show progress bar
|
||||
|
|
@ -226,7 +190,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint()
|
|||
++j;
|
||||
continue;
|
||||
}
|
||||
if (!plr->isAllowUseBattleGroundObject() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
if (!plr->CanCaptureTowerPoint() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
//move player out of point (add him to players that are out of points
|
||||
{
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
|
||||
|
|
@ -306,6 +270,20 @@ void BattleGroundEY::UpdateTeamScore(uint32 Team)
|
|||
UpdateWorldState(EY_HORDE_RESOURCES, score);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if( winner == ALLIANCE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if( winner == HORDE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
//complete map reward
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdatePointsCount(uint32 Team)
|
||||
{
|
||||
if(Team == ALLIANCE)
|
||||
|
|
@ -530,6 +508,8 @@ void BattleGroundEY::Reset()
|
|||
m_DroppedFlagGUID = 0;
|
||||
m_PointAddingTimer = 0;
|
||||
m_TowerCapCheckTimer = 0;
|
||||
bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
|
||||
uint32 m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
|
||||
|
||||
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
|
|
@ -554,7 +534,7 @@ void BattleGroundEY::RespawnFlag(bool send_message)
|
|||
|
||||
if(send_message)
|
||||
{
|
||||
SendMessageToAll(GetMangosString(LANG_BG_EY_RESETED_FLAG));
|
||||
SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound...
|
||||
}
|
||||
|
||||
|
|
@ -603,32 +583,20 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
|
|||
if(GetFlagPickerGUID() != Source->GetGUID())
|
||||
return;
|
||||
|
||||
const char *message = "";
|
||||
uint8 type = 0;
|
||||
|
||||
SetFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
|
||||
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
|
||||
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
message = GetMangosString(LANG_BG_EY_DROPPED_FLAG);
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
message = GetMangosString(LANG_BG_EY_DROPPED_FLAG);
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
}
|
||||
//this does not work correctly :( (it should remove flag carrier name)
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
|
||||
|
|
@ -636,20 +604,14 @@ void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
if(GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
|
||||
return;
|
||||
|
||||
const char *message;
|
||||
uint8 type = 0;
|
||||
message = GetMangosString(LANG_BG_EY_HAS_TAKEN_FLAG);
|
||||
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
|
||||
}
|
||||
|
||||
|
|
@ -663,9 +625,10 @@ void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
||||
|
|
@ -674,8 +637,6 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
|||
return;
|
||||
|
||||
//Natural point
|
||||
uint8 message_type = 0;
|
||||
const char *message = "";
|
||||
uint32 Team = m_PointOwnedByTeam[Point];
|
||||
|
||||
if(!Team)
|
||||
|
|
@ -684,8 +645,6 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
|||
if (Team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
|
||||
message_type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
message = GetMangosString(m_LoosingPointTypes[Point].MessageIdAlliance);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
|
||||
|
|
@ -693,8 +652,6 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
|||
else
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_HORDE]--;
|
||||
message_type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
message = GetMangosString(m_LoosingPointTypes[Point].MessageIdHorde);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
|
||||
|
|
@ -709,9 +666,10 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
|||
m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
|
||||
m_PointState[Point] = EY_POINT_NO_OWNER;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), message_type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
if (Team == ALLIANCE)
|
||||
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
UpdatePointsIcons(Team, Point);
|
||||
UpdatePointsCount(Team);
|
||||
|
|
@ -722,8 +680,6 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
|
|||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint8 type = 0;
|
||||
const char *message = "";
|
||||
uint32 Team = Source->GetTeam();
|
||||
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
|
||||
|
|
@ -733,8 +689,6 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
|
|||
if (Team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
message = GetMangosString(m_CapturingPointTypes[Point].MessageIdAlliance);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
|
||||
|
|
@ -742,8 +696,6 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
|
|||
else
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_HORDE]++;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
message = GetMangosString(m_CapturingPointTypes[Point].MessageIdHorde);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
|
||||
|
|
@ -754,9 +706,10 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
|
|||
m_PointOwnedByTeam[Point] = Team;
|
||||
m_PointState[Point] = EY_POINT_UNDER_CONTROL;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
if (Team == ALLIANCE)
|
||||
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
if(m_BgCreatures[Point])
|
||||
DelCreature(Point);
|
||||
|
|
@ -778,38 +731,33 @@ void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType
|
|||
if(GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
|
||||
return;
|
||||
|
||||
uint8 type = 0;
|
||||
uint8 team_id = 0;
|
||||
const char *message = "";
|
||||
|
||||
SetFlagPicker(0);
|
||||
m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
team_id = BG_TEAM_ALLIANCE;
|
||||
message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_A);
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
|
||||
team_id = BG_TEAM_HORDE;
|
||||
message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_H);
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
}
|
||||
|
||||
SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
|
||||
|
||||
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
|
||||
m_FlagCapturedBgObjectType = BgObjectType;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
uint8 team_id = 0;
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
team_id = BG_TEAM_ALLIANCE;
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
}
|
||||
else
|
||||
{
|
||||
team_id = BG_TEAM_HORDE;
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
}
|
||||
|
||||
if(m_TeamPointsCount[team_id] > 0)
|
||||
AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
|
||||
|
|
|
|||
|
|
@ -210,6 +210,9 @@ enum EYBattleGroundObjectTypes
|
|||
BG_EY_OBJECT_MAX = 59
|
||||
};
|
||||
|
||||
#define BG_EY_NotEYWeekendHonorTicks 330
|
||||
#define BG_EY_EYWeekendHonorTicks 200
|
||||
|
||||
enum BG_EY_FlagState
|
||||
{
|
||||
BG_EY_FLAG_STATE_ON_BASE = 0,
|
||||
|
|
@ -302,6 +305,8 @@ class BattleGroundEY : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetFlagPickerGUID() const { return m_FlagKeeper; }
|
||||
|
|
@ -319,6 +324,7 @@ class BattleGroundEY : public BattleGround
|
|||
virtual bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void UpdateTeamScore(uint32 Team);
|
||||
void EndBattleGround(uint32 winner);
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
|
||||
virtual void FillInitialWorldStates(WorldPacket& data);
|
||||
void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;}
|
||||
|
|
@ -368,5 +374,6 @@ class BattleGroundEY : public BattleGround
|
|||
uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX];
|
||||
|
||||
int32 m_PointAddingTimer;
|
||||
uint32 m_HonorTics;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldSession.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Object.h"
|
||||
#include "Chat.h"
|
||||
|
|
@ -111,9 +110,9 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
|||
return;
|
||||
|
||||
// get bg instance or bg template if instance not found
|
||||
BattleGround * bg = 0;
|
||||
BattleGround * bg = NULL;
|
||||
if(instanceId)
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId);
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
|
||||
if(!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
|
||||
{
|
||||
|
|
@ -157,10 +156,11 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
|||
// if we're here, then the conditions to join a bg are met. We can proceed in joining.
|
||||
|
||||
// _player->GetGroup() was already checked, grp is already initialized
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
|
||||
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
if(joinAsGroup /* && _player->GetGroup()*/)
|
||||
{
|
||||
sLog.outDebug("Battleground: the following players are joining as group:");
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
|
||||
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
|
|
@ -173,7 +173,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
|||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
|
|
@ -181,9 +181,6 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
|||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
sLog.outDebug("Battleground: group end");
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
if(!ginfo->IsInvitedToBGInstanceGUID)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -194,16 +191,15 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
|||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0);
|
||||
SendPacket(&data);
|
||||
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, false, 0);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
if(!ginfo->IsInvitedToBGInstanceGUID)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
|
||||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
if(!ginfo->IsInvitedToBGInstanceGUID)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
|
||||
|
|
@ -323,22 +319,16 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
|||
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
|
||||
// if the player is not in queue, continue
|
||||
if(itrPlayerStatus == qpMap.end())
|
||||
continue;
|
||||
|
||||
// no group information, this should never happen
|
||||
if(!itrPlayerStatus->second.GroupInfo)
|
||||
// if the player is not in queue, continue or no group information - this should never happen
|
||||
if(itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo)
|
||||
continue;
|
||||
|
||||
BattleGround * bg = NULL;
|
||||
|
||||
// get possibly needed data from groupinfo
|
||||
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
uint8 israted = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
uint8 status = 0;
|
||||
|
||||
|
||||
if(!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
// not invited to bg, get template
|
||||
|
|
@ -362,7 +352,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
|||
|
||||
// re - invite player with proper data
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, itrPlayerStatus->second.GroupInfo->Team?itrPlayerStatus->second.GroupInfo->Team:_player->GetTeam(), i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype, israted);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
|
@ -429,6 +419,12 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
|||
sLog.outError("Battleground: Invalid player queue info!");
|
||||
return;
|
||||
}
|
||||
//if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
|
||||
if( arenatype == 0 && !_player->CanJoinToBattleground() )
|
||||
{
|
||||
sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
|
||||
action = 0;
|
||||
}
|
||||
WorldPacket data;
|
||||
switch(action)
|
||||
{
|
||||
|
|
@ -449,7 +445,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
|||
}
|
||||
_player->RemoveFromGroup();
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
// remove battleground queue status from BGmgr
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false);
|
||||
|
|
@ -484,7 +480,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
|||
}
|
||||
}
|
||||
_player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true);
|
||||
// player left queue, we should update it, maybe now his group fits in
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId,_player->GetBattleGroundQueueIdFromLevel(bgTypeId),arenatype,israted,rating);
|
||||
|
|
@ -528,84 +524,41 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
|
|||
sLog.outDebug( "WORLD: Battleground status" );
|
||||
|
||||
WorldPacket data;
|
||||
uint32 queueSlot = PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
|
||||
// TODO: we must put player back to battleground in case disconnect (< 5 minutes offline time) or teleport player on login(!) from battleground map to entry point
|
||||
if(_player->InBattleGround())
|
||||
{
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if(bg)
|
||||
if(!bg)
|
||||
return;
|
||||
BattleGroundQueueTypeId bgQueueTypeId_tmp = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId_tmp);
|
||||
if((bg->GetStatus() <= STATUS_IN_PROGRESS))
|
||||
{
|
||||
BattleGroundQueueTypeId bgQueueTypeId_tmp = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId_tmp);
|
||||
if((bg->GetStatus() <= STATUS_IN_PROGRESS))
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
SendPacket(&data);
|
||||
}
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
|
||||
if (i == queueSlot || !bgQueueTypeId)
|
||||
continue;
|
||||
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
|
||||
uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId);
|
||||
uint8 isRated = 0;
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
|
||||
if(itrPlayerStatus == qpMap.end())
|
||||
continue;
|
||||
if(itrPlayerStatus->second.GroupInfo)
|
||||
{
|
||||
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
isRated = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
}
|
||||
BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if(bg2)
|
||||
{
|
||||
//in this call is small bug, this call should be filled by player's waiting time in queue
|
||||
//this call nulls all timers for client :
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0,arenatype,isRated);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we should update all queues? .. i'm not sure if this code is correct
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
|
||||
if(!bgQueueTypeId)
|
||||
continue;
|
||||
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
|
||||
uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId);
|
||||
uint8 isRated = 0;
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
|
||||
if(itrPlayerStatus == qpMap.end())
|
||||
continue;
|
||||
if(itrPlayerStatus->second.GroupInfo)
|
||||
{
|
||||
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
isRated = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
}
|
||||
if(bg)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else // not sure if it needed...
|
||||
{
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, NULL, _player->GetTeam(),i , STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
SendPacket(&data);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
// we should update all queues? .. i'm not sure if this code is correct
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
|
||||
if(!bgQueueTypeId || i == queueSlot) //queueslot check in case we already send it in the above code
|
||||
continue;
|
||||
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
|
||||
uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId);
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if(!bg)
|
||||
continue;
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
|
||||
if(itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo)
|
||||
continue;
|
||||
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTime()-itrPlayerStatus->second.GroupInfo->JoinTime, arenatype);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data )
|
||||
|
|
@ -768,9 +721,10 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
|||
arenaRating = avg_pers_rating;
|
||||
}
|
||||
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
|
||||
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
|
||||
if(asGroup)
|
||||
{
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
|
||||
sLog.outDebug("Battleground: arena join as group start");
|
||||
if(isRated)
|
||||
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
|
||||
|
|
@ -786,7 +740,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
|||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
|
|
@ -794,7 +748,6 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
|||
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
sLog.outDebug("Battleground: arena join as group end");
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
|
||||
if(isRated)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
|
||||
}
|
||||
|
|
@ -807,13 +760,12 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
|||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
|
||||
SendPacket(&data);
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
|
||||
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattleGroundReportAFK( WorldPacket & recv_data )
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@ INSTANTIATE_SINGLETON_1( BattleGroundMgr );
|
|||
|
||||
BattleGroundQueue::BattleGroundQueue()
|
||||
{
|
||||
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
|
||||
{
|
||||
for(uint32 j = 0; j < MAX_BATTLEGROUND_QUEUES; j++)
|
||||
{
|
||||
m_SumOfWaitTimes[i][j] = 0;
|
||||
m_WaitTimeLastPlayer[i][j] = 0;
|
||||
for(uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; k++)
|
||||
m_WaitTimes[i][j][k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BattleGroundQueue::~BattleGroundQueue()
|
||||
|
|
@ -81,7 +91,7 @@ void BattleGroundQueue::SelectionPool::Init()
|
|||
|
||||
// remove group info from selection pool
|
||||
// returns true when we need to try to add new group to selection pool
|
||||
// or false when pool is ok
|
||||
// returns false when selection pool is ok or when we kicked smaller group than we need to kick
|
||||
// sometimes it can be called on empty selection pool
|
||||
bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
|
||||
{
|
||||
|
|
@ -105,7 +115,8 @@ bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
|
|||
GroupQueueInfo* ginfo = (*groupToKick);
|
||||
SelectedGroups.erase(groupToKick);
|
||||
PlayerCount -= ginfo->Players.size();
|
||||
if (abs((int32)(ginfo->Players.size() - size)) <= 1)
|
||||
//return false if we kicked smaller group or there are enough players in selection pool
|
||||
if (ginfo->Players.size() <= size + 1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -113,8 +124,8 @@ bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
|
|||
|
||||
// add group to selection pool
|
||||
// used when building selection pools
|
||||
// returns true if we can invite more players
|
||||
// returns false when selection pool is set
|
||||
// returns true if we can invite more players, or when we added group to selection pool
|
||||
// returns false when selection pool is full
|
||||
bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount)
|
||||
{
|
||||
//if group is larger than desired count - don't allow to add it to pool
|
||||
|
|
@ -123,6 +134,7 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
|
|||
SelectedGroups.push_back(ginfo);
|
||||
// increase selected players count
|
||||
PlayerCount += ginfo->Players.size();
|
||||
return true;
|
||||
}
|
||||
if( PlayerCount < desiredCount )
|
||||
return true;
|
||||
|
|
@ -147,7 +159,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId
|
|||
ginfo->ArenaTeamId = arenateamid;
|
||||
ginfo->IsRated = isRated;
|
||||
ginfo->IsInvitedToBGInstanceGUID = 0;
|
||||
ginfo->JoinTime = getMSTime();
|
||||
ginfo->JoinTime = sWorld.GetGameTime() * IN_MILISECONDS;
|
||||
ginfo->Team = leader->GetTeam();
|
||||
ginfo->ArenaTeamRating = arenaRating;
|
||||
ginfo->OpponentsTeamRating = 0;
|
||||
|
|
@ -173,8 +185,6 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
|
|||
{
|
||||
//if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak
|
||||
PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()];
|
||||
info.InviteTime = 0;
|
||||
info.LastInviteTime = 0;
|
||||
info.LastOnlineTime = getMSTime();
|
||||
info.GroupInfo = ginfo;
|
||||
|
||||
|
|
@ -182,6 +192,55 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
|
|||
ginfo->Players[plr->GetGUID()] = &info;
|
||||
}
|
||||
|
||||
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
|
||||
{
|
||||
uint32 timeInQueue = (sWorld.GetGameTime() * IN_MILISECONDS) - ginfo->JoinTime;
|
||||
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
|
||||
if( !ginfo->ArenaType )
|
||||
{
|
||||
if( ginfo->Team == HORDE )
|
||||
team_index = BG_TEAM_HORDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ginfo->IsRated )
|
||||
team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
|
||||
}
|
||||
|
||||
//store pointer to arrayindex of player that was added first
|
||||
uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]);
|
||||
//remove his time from sum
|
||||
m_SumOfWaitTimes[team_index][queue_id] -= m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)];
|
||||
//set average time to new
|
||||
m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)] = timeInQueue;
|
||||
//add new time to sum
|
||||
m_SumOfWaitTimes[team_index][queue_id] += timeInQueue;
|
||||
//set index of last player added to next one
|
||||
(*lastPlayerAddedPointer)++;
|
||||
(*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
|
||||
}
|
||||
|
||||
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
|
||||
{
|
||||
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
|
||||
if( !ginfo->ArenaType )
|
||||
{
|
||||
if( ginfo->Team == HORDE )
|
||||
team_index = BG_TEAM_HORDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ginfo->IsRated )
|
||||
team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
|
||||
}
|
||||
//check if there is enought values(we always add values > 0)
|
||||
if(m_WaitTimes[team_index][queue_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] )
|
||||
return (m_SumOfWaitTimes[team_index][queue_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME);
|
||||
else
|
||||
//if there aren't enough values return 0 - not available
|
||||
return 0;
|
||||
}
|
||||
|
||||
//remove player from queue and from group info, if group info is empty then remove it too
|
||||
void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount)
|
||||
{
|
||||
|
|
@ -232,7 +291,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
|
|||
}
|
||||
sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id);
|
||||
|
||||
// ALL variables are corrcetly set
|
||||
// ALL variables are correctly set
|
||||
// We can ignore leveling up in queue - it should not cause crash
|
||||
// remove player from group
|
||||
// if only one player there, remove group
|
||||
|
|
@ -257,6 +316,22 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
|
|||
if( (decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty()) )
|
||||
AnnounceWorld(group, guid, false);
|
||||
|
||||
//if player leaves queue and he is invited to rated arena match, then he have to loose
|
||||
if( group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount )
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(group->ArenaTeamId);
|
||||
if( at )
|
||||
{
|
||||
sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(guid), group->OpponentsTeamRating);
|
||||
Player *plr = objmgr.GetPlayer(guid);
|
||||
if( plr )
|
||||
at->MemberLost(plr, group->OpponentsTeamRating);
|
||||
else
|
||||
at->OfflineMemberLost(guid, group->OpponentsTeamRating);
|
||||
at->SaveToDB();
|
||||
}
|
||||
}
|
||||
|
||||
// remove group queue info if needed
|
||||
if( group->Players.empty() )
|
||||
{
|
||||
|
|
@ -278,7 +353,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
|
|||
plr2->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to
|
||||
// queue->removeplayer, it causes bugs
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr2->GetTeam(), queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0);
|
||||
plr2->GetSession()->SendPacket(&data);
|
||||
}
|
||||
// then actually delete, this may delete the group as well!
|
||||
|
|
@ -355,13 +430,10 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
// set invitation
|
||||
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
|
||||
// loop through the players
|
||||
for(std::map<uint64,PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
|
||||
{
|
||||
// set status
|
||||
itr->second->InviteTime = getMSTime();
|
||||
itr->second->LastInviteTime = getMSTime();
|
||||
|
||||
// get the player
|
||||
Player* plr = objmgr.GetPlayer(itr->first);
|
||||
// if offline, skip him, this should not happen - player is removed from queue when he logs out
|
||||
|
|
@ -369,6 +441,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
continue;
|
||||
|
||||
// invite the player
|
||||
PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id);
|
||||
sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID(), bg->GetTypeID(), ginfo->Team);
|
||||
|
||||
WorldPacket data;
|
||||
|
|
@ -378,7 +451,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
sLog.outDebug("Battleground: invited plr %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.",plr->GetName(),plr->GetGUIDLow(),bg->GetInstanceID(),queueSlot,bg->GetTypeID());
|
||||
|
||||
// send status packet
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, side?side:plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -410,7 +483,6 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
|
|||
{
|
||||
// after removing this much playerinfos, the ginfo will be deleted, so we'll use a for loop
|
||||
uint32 to_remove = ginfo->Players.size();
|
||||
uint32 team = ginfo->Team;
|
||||
for(uint32 j = 0; j < to_remove; j++)
|
||||
{
|
||||
// always remove the first one in the group
|
||||
|
|
@ -436,7 +508,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
|
|||
// remove player from queue, this might delete the ginfo as well! don't use that pointer after this!
|
||||
RemovePlayer(itr2->first, true);
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, team, queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
|
@ -499,7 +571,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
|
|||
//if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
|
||||
if( !m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() )
|
||||
{
|
||||
if( aliFree <= diffHorde - 1 )
|
||||
if( aliFree <= diffHorde + 1 )
|
||||
break;
|
||||
m_SelectionPools[BG_TEAM_HORDE].KickGroup(diffHorde - diffAli);
|
||||
}
|
||||
|
|
@ -514,7 +586,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
|
|||
}
|
||||
if( !m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() )
|
||||
{
|
||||
if( hordeFree <= diffAli - 1 )
|
||||
if( hordeFree <= diffAli + 1 )
|
||||
break;
|
||||
m_SelectionPools[BG_TEAM_ALLIANCE].KickGroup(diffAli - diffHorde);
|
||||
}
|
||||
|
|
@ -622,7 +694,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
|
|||
return false;
|
||||
}
|
||||
//allow 1v0 if debug bg
|
||||
if( sBattleGroundMgr.isTesting() && (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()) )
|
||||
if( sBattleGroundMgr.isTesting() && bg_template->isBattleGround() && (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()) )
|
||||
return true;
|
||||
//return true if there are enough players in selection pools - enable to work .debug bg command correctly
|
||||
return m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers;
|
||||
|
|
@ -995,7 +1067,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
|||
if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, qItr->second.GroupInfo->Team, queueSlot, STATUS_WAIT_JOIN, INVITATION_REMIND_TIME, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITATION_REMIND_TIME, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1030,21 +1102,11 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
|||
BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid);
|
||||
if (qMapItr != qpMap.end() && qMapItr->second.GroupInfo && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
|
||||
{
|
||||
if (qMapItr->second.GroupInfo->IsRated)
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(qMapItr->second.GroupInfo->ArenaTeamId);
|
||||
if (at)
|
||||
{
|
||||
sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(plr->GetGUID()), qMapItr->second.GroupInfo->OpponentsTeamRating);
|
||||
at->MemberLost(plr, qMapItr->second.GroupInfo->OpponentsTeamRating);
|
||||
at->SaveToDB();
|
||||
}
|
||||
}
|
||||
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bg->GetTypeID(), bg->GetQueueId());
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, m_PlayersTeam, queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1075,10 +1137,10 @@ BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe
|
|||
|
||||
BattleGroundMgr::~BattleGroundMgr()
|
||||
{
|
||||
DeleteAlllBattleGrounds();
|
||||
DeleteAllBattleGrounds();
|
||||
}
|
||||
|
||||
void BattleGroundMgr::DeleteAlllBattleGrounds()
|
||||
void BattleGroundMgr::DeleteAllBattleGrounds()
|
||||
{
|
||||
for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
|
||||
{
|
||||
|
|
@ -1086,6 +1148,8 @@ void BattleGroundMgr::DeleteAlllBattleGrounds()
|
|||
{
|
||||
BattleGround * bg = itr->second;
|
||||
m_BattleGrounds[i].erase(itr++);
|
||||
if(!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
|
||||
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
|
||||
delete bg;
|
||||
}
|
||||
}
|
||||
|
|
@ -1120,6 +1184,8 @@ void BattleGroundMgr::Update(uint32 diff)
|
|||
{
|
||||
BattleGround * bg = itr->second;
|
||||
m_BattleGrounds[i].erase(itr);
|
||||
if(!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty())
|
||||
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID());
|
||||
delete bg;
|
||||
}
|
||||
}
|
||||
|
|
@ -1160,7 +1226,7 @@ void BattleGroundMgr::Update(uint32 diff)
|
|||
}
|
||||
}
|
||||
|
||||
void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype, uint8 israted)
|
||||
void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype)
|
||||
{
|
||||
// we can be in 3 queues in same time...
|
||||
if(StatusID == 0)
|
||||
|
|
@ -1175,9 +1241,10 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
|
|||
*data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time
|
||||
// uint64 in client
|
||||
*data << uint64( uint64(arenatype ? arenatype : bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) );
|
||||
*data << uint32(0); // unknown
|
||||
*data << uint32(bg->GetClientInstanceID());
|
||||
// alliance/horde for BG and skirmish/rated for Arenas
|
||||
*data << uint8(bg->isArena() ? ( israted ? israted : bg->isRated() ) : bg->GetTeamIndexByTeamId(team));
|
||||
// following displays the minimap-icon 0 = faction icon 1 = arenaicon
|
||||
*data << uint8(bg->isArena());
|
||||
/* *data << uint8(arenatype ? arenatype : bg->GetArenaType()); // team type (0=BG, 2=2x2, 3=3x3, 5=5x5), for arenas // NOT PROPER VALUE IF ARENA ISN'T RUNNING YET!!!!
|
||||
switch(bg->GetTypeID()) // value depends on bg id
|
||||
{
|
||||
|
|
@ -1227,10 +1294,7 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
|
|||
*data << uint16(0x1F90); // unk value 8080
|
||||
*data << uint32(bg->GetInstanceID()); // instance id
|
||||
|
||||
if(bg->isBattleGround())
|
||||
*data << uint8(bg->GetTeamIndexByTeamId(team)); // team
|
||||
else
|
||||
*data << uint8(israted?israted:bg->isRated()); // is rated battle
|
||||
*data << uint8(bg->isArena()); // minimap-icon 0=faction 1=arena
|
||||
*/
|
||||
*data << uint32(StatusID); // status
|
||||
switch(StatusID)
|
||||
|
|
@ -1386,10 +1450,10 @@ void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid)
|
|||
*data << uint32(soundid);
|
||||
}
|
||||
|
||||
void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr)
|
||||
void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid)
|
||||
{
|
||||
data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8);
|
||||
*data << uint64(plr->GetGUID());
|
||||
*data << uint64(guid);
|
||||
}
|
||||
|
||||
void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr)
|
||||
|
|
@ -1435,6 +1499,25 @@ void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, BattleGro
|
|||
plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
|
||||
}
|
||||
|
||||
BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
|
||||
{
|
||||
//cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
|
||||
//SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id
|
||||
BattleGround* bg = GetBattleGroundTemplate(bgTypeId);
|
||||
if( !bg )
|
||||
return NULL;
|
||||
|
||||
if(bg->isArena())
|
||||
return GetBattleGround(instanceId, bgTypeId);
|
||||
|
||||
for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr)
|
||||
{
|
||||
if(itr->second->GetClientInstanceID() == instanceId)
|
||||
return itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId)
|
||||
{
|
||||
//search if needed
|
||||
|
|
@ -1459,6 +1542,28 @@ BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTyp
|
|||
return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
|
||||
}
|
||||
|
||||
uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
|
||||
{
|
||||
if( IsArenaType(bgTypeId) )
|
||||
return 0; //arenas don't have client-instanceids
|
||||
|
||||
// we create here an instanceid, which is just for
|
||||
// displaying this to the client and without any other use..
|
||||
// the client-instanceIds are unique for each battleground-type
|
||||
// the instance-id just needs to be as low as possible, beginning with 1
|
||||
// the following works, because std::set is default ordered with "<"
|
||||
// the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
|
||||
uint32 lastId = 0;
|
||||
for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();)
|
||||
{
|
||||
if( (++lastId) != *itr) //if there is a gap between the ids, we will break..
|
||||
break;
|
||||
lastId = *itr;
|
||||
}
|
||||
m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1);
|
||||
return lastId + 1;
|
||||
}
|
||||
|
||||
// create a new battleground that will really be used to play
|
||||
BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated)
|
||||
{
|
||||
|
|
@ -1528,6 +1633,7 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
|
|||
|
||||
// generate a new instance id
|
||||
bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id
|
||||
bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id));
|
||||
|
||||
// reset the new bg (set status to status_wait_queue from status_none)
|
||||
bg->Reset();
|
||||
|
|
@ -1752,7 +1858,7 @@ void BattleGroundMgr::DistributeArenaPoints()
|
|||
for (std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.begin(); plr_itr != PlayerPoints.end(); ++plr_itr)
|
||||
{
|
||||
//update to database
|
||||
CharacterDatabase.PExecute("UPDATE characters SET arena_pending_points = '%u' WHERE `guid` = '%u'", plr_itr->second, plr_itr->first);
|
||||
CharacterDatabase.PExecute("UPDATE characters SET arena_pending_points = '%u' WHERE guid = '%u'", plr_itr->second, plr_itr->first);
|
||||
//add points if player is online
|
||||
Player* pl = objmgr.GetPlayer(plr_itr->first);
|
||||
if (pl)
|
||||
|
|
@ -1803,16 +1909,11 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
|
|||
uint32 count = 0;
|
||||
*data << uint32(0x00); // number of bg instances
|
||||
|
||||
for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr)
|
||||
uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId);
|
||||
for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr)
|
||||
{
|
||||
// skip sending battleground template
|
||||
if( itr == m_BattleGrounds[bgTypeId].begin() )
|
||||
continue;
|
||||
if( PlayerLevel >= itr->second->GetMinLevel() && PlayerLevel <= itr->second->GetMaxLevel() )
|
||||
{
|
||||
*data << uint32(itr->second->GetInstanceID());
|
||||
++count;
|
||||
}
|
||||
*data << uint32(*itr);
|
||||
++count;
|
||||
}
|
||||
data->put<uint32>( count_pos , count);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,12 +30,11 @@ typedef std::list<BattleGround*> BGFreeSlotQueueType;
|
|||
typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
|
||||
|
||||
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
|
||||
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
|
||||
|
||||
struct GroupQueueInfo; // type predefinition
|
||||
struct PlayerQueueInfo // stores information for players in queue
|
||||
{
|
||||
uint32 InviteTime; // first invite time
|
||||
uint32 LastInviteTime; // last invite time
|
||||
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo
|
||||
};
|
||||
|
|
@ -79,6 +78,9 @@ class BattleGroundQueue
|
|||
GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
|
||||
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
|
||||
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
|
||||
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
|
||||
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
|
||||
|
||||
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
|
||||
void BGEndedRemoveInvites(BattleGround * bg);
|
||||
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
|
||||
|
|
@ -120,6 +122,9 @@ class BattleGroundQueue
|
|||
private:
|
||||
|
||||
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
|
||||
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
||||
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
|
||||
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -174,12 +179,12 @@ class BattleGroundMgr
|
|||
|
||||
/* Packet Building */
|
||||
void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr);
|
||||
void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr);
|
||||
void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid);
|
||||
void BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player *plr, BattleGroundTypeId bgTypeId);
|
||||
void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId);
|
||||
void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value);
|
||||
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
|
||||
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0);
|
||||
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0);
|
||||
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
|
||||
void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
|
||||
|
||||
|
|
@ -188,18 +193,20 @@ class BattleGroundMgr
|
|||
void InvitePlayer(Player* plr, uint32 bgInstanceGUID, BattleGroundTypeId bgTypeId, uint32 team);
|
||||
|
||||
/* Battlegrounds */
|
||||
BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
|
||||
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
|
||||
|
||||
BattleGround * GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
|
||||
BattleGround * CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
|
||||
BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
|
||||
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
|
||||
|
||||
uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
|
||||
|
||||
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
|
||||
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
|
||||
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
|
||||
|
||||
void CreateInitialBattleGrounds();
|
||||
void DeleteAlllBattleGrounds();
|
||||
void DeleteAllBattleGrounds();
|
||||
|
||||
void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId);
|
||||
|
||||
|
|
@ -240,6 +247,7 @@ class BattleGroundMgr
|
|||
|
||||
/* Battlegrounds */
|
||||
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
|
||||
std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client
|
||||
uint32 m_NextRatingDiscardUpdate;
|
||||
uint64 m_NextAutoDistributionTime;
|
||||
uint32 m_AutoDistributionTimeChecker;
|
||||
|
|
|
|||
|
|
@ -20,15 +20,23 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundNA.h"
|
||||
#include "Creature.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundNA::BattleGroundNA()
|
||||
{
|
||||
m_BgObjects.resize(BG_NA_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundNA::~BattleGroundNA()
|
||||
|
|
@ -40,70 +48,27 @@ void BattleGroundNA::Update(uint32 diff)
|
|||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
// after bg start we get there
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if (!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
SetStartDelayTime(START_DELAY1);
|
||||
SendMessageToAll(LANG_ARENA_ONE_MINUTE);
|
||||
}
|
||||
// After 30 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
|
||||
}
|
||||
// After 15 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
|
||||
}
|
||||
// delay expired (1 minute)
|
||||
else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
SendMessageToAll(LANG_ARENA_BEGUN);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(0);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
/*if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundNA::StartingEventCloseDoors()
|
||||
{
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundNA::StartingEventOpenDoors()
|
||||
{
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundNA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
@ -124,10 +89,7 @@ void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
|||
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
|
@ -146,16 +108,7 @@ void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
|
|||
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ class BattleGroundNA : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
|
|
|||
|
|
@ -20,15 +20,23 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundRL.h"
|
||||
#include "Creature.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "Language.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattleGroundRL::BattleGroundRL()
|
||||
{
|
||||
m_BgObjects.resize(BG_RL_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundRL::~BattleGroundRL()
|
||||
|
|
@ -40,71 +48,27 @@ void BattleGroundRL::Update(uint32 diff)
|
|||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if (!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
SetStartDelayTime(START_DELAY1);
|
||||
SendMessageToAll(LANG_ARENA_ONE_MINUTE);
|
||||
}
|
||||
// After 30 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x04))
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(LANG_ARENA_THIRTY_SECONDS);
|
||||
}
|
||||
// After 15 seconds, warning is signalled
|
||||
else if (GetStartDelayTime() <= START_DELAY3 && !(m_Events & 0x08))
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(LANG_ARENA_FIFTEEN_SECONDS);
|
||||
}
|
||||
// delay expired (1 minute)
|
||||
else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10))
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
SendMessageToAll(LANG_ARENA_BEGUN);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(0);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
/*if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundRL::StartingEventCloseDoors()
|
||||
{
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundRL::StartingEventOpenDoors()
|
||||
{
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundRL::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
@ -125,10 +89,7 @@ void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
|||
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
|
@ -147,16 +108,7 @@ void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
|
|||
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ class BattleGroundRL : public BattleGround
|
|||
virtual void AddPlayer(Player *plr);
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,20 @@
|
|||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundRV.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundRV::BattleGroundRV()
|
||||
{
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundRV::~BattleGroundRV()
|
||||
|
|
@ -35,6 +45,14 @@ void BattleGroundRV::Update(uint32 diff)
|
|||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundRV::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRV::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRV::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class BattleGroundRV : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
|
|
|
|||
|
|
@ -16,13 +16,18 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundSA.h"
|
||||
#include "Player.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundSA::BattleGroundSA()
|
||||
{
|
||||
|
||||
//TODO FIX ME!
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundSA::~BattleGroundSA()
|
||||
|
|
@ -35,6 +40,14 @@ void BattleGroundSA::Update(uint32 diff)
|
|||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundSA::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ class BattleGroundSA : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
#include "BattleGroundWS.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "Chat.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Language.h"
|
||||
|
|
@ -32,6 +30,11 @@ BattleGroundWS::BattleGroundWS()
|
|||
{
|
||||
m_BgObjects.resize(BG_WS_OBJECT_MAX);
|
||||
m_BgCreatures.resize(BG_CREATURES_MAX_WS);
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundWS::~BattleGroundWS()
|
||||
|
|
@ -42,75 +45,7 @@ void BattleGroundWS::Update(uint32 diff)
|
|||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
// after bg start we get there (once)
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
|
||||
{
|
||||
ModifyStartDelayTime(diff);
|
||||
|
||||
if(!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
// for(uint32 i = WS_SPIRIT_MAIN_ALLIANCE; i <= WS_SPIRIT_MAIN_HORDE; i++)
|
||||
// SpawnBGCreature(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
|
||||
{
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
DoorClose(i);
|
||||
}
|
||||
for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
|
||||
SetStartDelayTime(START_DELAY0);
|
||||
}
|
||||
// After 1 minute, warning is signalled
|
||||
else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
|
||||
{
|
||||
m_Events |= 0x04;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_ONE_MINUTE));
|
||||
}
|
||||
// After 1,5 minute, warning is signalled
|
||||
else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
|
||||
{
|
||||
m_Events |= 0x08;
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_HALF_MINUTE));
|
||||
}
|
||||
// After 2 minutes, gates OPEN ! x)
|
||||
else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
|
||||
{
|
||||
m_Events |= 0x10;
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; i++)
|
||||
DoorOpen(i);
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
|
||||
|
||||
for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_BEGIN));
|
||||
|
||||
PlaySoundToAll(SOUND_BG_START);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player* plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
|
||||
}
|
||||
}
|
||||
else if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
||||
{
|
||||
|
|
@ -155,6 +90,33 @@ void BattleGroundWS::Update(uint32 diff)
|
|||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::StartingEventCloseDoors()
|
||||
{
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
|
||||
{
|
||||
DoorClose(i);
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattleGroundWS::StartingEventOpenDoors()
|
||||
{
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; i++)
|
||||
DoorOpen(i);
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
|
||||
|
||||
for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundWS::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
|
|
@ -182,7 +144,7 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
|
|||
//when map_update will be allowed for battlegrounds this code will be useless
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_F_PLACED));
|
||||
SendMessageToAll(LANG_BG_WS_F_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound...
|
||||
}
|
||||
}
|
||||
|
|
@ -196,12 +158,12 @@ void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
|
|||
if(team == ALLIANCE)
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED));
|
||||
SendMessageToAll(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(GetMangosString(LANG_BG_WS_HORDE_FLAG_RESPAWNED));
|
||||
SendMessageToAll(LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
|
||||
|
|
@ -220,11 +182,7 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
|
|||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint8 type = 0;
|
||||
uint32 winner = 0;
|
||||
const char *message = "";
|
||||
|
||||
//TODO FIX reputation and honor gains for low level players!
|
||||
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
|
|
@ -236,13 +194,10 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
|
|||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||
// Drop Horde Flag from Player
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
message = GetMangosString(LANG_BG_WS_CAPTURED_HF);
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
if(GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
|
||||
AddPoint(ALLIANCE, 1);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
RewardReputationToTeam(890, 35, ALLIANCE); // +35 reputation
|
||||
RewardHonorToTeam(40, ALLIANCE); // +40 bonushonor
|
||||
RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -253,26 +208,26 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
|
|||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||
// Drop Alliance Flag from Player
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
message = GetMangosString(LANG_BG_WS_CAPTURED_AF);
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
if(GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE)
|
||||
AddPoint(HORDE, 1);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
|
||||
RewardReputationToTeam(889, 35, HORDE); // +35 reputation
|
||||
RewardHonorToTeam(40, HORDE); // +40 bonushonor
|
||||
RewardReputationToTeam(889, m_ReputationCapture, HORDE);
|
||||
}
|
||||
//for flag capture is reward 2 honorable kills
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(2), Source->GetTeam());
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
UpdateFlagState(Source->GetTeam(), 1); // flag state none
|
||||
UpdateTeamScore(Source->GetTeam());
|
||||
// only flag capture should be updated
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures...
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
|
||||
|
||||
if(GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
|
||||
winner = ALLIANCE;
|
||||
|
|
@ -324,8 +279,6 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
|||
return;
|
||||
}
|
||||
|
||||
const char *message = "";
|
||||
uint8 type = 0;
|
||||
bool set = false;
|
||||
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
|
|
@ -337,8 +290,6 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
|||
SetHordeFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||
message = GetMangosString(LANG_BG_WS_DROPPED_HF);
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
|
||||
set = true;
|
||||
}
|
||||
|
|
@ -352,8 +303,6 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
|||
SetAllianceFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||
message = GetMangosString(LANG_BG_WS_DROPPED_AF);
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
|
||||
set = true;
|
||||
}
|
||||
|
|
@ -364,14 +313,16 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
|||
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
UpdateFlagState(Source->GetTeam(), 1);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, uint32(-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1));
|
||||
}
|
||||
|
||||
m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
|
||||
}
|
||||
|
|
@ -382,14 +333,14 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
const char *message = NULL;
|
||||
uint8 type = 0;
|
||||
int32 message_id = 0;
|
||||
ChatMsg type;
|
||||
|
||||
//alliance flag picked up from base
|
||||
if(Source->GetTeam() == HORDE && GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
|
||||
&& m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_PICKEDUP_AF);
|
||||
message_id = LANG_BG_WS_PICKEDUP_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
|
||||
|
|
@ -405,7 +356,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
if (Source->GetTeam() == ALLIANCE && GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
|
||||
&& m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_PICKEDUP_HF);
|
||||
message_id = LANG_BG_WS_PICKEDUP_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
|
||||
|
|
@ -422,7 +373,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
{
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_RETURNED_AF);
|
||||
message_id = LANG_BG_WS_RETURNED_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
|
||||
RespawnFlag(ALLIANCE, false);
|
||||
|
|
@ -432,7 +383,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
}
|
||||
else
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_PICKEDUP_AF);
|
||||
message_id = LANG_BG_WS_PICKEDUP_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
|
||||
|
|
@ -451,7 +402,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
{
|
||||
if(Source->GetTeam() == HORDE)
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_RETURNED_HF);
|
||||
message_id = LANG_BG_WS_RETURNED_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
|
||||
RespawnFlag(HORDE, false);
|
||||
|
|
@ -461,7 +412,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
}
|
||||
else
|
||||
{
|
||||
message = GetMangosString(LANG_BG_WS_PICKEDUP_HF);
|
||||
message_id = LANG_BG_WS_PICKEDUP_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
|
||||
|
|
@ -475,12 +426,10 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
|
|||
//target_obj->Delete();
|
||||
}
|
||||
|
||||
if (!type)
|
||||
if (!message_id)
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
|
||||
SendPacketToAll(&data);
|
||||
SendMessageToAll(message_id, type, Source);
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
}
|
||||
|
||||
|
|
@ -642,16 +591,33 @@ void BattleGroundWS::Reset()
|
|||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
||||
bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
|
||||
m_ReputationCapture = (isBGWeekend) ? 45 : 35;
|
||||
m_HonorWinKills = (isBGWeekend) ? 3 : 1;
|
||||
m_HonorEndKills = (isBGWeekend) ? 4 : 2;
|
||||
|
||||
/* Spirit nodes is static at this BG and then not required deleting at BG reset.
|
||||
if(m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
|
||||
DelCreature(WS_SPIRIT_MAIN_ALLIANCE);
|
||||
|
||||
if(m_BgCreatures[WS_SPIRIT_MAIN_HORDE])
|
||||
DelCreature(WS_SPIRIT_MAIN_HORDE);
|
||||
*/
|
||||
}
|
||||
|
||||
void BattleGroundWS::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if( winner == ALLIANCE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
|
||||
if( winner == HORDE )
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
|
||||
//complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
|
|
@ -684,6 +650,29 @@ void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
|
|||
}
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
//if status in progress, it returns main graveyards with spiritguides
|
||||
//else it will return the graveyard in the flagroom - this is especially good
|
||||
//if a player dies in preparation phase - then the player can't cheat
|
||||
//and teleport to the graveyard outside the flagroom
|
||||
//and start running around, while the doors are still closed
|
||||
if(player->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
|
||||
else
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetStatus() == STATUS_IN_PROGRESS)
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
|
||||
else
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_HORDE);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE));
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ enum BG_WS_FlagState
|
|||
|
||||
enum BG_WS_Graveyards
|
||||
{
|
||||
WS_GRAVEYARD_MAIN_ALLIANCE = 771,
|
||||
WS_GRAVEYARD_MAIN_HORDE = 772
|
||||
WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
|
||||
WS_GRAVEYARD_FLAGROOM_HORDE = 770,
|
||||
WS_GRAVEYARD_MAIN_ALLIANCE = 771,
|
||||
WS_GRAVEYARD_MAIN_HORDE = 772
|
||||
};
|
||||
|
||||
enum BG_WS_CreatureTypes
|
||||
|
|
@ -138,6 +140,8 @@ class BattleGroundWS : public BattleGround
|
|||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; }
|
||||
|
|
@ -160,6 +164,8 @@ class BattleGroundWS : public BattleGround
|
|||
void HandleKillPlayer(Player *player, Player *killer);
|
||||
bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void EndBattleGround(uint32 winner);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
||||
void UpdateFlagState(uint32 team, uint32 value);
|
||||
void UpdateTeamScore(uint32 team);
|
||||
|
|
@ -181,5 +187,9 @@ class BattleGroundWS : public BattleGround
|
|||
uint32 m_TeamScores[2];
|
||||
int32 m_FlagsTimer[2];
|
||||
int32 m_FlagsDropTimer[2];
|
||||
|
||||
uint32 m_ReputationCapture;
|
||||
uint32 m_HonorWinKills;
|
||||
uint32 m_HonorEndKills;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include "Guild.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Auth/md5.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Group.h"
|
||||
#include "Database/DatabaseImpl.h"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "Player.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Chat.h"
|
||||
#include "MapManager.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
#include "AccountMgr.h"
|
||||
|
|
@ -418,26 +417,25 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||
|
||||
static ChatCommand npcCommandTable[] =
|
||||
{
|
||||
{ "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
|
||||
{ "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
|
||||
{ "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
|
||||
{ "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
|
||||
{ "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
|
||||
{ "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
|
||||
{ "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
|
||||
{ "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
|
||||
{ "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
|
||||
{ "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
|
||||
{ "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
|
||||
{ "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
|
||||
{ "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
|
||||
{ "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
|
||||
{ "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
|
||||
{ "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
|
||||
{ "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
|
||||
{ "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnDistCommand, "", NULL },
|
||||
{ "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnTimeCommand, "", NULL },
|
||||
{ "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
|
||||
{ "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
|
||||
{ "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
|
||||
{ "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
|
||||
{ "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleChangeLevelCommand, "", NULL },
|
||||
{ "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
|
||||
{ "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleAddVendorItemCommand, "", NULL },
|
||||
{ "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleDelVendorItemCommand, "", NULL },
|
||||
{ "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
|
||||
{ "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
|
||||
{ "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
|
||||
{ "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
|
||||
{ "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
|
||||
{ "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
|
||||
{ "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
|
||||
{ "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
|
||||
{ "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
|
||||
{ "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
|
||||
{ "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
|
||||
|
|
@ -445,9 +443,9 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||
{ "setdeathstate", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetDeathStateCommand, "", NULL },
|
||||
|
||||
//{ TODO: fix or remove this commands
|
||||
{ "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNameCommand, "", NULL },
|
||||
{ "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleSubNameCommand, "", NULL },
|
||||
{ "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddWeaponCommand, "", NULL },
|
||||
{ "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAddWeaponCommand, "", NULL },
|
||||
{ "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcNameCommand, "", NULL },
|
||||
{ "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSubNameCommand, "", NULL },
|
||||
//}
|
||||
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
|
|
|
|||
|
|
@ -176,10 +176,14 @@ class ChatHandler
|
|||
bool HandleModifyPhaseCommand(const char* args);
|
||||
bool HandleModifyGenderCommand(const char* args);
|
||||
|
||||
//-----------------------Npc Commands-----------------------
|
||||
bool HandleNpcAddCommand(const char* args);
|
||||
bool HandleNpcAddMoveCommand(const char* args);
|
||||
bool HandleNpcAddVendorItemCommand(const char* args);
|
||||
bool HandleNpcChangeEntryCommand(const char *args);
|
||||
bool HandleNpcChangeLevelCommand(const char* args);
|
||||
bool HandleNpcDeleteCommand(const char* args);
|
||||
bool HandleNpcDelVendorItemCommand(const char* args);
|
||||
bool HandleNpcFactionIdCommand(const char* args);
|
||||
bool HandleNpcFlagCommand(const char* args);
|
||||
bool HandleNpcFollowCommand(const char* args);
|
||||
|
|
@ -187,6 +191,7 @@ class ChatHandler
|
|||
bool HandleNpcMoveCommand(const char* args);
|
||||
bool HandleNpcPlayEmoteCommand(const char* args);
|
||||
bool HandleNpcSayCommand(const char* args);
|
||||
bool HandleNpcSetDeathStateCommand(const char* args);
|
||||
bool HandleNpcSetModelCommand(const char* args);
|
||||
bool HandleNpcSetMoveTypeCommand(const char* args);
|
||||
bool HandleNpcSetPhaseCommand(const char* args);
|
||||
|
|
@ -197,7 +202,12 @@ class ChatHandler
|
|||
bool HandleNpcUnFollowCommand(const char* args);
|
||||
bool HandleNpcWhisperCommand(const char* args);
|
||||
bool HandleNpcYellCommand(const char* args);
|
||||
bool HandleNpcSetDeathStateCommand(const char* args);
|
||||
|
||||
//TODO: NpcCommands that needs to be fixed :
|
||||
bool HandleNpcAddWeaponCommand(const char* args);
|
||||
bool HandleNpcNameCommand(const char* args);
|
||||
bool HandleNpcSubNameCommand(const char* args);
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool HandleReloadAllCommand(const char* args);
|
||||
bool HandleReloadAllAreaCommand(const char* args);
|
||||
|
|
@ -300,13 +310,8 @@ class ChatHandler
|
|||
bool HandleDebugSpellFailCommand(const char* args);
|
||||
|
||||
bool HandleGUIDCommand(const char* args);
|
||||
bool HandleNameCommand(const char* args);
|
||||
bool HandleSubNameCommand(const char* args);
|
||||
bool HandleItemMoveCommand(const char* args);
|
||||
bool HandleDeMorphCommand(const char* args);
|
||||
bool HandleAddVendorItemCommand(const char* args);
|
||||
bool HandleDelVendorItemCommand(const char* args);
|
||||
bool HandleChangeLevelCommand(const char* args);
|
||||
bool HandleSetPoiCommand(const char* args);
|
||||
bool HandleEquipErrorCommand(const char* args);
|
||||
bool HandleGoCreatureCommand(const char* args);
|
||||
|
|
@ -341,7 +346,6 @@ class ChatHandler
|
|||
bool HandleGoXYZCommand(const char* args);
|
||||
bool HandleGoZoneXYCommand(const char* args);
|
||||
bool HandleGoGridCommand(const char* args);
|
||||
bool HandleAddWeaponCommand(const char* args);
|
||||
bool HandleAllowMovementCommand(const char* args);
|
||||
bool HandleGoCommand(const char* args);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "ChannelMgr.h"
|
||||
#include "Group.h"
|
||||
#include "Guild.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptCalls.h"
|
||||
#include "Player.h"
|
||||
|
|
@ -522,44 +521,42 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
|||
}
|
||||
|
||||
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
|
||||
if (em)
|
||||
if (!em)
|
||||
return;
|
||||
|
||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
|
||||
|
||||
uint32 emote_anim = em->textid;
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
switch(emote_anim)
|
||||
{
|
||||
uint32 emote_anim = em->textid;
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
switch(emote_anim)
|
||||
{
|
||||
case EMOTE_STATE_SLEEP:
|
||||
case EMOTE_STATE_SIT:
|
||||
case EMOTE_STATE_KNEEL:
|
||||
case EMOTE_ONESHOT_NONE:
|
||||
break;
|
||||
default:
|
||||
GetPlayer()->HandleEmoteCommand(emote_anim);
|
||||
break;
|
||||
}
|
||||
|
||||
data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
|
||||
data << GetPlayer()->GetGUID();
|
||||
data << (uint32)text_emote;
|
||||
data << emoteNum;
|
||||
data << (uint32)namlen;
|
||||
if( namlen > 1 )
|
||||
{
|
||||
data.append(nam, namlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
data << (uint8)0x00;
|
||||
}
|
||||
|
||||
GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
|
||||
|
||||
//Send scripted event call
|
||||
if (pCreature && Script)
|
||||
Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
|
||||
case EMOTE_STATE_SLEEP:
|
||||
case EMOTE_STATE_SIT:
|
||||
case EMOTE_STATE_KNEEL:
|
||||
case EMOTE_ONESHOT_NONE:
|
||||
break;
|
||||
default:
|
||||
GetPlayer()->HandleEmoteCommand(emote_anim);
|
||||
break;
|
||||
}
|
||||
|
||||
data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
|
||||
data << GetPlayer()->GetGUID();
|
||||
data << (uint32)text_emote;
|
||||
data << emoteNum;
|
||||
data << (uint32)namlen;
|
||||
if( namlen > 1 )
|
||||
data.append(nam, namlen);
|
||||
else
|
||||
data << (uint8)0x00;
|
||||
|
||||
GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);
|
||||
|
||||
//Send scripted event call
|
||||
if (pCreature && Script)
|
||||
Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
|
||||
}
|
||||
|
||||
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "ObjectDefines.h"
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@
|
|||
#include "Corpse.h"
|
||||
#include "Player.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "GossipDef.h"
|
||||
#include "World.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
|
|
@ -35,7 +34,6 @@
|
|||
#include "CreatureAI.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Formulas.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "InstanceData.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
|
|
@ -1564,7 +1562,7 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
|
|||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
|
||||
if(!spellInfo)
|
||||
{
|
||||
sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
|
||||
sLog.outError("WORLD: unknown spell id %i", m_spells[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1614,7 +1612,7 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim)
|
|||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
|
||||
if(!spellInfo)
|
||||
{
|
||||
sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
|
||||
sLog.outError("WORLD: unknown spell id %i", m_spells[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2117,4 +2115,4 @@ void Creature::SetActiveObjectState( bool on )
|
|||
|
||||
if(world)
|
||||
map->Add(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "CreatureAIRegistry.h"
|
||||
#include "NullCreatureAI.h"
|
||||
#include "ReactorAI.h"
|
||||
#include "AggressorAI.h"
|
||||
|
|
@ -26,7 +25,6 @@
|
|||
#include "RandomMovementGenerator.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "MovementGeneratorImpl.h"
|
||||
#include "MapManager.h"
|
||||
#include "CreatureAIRegistry.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#ifndef MANGOS_DESTINATIONHOLDERIMP_H
|
||||
#define MANGOS_DESTINATIONHOLDERIMP_H
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolder.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,9 @@
|
|||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "UpdateData.h"
|
||||
#include "MapManager.h"
|
||||
#include "Player.h"
|
||||
|
||||
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket)
|
||||
|
|
|
|||
|
|
@ -17,16 +17,11 @@
|
|||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "GameObject.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "MapManager.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "MovementGenerator.h"
|
||||
#include "DestinationHolder.h"
|
||||
#include "Traveller.h"
|
||||
#include "MapManager.h"
|
||||
|
||||
template<class T>
|
||||
class MANGOS_DLL_SPEC FleeingMovementGenerator
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
|
|||
data.Initialize( SMSG_GMTICKET_CREATE, 4 );
|
||||
data << uint32(2);
|
||||
SendPacket( &data );
|
||||
DEBUG_LOG("update the ticket\n");
|
||||
DEBUG_LOG("update the ticket");
|
||||
|
||||
//TODO: Guard player map
|
||||
HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "GameEvent.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "World.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PoolHandler.h"
|
||||
|
|
@ -26,9 +26,9 @@
|
|||
#include "MapManager.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(GameEvent);
|
||||
INSTANTIATE_SINGLETON_1(GameEventMgr);
|
||||
|
||||
bool GameEvent::CheckOneGameEvent(uint16 entry) const
|
||||
bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
|
||||
{
|
||||
// Get the event information
|
||||
time_t currenttime = time(NULL);
|
||||
|
|
@ -39,7 +39,7 @@ bool GameEvent::CheckOneGameEvent(uint16 entry) const
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32 GameEvent::NextCheck(uint16 entry) const
|
||||
uint32 GameEventMgr::NextCheck(uint16 entry) const
|
||||
{
|
||||
time_t currenttime = time(NULL);
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ uint32 GameEvent::NextCheck(uint16 entry) const
|
|||
return delay;
|
||||
}
|
||||
|
||||
void GameEvent::StartEvent( uint16 event_id, bool overwrite )
|
||||
void GameEventMgr::StartEvent( uint16 event_id, bool overwrite )
|
||||
{
|
||||
AddActiveEvent(event_id);
|
||||
ApplyNewEvent(event_id);
|
||||
|
|
@ -77,7 +77,7 @@ void GameEvent::StartEvent( uint16 event_id, bool overwrite )
|
|||
}
|
||||
}
|
||||
|
||||
void GameEvent::StopEvent( uint16 event_id, bool overwrite )
|
||||
void GameEventMgr::StopEvent( uint16 event_id, bool overwrite )
|
||||
{
|
||||
RemoveActiveEvent(event_id);
|
||||
UnApplyEvent(event_id);
|
||||
|
|
@ -89,7 +89,7 @@ void GameEvent::StopEvent( uint16 event_id, bool overwrite )
|
|||
}
|
||||
}
|
||||
|
||||
void GameEvent::LoadFromDB()
|
||||
void GameEventMgr::LoadFromDB()
|
||||
{
|
||||
{
|
||||
QueryResult *result = WorldDatabase.Query("SELECT MAX(entry) FROM game_event");
|
||||
|
|
@ -108,7 +108,7 @@ void GameEvent::LoadFromDB()
|
|||
mGameEvent.resize(max_event_id+1);
|
||||
}
|
||||
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,description FROM game_event");
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time),occurence,length,holiday,description FROM game_event");
|
||||
if( !result )
|
||||
{
|
||||
mGameEvent.clear();
|
||||
|
|
@ -142,6 +142,8 @@ void GameEvent::LoadFromDB()
|
|||
pGameEvent.end = time_t(endtime);
|
||||
pGameEvent.occurence = fields[3].GetUInt32();
|
||||
pGameEvent.length = fields[4].GetUInt32();
|
||||
pGameEvent.holiday_id = fields[5].GetUInt32();
|
||||
|
||||
|
||||
if(pGameEvent.length==0) // length>0 is validity check
|
||||
{
|
||||
|
|
@ -149,7 +151,16 @@ void GameEvent::LoadFromDB()
|
|||
continue;
|
||||
}
|
||||
|
||||
pGameEvent.description = fields[5].GetCppString();
|
||||
if(pGameEvent.holiday_id)
|
||||
{
|
||||
if(!sHolidaysStore.LookupEntry(pGameEvent.holiday_id))
|
||||
{
|
||||
sLog.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id,pGameEvent.holiday_id);
|
||||
pGameEvent.holiday_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pGameEvent.description = fields[6].GetCppString();
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
|
@ -405,7 +416,7 @@ void GameEvent::LoadFromDB()
|
|||
}
|
||||
}
|
||||
|
||||
uint32 GameEvent::Initialize() // return the next event delay in ms
|
||||
uint32 GameEventMgr::Initialize() // return the next event delay in ms
|
||||
{
|
||||
m_ActiveEvents.clear();
|
||||
uint32 delay = Update();
|
||||
|
|
@ -414,7 +425,7 @@ uint32 GameEvent::Initialize() // return the next e
|
|||
return delay;
|
||||
}
|
||||
|
||||
uint32 GameEvent::Update() // return the next event delay in ms
|
||||
uint32 GameEventMgr::Update() // return the next event delay in ms
|
||||
{
|
||||
uint32 nextEventDelay = max_ge_check_delay; // 1 day
|
||||
uint32 calcDelay;
|
||||
|
|
@ -450,7 +461,7 @@ uint32 GameEvent::Update() // return the next e
|
|||
return (nextEventDelay + 1) * IN_MILISECONDS; // Add 1 second to be sure event has started/stopped at next call
|
||||
}
|
||||
|
||||
void GameEvent::UnApplyEvent(uint16 event_id)
|
||||
void GameEventMgr::UnApplyEvent(uint16 event_id)
|
||||
{
|
||||
sLog.outString("GameEvent %u \"%s\" removed.", event_id, mGameEvent[event_id].description.c_str());
|
||||
// un-spawn positive event tagged objects
|
||||
|
|
@ -464,7 +475,7 @@ void GameEvent::UnApplyEvent(uint16 event_id)
|
|||
UpdateEventQuests(event_id, false);
|
||||
}
|
||||
|
||||
void GameEvent::ApplyNewEvent(uint16 event_id)
|
||||
void GameEventMgr::ApplyNewEvent(uint16 event_id)
|
||||
{
|
||||
switch(sWorld.getConfig(CONFIG_EVENT_ANNOUNCE))
|
||||
{
|
||||
|
|
@ -487,13 +498,13 @@ void GameEvent::ApplyNewEvent(uint16 event_id)
|
|||
UpdateEventQuests(event_id, true);
|
||||
}
|
||||
|
||||
void GameEvent::GameEventSpawn(int16 event_id)
|
||||
void GameEventMgr::GameEventSpawn(int16 event_id)
|
||||
{
|
||||
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
||||
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
|
||||
sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +537,7 @@ void GameEvent::GameEventSpawn(int16 event_id)
|
|||
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
|
||||
sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +571,7 @@ void GameEvent::GameEventSpawn(int16 event_id)
|
|||
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
|
||||
sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -570,13 +581,13 @@ void GameEvent::GameEventSpawn(int16 event_id)
|
|||
}
|
||||
}
|
||||
|
||||
void GameEvent::GameEventUnspawn(int16 event_id)
|
||||
void GameEventMgr::GameEventUnspawn(int16 event_id)
|
||||
{
|
||||
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
||||
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventCreatureGuids.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
|
||||
sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %u)",internal_event_id,mGameEventCreatureGuids.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +608,7 @@ void GameEvent::GameEventUnspawn(int16 event_id)
|
|||
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventGameobjectGuids.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
|
||||
sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %u)",internal_event_id,mGameEventGameobjectGuids.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -614,7 +625,7 @@ void GameEvent::GameEventUnspawn(int16 event_id)
|
|||
}
|
||||
if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size())
|
||||
{
|
||||
sLog.outError("GameEvent::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
|
||||
sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: %u)",internal_event_id,mGameEventPoolIds.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -624,7 +635,7 @@ void GameEvent::GameEventUnspawn(int16 event_id)
|
|||
}
|
||||
}
|
||||
|
||||
void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate)
|
||||
void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
|
||||
{
|
||||
for(ModelEquipList::iterator itr = mGameEventModelEquip[event_id].begin();itr != mGameEventModelEquip[event_id].end();++itr)
|
||||
{
|
||||
|
|
@ -703,7 +714,7 @@ void GameEvent::ChangeEquipOrModel(int16 event_id, bool activate)
|
|||
}
|
||||
}
|
||||
|
||||
void GameEvent::UpdateEventQuests(uint16 event_id, bool Activate)
|
||||
void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate)
|
||||
{
|
||||
QuestRelList::iterator itr;
|
||||
for (itr = mGameEventQuests[event_id].begin();itr != mGameEventQuests[event_id].end();++itr)
|
||||
|
|
@ -729,7 +740,19 @@ void GameEvent::UpdateEventQuests(uint16 event_id, bool Activate)
|
|||
}
|
||||
}
|
||||
|
||||
GameEvent::GameEvent()
|
||||
GameEventMgr::GameEventMgr()
|
||||
{
|
||||
isSystemInit = false;
|
||||
}
|
||||
|
||||
MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id )
|
||||
{
|
||||
GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
|
||||
GameEventMgr::ActiveEvents const& ae = gameeventmgr.GetActiveEventList();
|
||||
|
||||
for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr)
|
||||
if(events[id].holiday_id==id)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -16,15 +16,18 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOS_GAMEEVENT_H
|
||||
#define MANGOS_GAMEEVENT_H
|
||||
#ifndef MANGOS_GAMEEVENT_MGR_H
|
||||
#define MANGOS_GAMEEVENT_MGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Platform/Define.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
#define max_ge_check_delay 86400 // 1 day in seconds
|
||||
|
||||
class Creature;
|
||||
class GameObject;
|
||||
|
||||
struct GameEventData
|
||||
{
|
||||
GameEventData() : start(1),end(0),occurence(0),length(0) {}
|
||||
|
|
@ -32,6 +35,7 @@ struct GameEventData
|
|||
time_t end;
|
||||
uint32 occurence;
|
||||
uint32 length;
|
||||
uint32 holiday_id;
|
||||
std::string description;
|
||||
|
||||
bool isValid() const { return length > 0; }
|
||||
|
|
@ -45,11 +49,11 @@ struct ModelEquip
|
|||
uint32 equipement_id_prev;
|
||||
};
|
||||
|
||||
class GameEvent
|
||||
class GameEventMgr
|
||||
{
|
||||
public:
|
||||
GameEvent();
|
||||
~GameEvent() {};
|
||||
GameEventMgr();
|
||||
~GameEventMgr() {};
|
||||
typedef std::set<uint16> ActiveEvents;
|
||||
typedef std::vector<GameEventData> GameEventDataMap;
|
||||
ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; }
|
||||
|
|
@ -92,5 +96,8 @@ class GameEvent
|
|||
bool isSystemInit;
|
||||
};
|
||||
|
||||
#define gameeventmgr MaNGOS::Singleton<GameEvent>::Instance()
|
||||
#define gameeventmgr MaNGOS::Singleton<GameEventMgr>::Instance()
|
||||
|
||||
MANGOS_DLL_SPEC bool IsHolidayActive(HolidayIds id);
|
||||
|
||||
#endif
|
||||
|
|
@ -26,10 +26,8 @@
|
|||
#include "UpdateMask.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "MapManager.h"
|
||||
#include "LootMgr.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
|
@ -472,14 +470,15 @@ void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
|
|||
{
|
||||
fishloot->clear();
|
||||
|
||||
uint32 subzone = GetAreaId();
|
||||
uint32 zone, subzone;
|
||||
GetZoneAndAreaId(zone,subzone);
|
||||
|
||||
// if subzone loot exist use it
|
||||
if(LootTemplates_Fishing.HaveLootFor(subzone))
|
||||
fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
|
||||
// else use zone loot
|
||||
else
|
||||
fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, loot_owner,true);
|
||||
fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true);
|
||||
}
|
||||
|
||||
void GameObject::SaveToDB()
|
||||
|
|
@ -1000,11 +999,12 @@ void GameObject::Use(Unit* user)
|
|||
// 2) if skill == base_zone_skill => 5% chance
|
||||
// 3) chance is linear dependence from (base_zone_skill-skill)
|
||||
|
||||
uint32 subzone = GetAreaId();
|
||||
uint32 zone, subzone;
|
||||
GetZoneAndAreaId(zone,subzone);
|
||||
|
||||
int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone );
|
||||
if(!zone_skill)
|
||||
zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() );
|
||||
zone_skill = objmgr.GetFishingBaseSkillLevel( zone );
|
||||
|
||||
//provide error, no fishable zone or area should be 0
|
||||
if(!zone_skill)
|
||||
|
|
@ -1174,7 +1174,7 @@ void GameObject::Use(Unit* user)
|
|||
|
||||
Player* player = (Player*)user;
|
||||
|
||||
if( player->isAllowUseBattleGroundObject() )
|
||||
if( player->CanUseBattleGroundObject() )
|
||||
{
|
||||
// in battleground check
|
||||
BattleGround *bg = player->GetBattleGround();
|
||||
|
|
@ -1199,7 +1199,7 @@ void GameObject::Use(Unit* user)
|
|||
|
||||
Player* player = (Player*)user;
|
||||
|
||||
if( player->isAllowUseBattleGroundObject() )
|
||||
if( player->CanUseBattleGroundObject() )
|
||||
{
|
||||
// in battleground check
|
||||
BattleGround *bg = player->GetBattleGround();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "UpdateData.h"
|
||||
#include "Item.h"
|
||||
#include "Map.h"
|
||||
#include "MapManager.h"
|
||||
#include "Transports.h"
|
||||
#include "ObjectAccessor.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -862,6 +862,27 @@ namespace MaNGOS
|
|||
std::vector<WorldPacket*> i_data_cache; // 0 = default, i => i-1 locale index
|
||||
};
|
||||
|
||||
// Prepare using Builder localized packets with caching and send to player
|
||||
template<class Builder>
|
||||
class LocalizedPacketListDo
|
||||
{
|
||||
public:
|
||||
typedef std::vector<WorldPacket*> WorldPacketList;
|
||||
explicit LocalizedPacketListDo(Builder& builder) : i_builder(builder) {}
|
||||
|
||||
~LocalizedPacketListDo()
|
||||
{
|
||||
for(size_t i = 0; i < i_data_cache.size(); ++i)
|
||||
for(int j = 0; j < i_data_cache[i].size(); ++j)
|
||||
delete i_data_cache[i][j];
|
||||
}
|
||||
void operator()( Player* p );
|
||||
|
||||
private:
|
||||
Builder& i_builder;
|
||||
std::vector<WorldPacketList> i_data_cache;
|
||||
// 0 = default, i => i-1 locale index
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
template<> void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
|
||||
|
|
|
|||
|
|
@ -562,4 +562,28 @@ void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
|
|||
p->SendDirectMessage(data);
|
||||
}
|
||||
|
||||
template<class Builder>
|
||||
void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p )
|
||||
{
|
||||
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
|
||||
uint32 cache_idx = loc_idx+1;
|
||||
WorldPacketList* data_list;
|
||||
|
||||
// create if not cached yet
|
||||
if(i_data_cache.size() < cache_idx+1 || i_data_cache[cache_idx].empty())
|
||||
{
|
||||
if(i_data_cache.size() < cache_idx+1)
|
||||
i_data_cache.resize(cache_idx+1);
|
||||
|
||||
data_list = &i_data_cache[cache_idx];
|
||||
|
||||
i_builder(*data_list,loc_idx);
|
||||
}
|
||||
else
|
||||
data_list = &i_data_cache[cache_idx];
|
||||
|
||||
for(size_t i = 0; i < data_list->size(); ++i)
|
||||
p->SendDirectMessage((*data_list)[i]);
|
||||
}
|
||||
|
||||
#endif // MANGOS_GRIDNOTIFIERSIMPL_H
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "GridStates.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "GameSystem/Grid.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Group.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "MapManager.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
|
@ -215,26 +213,16 @@ void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
|
|||
Group *group = GetPlayer()->GetGroupInvite();
|
||||
if (!group) return;
|
||||
|
||||
// remember leader if online
|
||||
Player *leader = objmgr.GetPlayer(group->GetLeaderGUID());
|
||||
|
||||
/** error handling **/
|
||||
// uninvite, group can be deleted
|
||||
GetPlayer()->UninviteFromGroup();
|
||||
|
||||
if(!leader || !leader->GetSession())
|
||||
return;
|
||||
/********************/
|
||||
|
||||
// everything's fine, do it
|
||||
if(!group->IsCreated())
|
||||
{
|
||||
// note: this means that if you invite more than one person
|
||||
// and one of them declines before the first one accepts
|
||||
// all invites will be cleared
|
||||
// fixme: is that ok ?
|
||||
group->RemoveAllInvites();
|
||||
delete group;
|
||||
}
|
||||
|
||||
GetPlayer()->SetGroupInvite(NULL);
|
||||
|
||||
// report
|
||||
WorldPacket data( SMSG_GROUP_DECLINE, 10 ); // guess size
|
||||
data << GetPlayer()->GetName();
|
||||
leader->GetSession()->SendPacket( &data );
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "Database/DatabaseEnv.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "MapManager.h"
|
||||
#include "Player.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
|
@ -27,6 +26,7 @@
|
|||
#include "Chat.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Util.h"
|
||||
#include "Language.h"
|
||||
|
||||
Guild::Guild()
|
||||
{
|
||||
|
|
@ -50,27 +50,25 @@ Guild::~Guild()
|
|||
|
||||
}
|
||||
|
||||
bool Guild::create(uint64 lGuid, std::string gname)
|
||||
bool Guild::create(Player* leader, std::string gname)
|
||||
{
|
||||
std::string rname;
|
||||
std::string lName;
|
||||
|
||||
if(!objmgr.GetPlayerNameByGUID(lGuid, lName))
|
||||
return false;
|
||||
if(objmgr.GetGuildByName(gname))
|
||||
return false;
|
||||
|
||||
sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(lGuid));
|
||||
WorldSession* lSession = leader->GetSession();
|
||||
if(!lSession)
|
||||
return false;
|
||||
|
||||
leaderGuid = lGuid;
|
||||
leaderGuid = leader->GetGUID();
|
||||
name = gname;
|
||||
GINFO = "";
|
||||
MOTD = "No message set.";
|
||||
guildbank_money = 0;
|
||||
purchased_tabs = 0;
|
||||
|
||||
Id = objmgr.GenerateGuildId();
|
||||
|
||||
sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(leaderGuid));
|
||||
|
||||
// gname already assigned to Guild::name, use it to encode string for DB
|
||||
CharacterDatabase.escape_string(gname);
|
||||
|
||||
|
|
@ -88,18 +86,13 @@ bool Guild::create(uint64 lGuid, std::string gname)
|
|||
Id, gname.c_str(), GUID_LOPART(leaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, guildbank_money);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
rname = "Guild Master";
|
||||
CreateRank(rname,GR_RIGHT_ALL);
|
||||
rname = "Officer";
|
||||
CreateRank(rname,GR_RIGHT_ALL);
|
||||
rname = "Veteran";
|
||||
CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
rname = "Member";
|
||||
CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
rname = "Initiate";
|
||||
CreateRank(rname,GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
CreateRank(lSession->GetMangosString(LANG_GUILD_MASTER), GR_RIGHT_ALL);
|
||||
CreateRank(lSession->GetMangosString(LANG_GUILD_OFFICER), GR_RIGHT_ALL);
|
||||
CreateRank(lSession->GetMangosString(LANG_GUILD_VETERAN), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
CreateRank(lSession->GetMangosString(LANG_GUILD_MEMBER), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
CreateRank(lSession->GetMangosString(LANG_GUILD_INITIATE),GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||
|
||||
return AddMember(lGuid, (uint32)GR_GUILDMASTER);
|
||||
return AddMember(leaderGuid, (uint32)GR_GUILDMASTER);
|
||||
}
|
||||
|
||||
bool Guild::AddMember(uint64 plGuid, uint32 plRank)
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ class Guild
|
|||
Guild();
|
||||
~Guild();
|
||||
|
||||
bool create(uint64 lGuid, std::string gname);
|
||||
bool create(Player* leader, std::string gname);
|
||||
void Disband();
|
||||
|
||||
typedef std::map<uint32, MemberSlot> MemberList;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Guild.h"
|
||||
#include "MapManager.h"
|
||||
#include "GossipDef.h"
|
||||
#include "SocialMgr.h"
|
||||
|
||||
|
|
@ -63,7 +62,7 @@ void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
|
|||
return;
|
||||
|
||||
Guild *guild = new Guild;
|
||||
if(!guild->create(GetPlayer()->GetGUID(),gname))
|
||||
if(!guild->create(GetPlayer(),gname))
|
||||
{
|
||||
delete guild;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "Traveller.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#include "IdleMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "Unit.h"
|
||||
|
||||
IdleMovementGenerator si_idleMovement;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "Common.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
|
||||
#include "Player.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Log.h"
|
||||
#include "GridStates.h"
|
||||
#include "CellImpl.h"
|
||||
|
|
@ -34,7 +32,6 @@
|
|||
#include "GridNotifiersImpl.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Transports.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "Group.h"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
|
|
|||
|
|
@ -170,7 +170,8 @@ enum MangosStrings
|
|||
LANG_CONSOLE_COMMAND = 172,
|
||||
LANG_YOU_CHANGE_RUNIC_POWER = 173,
|
||||
LANG_YOURS_RUNIC_POWER_CHANGED = 174,
|
||||
// Room for more level 1 175-199 not used
|
||||
LANG_LIQUID_STATUS = 175,
|
||||
// Room for more level 1 176-199 not used
|
||||
|
||||
// level 2 chat
|
||||
LANG_NO_SELECTION = 200,
|
||||
|
|
@ -569,9 +570,11 @@ enum MangosStrings
|
|||
// Battleground
|
||||
LANG_BG_A_WINS = 600,
|
||||
LANG_BG_H_WINS = 601,
|
||||
LANG_BG_WS_ONE_MINUTE = 602,
|
||||
LANG_BG_WS_HALF_MINUTE = 603,
|
||||
LANG_BG_WS_BEGIN = 604,
|
||||
|
||||
LANG_BG_WS_START_TWO_MINUTES = 753,
|
||||
LANG_BG_WS_START_ONE_MINUTE = 602,
|
||||
LANG_BG_WS_START_HALF_MINUTE = 603,
|
||||
LANG_BG_WS_HAS_BEGUN = 604,
|
||||
|
||||
LANG_BG_WS_CAPTURED_HF = 605,
|
||||
LANG_BG_WS_CAPTURED_AF = 606,
|
||||
|
|
@ -585,9 +588,10 @@ enum MangosStrings
|
|||
LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED = 614,
|
||||
LANG_BG_WS_HORDE_FLAG_RESPAWNED = 615,
|
||||
|
||||
LANG_BG_EY_ONE_MINUTE = 636,
|
||||
LANG_BG_EY_HALF_MINUTE = 637,
|
||||
LANG_BG_EY_BEGIN = 638,
|
||||
LANG_BG_EY_START_TWO_MINUTES = 755,
|
||||
LANG_BG_EY_START_ONE_MINUTE = 636,
|
||||
LANG_BG_EY_START_HALF_MINUTE = 637,
|
||||
LANG_BG_EY_HAS_BEGUN = 638,
|
||||
|
||||
LANG_BG_AB_ALLY = 650,
|
||||
LANG_BG_AB_HORDE = 651,
|
||||
|
|
@ -600,9 +604,11 @@ enum MangosStrings
|
|||
LANG_BG_AB_NODE_DEFENDED = 658,
|
||||
LANG_BG_AB_NODE_ASSAULTED = 659,
|
||||
LANG_BG_AB_NODE_CLAIMED = 660,
|
||||
LANG_BG_AB_ONEMINTOSTART = 661,
|
||||
LANG_BG_AB_HALFMINTOSTART = 662,
|
||||
LANG_BG_AB_STARTED = 663,
|
||||
|
||||
LANG_BG_AB_START_TWO_MINUTES = 754,
|
||||
LANG_BG_AB_START_ONE_MINUTE = 661,
|
||||
LANG_BG_AB_START_HALF_MINUTE = 662,
|
||||
LANG_BG_AB_HAS_BEGUN = 663,
|
||||
LANG_BG_AB_A_NEAR_VICTORY = 664,
|
||||
LANG_BG_AB_H_NEAR_VICTORY = 665,
|
||||
LANG_BG_MARK_BY_MAIL = 666,
|
||||
|
|
@ -633,7 +639,7 @@ enum MangosStrings
|
|||
LANG_ARENA_ONE_MINUTE = 701,
|
||||
LANG_ARENA_THIRTY_SECONDS = 702,
|
||||
LANG_ARENA_FIFTEEN_SECONDS = 703,
|
||||
LANG_ARENA_BEGUN = 704,
|
||||
LANG_ARENA_HAS_BEGUN = 704,
|
||||
|
||||
LANG_WAIT_BEFORE_SPEAKING = 705,
|
||||
LANG_NOT_EQUIPPED_ITEM = 706,
|
||||
|
|
@ -658,7 +664,7 @@ enum MangosStrings
|
|||
LANG_ARENA_NOT_ENOUGH_PLAYERS = 723, // "Your group does not have enough players to join this match."
|
||||
LANG_ARENA_GOLD_WINS = 724, // "The Gold Team wins!"
|
||||
LANG_ARENA_GREEN_WINS = 725, // "The Green Team wins!"
|
||||
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 726, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
|
||||
// = 726, not used
|
||||
LANG_BG_GROUP_OFFLINE_MEMBER = 727, // "Your group has an offline member. Please remove him before joining."
|
||||
LANG_BG_GROUP_MIXED_FACTION = 728, // "Your group has players from the opposing faction. You can't join the battleground as a group."
|
||||
LANG_BG_GROUP_MIXED_LEVELS = 729, // "Your group has players from different battleground brakets. You can't join as group."
|
||||
|
|
@ -680,7 +686,16 @@ enum MangosStrings
|
|||
LANG_DIST_ARENA_POINTS_TEAM_START = 744,
|
||||
LANG_DIST_ARENA_POINTS_TEAM_END = 745,
|
||||
LANG_DIST_ARENA_POINTS_END = 746,
|
||||
// Room for batleground/arena strings 747-799 not used
|
||||
// = 747, not used
|
||||
// = 748, not used
|
||||
// = 749, not used
|
||||
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 750, // "Not enough players. This game will close in %u mins."
|
||||
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS = 751, // "Not enough players. This game will close in %u seconds."
|
||||
// = 752, not used
|
||||
// LANG_BG_WS_START_TWO_MINUTES = 753,
|
||||
// LANG_BG_AB_START_TWO_MINUTES = 754,
|
||||
// LANG_BG_EY_START_TWO_MINUTES = 755,
|
||||
// Room for batleground/arena strings 756-799 not used
|
||||
|
||||
// in game strings
|
||||
// = 800, not used
|
||||
|
|
@ -694,7 +709,12 @@ enum MangosStrings
|
|||
LANG_PLAYER_NOT_EXIST_OR_OFFLINE = 808,
|
||||
LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809,
|
||||
LANG_ACHIEVEMENT_EARNED = 810,
|
||||
// Room for in-game strings 811-999 not used
|
||||
LANG_GUILD_MASTER = 811,
|
||||
LANG_GUILD_OFFICER = 812,
|
||||
LANG_GUILD_VETERAN = 813,
|
||||
LANG_GUILD_MEMBER = 814,
|
||||
LANG_GUILD_INITIATE = 815,
|
||||
// Room for in-game strings 816-999 not used
|
||||
|
||||
// Level 4 (CLI only commands)
|
||||
LANG_COMMAND_EXIT = 1000,
|
||||
|
|
|
|||
|
|
@ -18,13 +18,10 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "World.h"
|
||||
#include "Player.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Chat.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Language.h"
|
||||
#include "AccountMgr.h"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "VMapFactory.h"
|
||||
#endif
|
||||
|
||||
//-----------------------Npc Commands-----------------------
|
||||
bool ChatHandler::HandleNpcSayCommand(const char* args)
|
||||
{
|
||||
if(!*args)
|
||||
|
|
@ -119,6 +120,7 @@ bool ChatHandler::HandleNpcWhisperCommand(const char* args)
|
|||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------
|
||||
|
||||
// global announce
|
||||
bool ChatHandler::HandleAnnounceCommand(const char* args)
|
||||
|
|
@ -282,8 +284,8 @@ bool ChatHandler::HandleGPSCommand(const char* args)
|
|||
CellPair cell_val = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
||||
Cell cell(cell_val);
|
||||
|
||||
uint32 zone_id = obj->GetZoneId();
|
||||
uint32 area_id = obj->GetAreaId();
|
||||
uint32 zone_id, area_id;
|
||||
obj->GetZoneAndAreaId(zone_id,area_id);
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId());
|
||||
AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id);
|
||||
|
|
@ -329,6 +331,12 @@ bool ChatHandler::HandleGPSCommand(const char* args)
|
|||
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
|
||||
zone_x, zone_y, ground_z, floor_z, have_map, have_vmap );
|
||||
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status);
|
||||
if (res)
|
||||
{
|
||||
PSendSysMessage(LANG_LIQUID_STATUS, liquid_status.level, liquid_status.depth_level, liquid_status.type, res);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
1610
src/game/Level2.cpp
1610
src/game/Level2.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -33,7 +33,6 @@
|
|||
#include "Guild.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "MapManager.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "ScriptCalls.h"
|
||||
#include "Language.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
|
@ -3066,7 +3065,7 @@ bool ChatHandler::HandleGuildCreateCommand(const char* args)
|
|||
}
|
||||
|
||||
Guild *guild = new Guild;
|
||||
if (!guild->create (player->GetGUID (),guildname))
|
||||
if (!guild->create (player,guildname))
|
||||
{
|
||||
delete guild;
|
||||
SendSysMessage (LANG_GUILD_NOT_CREATED);
|
||||
|
|
@ -3261,77 +3260,6 @@ bool ChatHandler::HandleGetDistanceCommand(const char* args)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIX-ME!!!
|
||||
|
||||
bool ChatHandler::HandleAddWeaponCommand(const char* /*args*/)
|
||||
{
|
||||
/*if (!*args)
|
||||
return false;
|
||||
|
||||
uint64 guid = m_session->GetPlayer()->GetSelection();
|
||||
if (guid == 0)
|
||||
{
|
||||
SendSysMessage(LANG_NO_SELECTION);
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
|
||||
|
||||
if(!pCreature)
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* pSlotID = strtok((char*)args, " ");
|
||||
if (!pSlotID)
|
||||
return false;
|
||||
|
||||
char* pItemID = strtok(NULL, " ");
|
||||
if (!pItemID)
|
||||
return false;
|
||||
|
||||
uint32 ItemID = atoi(pItemID);
|
||||
uint32 SlotID = atoi(pSlotID);
|
||||
|
||||
ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
|
||||
|
||||
bool added = false;
|
||||
if(tmpItem)
|
||||
{
|
||||
switch(SlotID)
|
||||
{
|
||||
case 1:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
case 2:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
case 3:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
default:
|
||||
PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
|
||||
added = false;
|
||||
break;
|
||||
}
|
||||
if(added)
|
||||
{
|
||||
PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleDieCommand(const char* /*args*/)
|
||||
{
|
||||
Unit* target = getSelectedUnit();
|
||||
|
|
@ -3592,7 +3520,7 @@ bool ChatHandler::HandleLinkGraveCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
if(objmgr.AddGraveYardLink(g_id,player->GetZoneId(),g_team))
|
||||
if(objmgr.AddGraveYardLink(g_id,zoneId,g_team))
|
||||
PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId);
|
||||
else
|
||||
PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId);
|
||||
|
|
@ -3616,6 +3544,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
|
|||
return false;
|
||||
|
||||
Player* player = m_session->GetPlayer();
|
||||
uint32 zone_id = player->GetZoneId();
|
||||
|
||||
WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard(
|
||||
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team);
|
||||
|
|
@ -3624,7 +3553,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
|
|||
{
|
||||
uint32 g_id = graveyard->ID;
|
||||
|
||||
GraveYardData const* data = objmgr.FindGraveYardData(g_id,player->GetZoneId());
|
||||
GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id);
|
||||
if (!data)
|
||||
{
|
||||
PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id);
|
||||
|
|
@ -3643,7 +3572,7 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
|
|||
else if(g_team == ALLIANCE)
|
||||
team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
|
||||
|
||||
PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),player->GetZoneId());
|
||||
PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3657,29 +3586,36 @@ bool ChatHandler::HandleNearGraveCommand(const char* args)
|
|||
team_name = GetMangosString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
|
||||
|
||||
if(g_team == ~uint32(0))
|
||||
PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, player->GetZoneId());
|
||||
PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
|
||||
else
|
||||
PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, player->GetZoneId(),team_name.c_str());
|
||||
PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//play npc emote
|
||||
bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
|
||||
//-----------------------Npc Commands-----------------------
|
||||
bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
|
||||
{
|
||||
uint32 emote = atoi((char*)args);
|
||||
if(!args)
|
||||
return false;
|
||||
|
||||
Creature* target = getSelectedCreature();
|
||||
if(!target)
|
||||
uint32 newEntryNum = atoi(args);
|
||||
if(!newEntryNum)
|
||||
return false;
|
||||
|
||||
Unit* unit = getSelectedUnit();
|
||||
if(!unit || unit->GetTypeId() != TYPEID_UNIT)
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
|
||||
|
||||
Creature* creature = (Creature*)unit;
|
||||
if(creature->UpdateEntry(newEntryNum))
|
||||
SendSysMessage(LANG_DONE);
|
||||
else
|
||||
SendSysMessage(LANG_ERROR);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3728,6 +3664,95 @@ bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
|
|||
return true;
|
||||
}
|
||||
|
||||
//play npc emote
|
||||
bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args)
|
||||
{
|
||||
uint32 emote = atoi((char*)args);
|
||||
|
||||
Creature* target = getSelectedCreature();
|
||||
if(!target)
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: NpcCommands that needs to be fixed :
|
||||
|
||||
bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/)
|
||||
{
|
||||
/*if (!*args)
|
||||
return false;
|
||||
|
||||
uint64 guid = m_session->GetPlayer()->GetSelection();
|
||||
if (guid == 0)
|
||||
{
|
||||
SendSysMessage(LANG_NO_SELECTION);
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
|
||||
|
||||
if(!pCreature)
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* pSlotID = strtok((char*)args, " ");
|
||||
if (!pSlotID)
|
||||
return false;
|
||||
|
||||
char* pItemID = strtok(NULL, " ");
|
||||
if (!pItemID)
|
||||
return false;
|
||||
|
||||
uint32 ItemID = atoi(pItemID);
|
||||
uint32 SlotID = atoi(pSlotID);
|
||||
|
||||
ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID);
|
||||
|
||||
bool added = false;
|
||||
if(tmpItem)
|
||||
{
|
||||
switch(SlotID)
|
||||
{
|
||||
case 1:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
case 2:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
case 3:
|
||||
pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
|
||||
added = true;
|
||||
break;
|
||||
default:
|
||||
PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID);
|
||||
added = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(added)
|
||||
PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID);
|
||||
}
|
||||
else
|
||||
{
|
||||
PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool ChatHandler::HandleExploreCheatCommand(const char* args)
|
||||
{
|
||||
if (!*args)
|
||||
|
|
@ -5686,30 +5711,6 @@ bool ChatHandler::HandleLoadPDumpCommand(const char *args)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleNpcChangeEntryCommand(const char *args)
|
||||
{
|
||||
if(!args)
|
||||
return false;
|
||||
|
||||
uint32 newEntryNum = atoi(args);
|
||||
if(!newEntryNum)
|
||||
return false;
|
||||
|
||||
Unit* unit = getSelectedUnit();
|
||||
if(!unit || unit->GetTypeId() != TYPEID_UNIT)
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
Creature* creature = (Creature*)unit;
|
||||
if(creature->UpdateEntry(newEntryNum))
|
||||
SendSysMessage(LANG_DONE);
|
||||
else
|
||||
SendSysMessage(LANG_ERROR);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleWritePDumpCommand(const char *args)
|
||||
{
|
||||
if(!args)
|
||||
|
|
|
|||
|
|
@ -114,11 +114,18 @@ void LootStore::LoadLootTable()
|
|||
float chanceOrQuestChance = fields[2].GetFloat();
|
||||
uint8 group = fields[3].GetUInt8();
|
||||
int32 mincountOrRef = fields[4].GetInt32();
|
||||
uint8 maxcount = fields[5].GetUInt8();
|
||||
uint32 maxcount = fields[5].GetUInt32();
|
||||
ConditionType condition = (ConditionType)fields[6].GetUInt8();
|
||||
uint32 cond_value1 = fields[7].GetUInt32();
|
||||
uint32 cond_value2 = fields[8].GetUInt32();
|
||||
|
||||
if(maxcount > std::numeric_limits<uint8>::max())
|
||||
{
|
||||
sLog.outErrorDb("Table '%s' entry %d item %d: maxcount value (%u) to large. must be less %u - skipped", GetName(), entry, item, maxcount,std::numeric_limits<uint8>::max());
|
||||
continue; // error already printed to log/console.
|
||||
}
|
||||
|
||||
|
||||
if(!PlayerCondition::IsValid(condition,cond_value1, cond_value2))
|
||||
{
|
||||
sLog.outErrorDb("... in table '%s' entry %u item %u", GetName(), entry, item);
|
||||
|
|
@ -248,6 +255,12 @@ bool LootStoreItem::Roll(bool rate) const
|
|||
// Checks correctness of values
|
||||
bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
|
||||
{
|
||||
if(group >= 1 << 7) // it stored in 7 bit field
|
||||
{
|
||||
sLog.outErrorDb("Table '%s' entry %d item %d: group (%u) must be less %u - skipped", store.GetName(), entry, itemid, group, 1 << 7);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mincountOrRef == 0)
|
||||
{
|
||||
sLog.outErrorDb("Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef);
|
||||
|
|
|
|||
|
|
@ -63,17 +63,17 @@ struct LootStoreItem
|
|||
uint32 itemid; // id of the item
|
||||
float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs
|
||||
int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative)
|
||||
uint8 group :8;
|
||||
uint8 group :7;
|
||||
bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
|
||||
uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative)
|
||||
uint16 conditionId :16; // additional loot condition Id
|
||||
bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB)
|
||||
|
||||
// Constructor, converting ChanceOrQuestChance -> (chance, needs_quest)
|
||||
// displayid is filled in IsValid() which must be called after
|
||||
LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount)
|
||||
: itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef),
|
||||
group(_group), maxcount(_maxcount), conditionId(_conditionId),
|
||||
needs_quest(_chanceOrQuestChance < 0) {}
|
||||
group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId)
|
||||
{}
|
||||
|
||||
bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
|
||||
bool IsValid(LootStore const& store, uint32 entry) const;
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ libmangosgame_a_SOURCES = \
|
|||
FleeingMovementGenerator.cpp \
|
||||
FleeingMovementGenerator.h \
|
||||
Formulas.h \
|
||||
GameEvent.cpp \
|
||||
GameEvent.h \
|
||||
GameEventMgr.cpp \
|
||||
GameEventMgr.h \
|
||||
GameObject.cpp \
|
||||
GameObject.h \
|
||||
GlobalEvents.cpp \
|
||||
|
|
|
|||
745
src/game/Map.cpp
745
src/game/Map.cpp
|
|
@ -19,7 +19,6 @@
|
|||
#include "MapManager.h"
|
||||
#include "Player.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Log.h"
|
||||
#include "GridStates.h"
|
||||
#include "CellImpl.h"
|
||||
|
|
@ -42,9 +41,6 @@
|
|||
#define DEFAULT_GRID_EXPIRY 300
|
||||
#define MAX_GRID_LOAD_TIME 50
|
||||
|
||||
// magic *.map header
|
||||
const char MAP_MAGIC[] = "MAP_3.00";
|
||||
|
||||
GridState* si_GridStates[MAX_GRID_STATE];
|
||||
|
||||
Map::~Map()
|
||||
|
|
@ -67,9 +63,9 @@ bool Map::ExistMap(uint32 mapid,int x,int y)
|
|||
return false;
|
||||
}
|
||||
|
||||
char magic[8];
|
||||
fread(magic,1,8,pf);
|
||||
if(strncmp(MAP_MAGIC,magic,8))
|
||||
map_fileheader header;
|
||||
fread(&header, sizeof(header), 1, pf);
|
||||
if (header.mapMagic != MAP_MAGIC || header.versionMagic != MAP_VERSION_MAGIC)
|
||||
{
|
||||
sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp);
|
||||
delete [] tmp;
|
||||
|
|
@ -79,7 +75,6 @@ bool Map::ExistMap(uint32 mapid,int x,int y)
|
|||
|
||||
delete [] tmp;
|
||||
fclose(pf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -158,29 +153,13 @@ void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y)
|
|||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y);
|
||||
sLog.outDetail("Loading map %s",tmp);
|
||||
// loading data
|
||||
FILE *pf=fopen(tmp,"rb");
|
||||
if(!pf)
|
||||
GridMaps[x][y] = new GridMap();
|
||||
if (!GridMaps[x][y]->loadData(tmp))
|
||||
{
|
||||
delete [] tmp;
|
||||
return;
|
||||
sLog.outError("Error load map file: \n %s\n", tmp);
|
||||
}
|
||||
|
||||
char magic[8];
|
||||
fread(magic,1,8,pf);
|
||||
if(strncmp(MAP_MAGIC,magic,8))
|
||||
{
|
||||
sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp);
|
||||
delete [] tmp;
|
||||
fclose(pf); //close file before return
|
||||
return;
|
||||
}
|
||||
delete [] tmp;
|
||||
|
||||
GridMap * buf= new GridMap;
|
||||
fread(buf,1,sizeof(GridMap),pf);
|
||||
fclose(pf);
|
||||
|
||||
GridMaps[x][y] = buf;
|
||||
delete [] tmp;
|
||||
return;
|
||||
}
|
||||
|
||||
void Map::LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x,int y)
|
||||
|
|
@ -1032,7 +1011,11 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
|||
{
|
||||
if (i_InstanceId == 0)
|
||||
{
|
||||
if(GridMaps[gx][gy]) delete (GridMaps[gx][gy]);
|
||||
if(GridMaps[gx][gy])
|
||||
{
|
||||
GridMaps[gx][gy]->unloadData();
|
||||
delete GridMaps[gx][gy];
|
||||
}
|
||||
// x and y are swapped
|
||||
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx);
|
||||
}
|
||||
|
|
@ -1057,94 +1040,527 @@ void Map::UnloadAll(bool pForce)
|
|||
}
|
||||
}
|
||||
|
||||
float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
|
||||
//*****************************
|
||||
// Grid function
|
||||
//*****************************
|
||||
GridMap::GridMap()
|
||||
{
|
||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||
m_flags = 0;
|
||||
// Area data
|
||||
m_gridArea = 0;
|
||||
m_area_map = NULL;
|
||||
// Height level data
|
||||
m_gridHeight = INVALID_HEIGHT;
|
||||
m_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
// Liquid data
|
||||
m_liquidType = 0;
|
||||
m_liquid_offX = 0;
|
||||
m_liquid_offY = 0;
|
||||
m_liquid_width = 0;
|
||||
m_liquid_height = 0;
|
||||
m_liquidLevel = INVALID_HEIGHT;
|
||||
m_liquid_type = NULL;
|
||||
m_liquid_map = NULL;
|
||||
}
|
||||
|
||||
GridMap::~GridMap()
|
||||
{
|
||||
unloadData();
|
||||
}
|
||||
|
||||
bool GridMap::loadData(char *filename)
|
||||
{
|
||||
// Unload old data if exist
|
||||
unloadData();
|
||||
|
||||
map_fileheader header;
|
||||
// Not return error if file not found
|
||||
FILE *in = fopen(filename, "rb");
|
||||
if (!in)
|
||||
return true;
|
||||
fread(&header, sizeof(header),1,in);
|
||||
if (header.mapMagic == MAP_MAGIC && header.versionMagic == MAP_VERSION_MAGIC)
|
||||
{
|
||||
// loadup area data
|
||||
if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize))
|
||||
{
|
||||
sLog.outError("Error loading map area data\n");
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
// loadup height data
|
||||
if (header.heightMapOffset && !loadHeihgtData(in, header.heightMapOffset, header.heightMapSize))
|
||||
{
|
||||
sLog.outError("Error loading map height data\n");
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
// loadup liquid data
|
||||
if (header.liquidMapOffset && !loadLiquidData(in, header.liquidMapOffset, header.liquidMapSize))
|
||||
{
|
||||
sLog.outError("Error loading map liquids data\n");
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
fclose(in);
|
||||
return true;
|
||||
}
|
||||
sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.", filename);
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
|
||||
void GridMap::unloadData()
|
||||
{
|
||||
if (m_area_map) delete[] m_area_map;
|
||||
if (m_V9) delete[] m_V9;
|
||||
if (m_V8) delete[] m_V8;
|
||||
if (m_liquid_type) delete[] m_liquid_type;
|
||||
if (m_liquid_map) delete[] m_liquid_map;
|
||||
m_area_map = NULL;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
m_liquid_type = NULL;
|
||||
m_liquid_map = NULL;
|
||||
m_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
}
|
||||
|
||||
bool GridMap::loadAreaData(FILE *in, uint32 offset, uint32 size)
|
||||
{
|
||||
map_areaHeader header;
|
||||
fseek(in, offset, SEEK_SET);
|
||||
fread(&header, sizeof(header), 1, in);
|
||||
if (header.fourcc != MAP_AREA_MAGIC)
|
||||
return false;
|
||||
|
||||
m_gridArea = header.gridArea;
|
||||
if (!(header.flags&MAP_AREA_NO_AREA))
|
||||
{
|
||||
m_area_map = new uint16 [16*16];
|
||||
fread(m_area_map, sizeof(uint16), 16*16, in);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GridMap::loadHeihgtData(FILE *in, uint32 offset, uint32 size)
|
||||
{
|
||||
map_heightHeader header;
|
||||
fseek(in, offset, SEEK_SET);
|
||||
fread(&header, sizeof(header), 1, in);
|
||||
if (header.fourcc != MAP_HEIGTH_MAGIC)
|
||||
return false;
|
||||
|
||||
m_gridHeight = header.gridHeight;
|
||||
if (!(header.flags&MAP_HEIGHT_NO_HIGHT))
|
||||
{
|
||||
if ((header.flags&MAP_HEIGHT_AS_INT16))
|
||||
{
|
||||
m_uint16_V9 = new uint16 [129*129];
|
||||
m_uint16_V8 = new uint16 [128*128];
|
||||
fread(m_uint16_V9, sizeof(uint16), 129*129, in);
|
||||
fread(m_uint16_V8, sizeof(uint16), 128*128, in);
|
||||
m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 65535;
|
||||
m_gridGetHeight = &GridMap::getHeightFromUint16;
|
||||
}
|
||||
else if ((header.flags&MAP_HEIGHT_AS_INT8))
|
||||
{
|
||||
m_uint8_V9 = new uint8 [129*129];
|
||||
m_uint8_V8 = new uint8 [128*128];
|
||||
fread(m_uint8_V9, sizeof(uint8), 129*129, in);
|
||||
fread(m_uint8_V8, sizeof(uint8), 128*128, in);
|
||||
m_gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 255;
|
||||
m_gridGetHeight = &GridMap::getHeightFromUint8;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_V9 = new float [129*129];
|
||||
m_V8 = new float [128*128];
|
||||
fread(m_V9, sizeof(float), 129*129, in);
|
||||
fread(m_V8, sizeof(float), 128*128, in);
|
||||
m_gridGetHeight = &GridMap::getHeightFromFloat;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GridMap::loadLiquidData(FILE *in, uint32 offset, uint32 size)
|
||||
{
|
||||
map_liquidHeader header;
|
||||
fseek(in, offset, SEEK_SET);
|
||||
fread(&header, sizeof(header), 1, in);
|
||||
if (header.fourcc != MAP_LIQUID_MAGIC)
|
||||
return false;
|
||||
|
||||
m_liquidType = header.liquidType;
|
||||
m_liquid_offX = header.offsetX;
|
||||
m_liquid_offY = header.offsetY;
|
||||
m_liquid_width = header.width;
|
||||
m_liquid_height= header.height;
|
||||
m_liquidLevel = header.liquidLevel;
|
||||
|
||||
if (!(header.flags&MAP_LIQUID_NO_TYPE))
|
||||
{
|
||||
m_liquid_type = new uint8 [16*16];
|
||||
fread(m_liquid_type, sizeof(uint8), 16*16, in);
|
||||
}
|
||||
if (!(header.flags&MAP_LIQUID_NO_HIGHT))
|
||||
{
|
||||
m_liquid_map = new float [m_liquid_width*m_liquid_height];
|
||||
fread(m_liquid_map, sizeof(float), m_liquid_width*m_liquid_height, in);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16 GridMap::getArea(float x, float y)
|
||||
{
|
||||
if (!m_area_map)
|
||||
return m_gridArea;
|
||||
|
||||
x = 16 * (32 - x/SIZE_OF_GRIDS);
|
||||
y = 16 * (32 - y/SIZE_OF_GRIDS);
|
||||
int lx = (int)x & 15;
|
||||
int ly = (int)y & 15;
|
||||
return m_area_map[lx*16 + ly];
|
||||
}
|
||||
|
||||
float GridMap::getHeightFromFlat(float x, float y) const
|
||||
{
|
||||
return m_gridHeight;
|
||||
}
|
||||
|
||||
float GridMap::getHeightFromFloat(float x, float y) const
|
||||
{
|
||||
if (!m_V8 || !m_V9)
|
||||
return m_gridHeight;
|
||||
|
||||
x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
|
||||
y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
|
||||
|
||||
int x_int = (int)x;
|
||||
int y_int = (int)y;
|
||||
x -= x_int;
|
||||
y -= y_int;
|
||||
x_int&=(MAP_RESOLUTION - 1);
|
||||
y_int&=(MAP_RESOLUTION - 1);
|
||||
|
||||
// Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
|
||||
// +--------------> X
|
||||
// | h1-------h2 Coordinates is:
|
||||
// | | \ 1 / | h1 0,0
|
||||
// | | \ / | h2 0,1
|
||||
// | | 2 h5 3 | h3 1,0
|
||||
// | | / \ | h4 1,1
|
||||
// | | / 4 \ | h5 1/2,1/2
|
||||
// | h3-------h4
|
||||
// V Y
|
||||
// For find height need
|
||||
// 1 - detect triangle
|
||||
// 2 - solve linear equation from triangle points
|
||||
// Calculate coefficients for solve h = a*x + b*y + c
|
||||
|
||||
float a,b,c;
|
||||
// Select triangle:
|
||||
if (x+y < 1)
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 1 triangle (h1, h2, h5 points)
|
||||
float h1 = m_V9[(x_int )*129 + y_int];
|
||||
float h2 = m_V9[(x_int+1)*129 + y_int];
|
||||
float h5 = 2 * m_V8[x_int*128 + y_int];
|
||||
a = h2-h1;
|
||||
b = h5-h1-h2;
|
||||
c = h1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 triangle (h1, h3, h5 points)
|
||||
float h1 = m_V9[x_int*129 + y_int ];
|
||||
float h3 = m_V9[x_int*129 + y_int+1];
|
||||
float h5 = 2 * m_V8[x_int*128 + y_int];
|
||||
a = h5 - h1 - h3;
|
||||
b = h3 - h1;
|
||||
c = h1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 3 triangle (h2, h4, h5 points)
|
||||
float h2 = m_V9[(x_int+1)*129 + y_int ];
|
||||
float h4 = m_V9[(x_int+1)*129 + y_int+1];
|
||||
float h5 = 2 * m_V8[x_int*128 + y_int];
|
||||
a = h2 + h4 - h5;
|
||||
b = h4 - h2;
|
||||
c = h5 - h4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4 triangle (h3, h4, h5 points)
|
||||
float h3 = m_V9[(x_int )*129 + y_int+1];
|
||||
float h4 = m_V9[(x_int+1)*129 + y_int+1];
|
||||
float h5 = 2 * m_V8[x_int*128 + y_int];
|
||||
a = h4 - h3;
|
||||
b = h3 + h4 - h5;
|
||||
c = h5 - h4;
|
||||
}
|
||||
}
|
||||
// Calculate height
|
||||
return a * x + b * y + c;
|
||||
}
|
||||
|
||||
float GridMap::getHeightFromUint8(float x, float y) const
|
||||
{
|
||||
if (!m_uint8_V8 || !m_uint8_V9)
|
||||
return m_gridHeight;
|
||||
|
||||
x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
|
||||
y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
|
||||
|
||||
int x_int = (int)x;
|
||||
int y_int = (int)y;
|
||||
x -= x_int;
|
||||
y -= y_int;
|
||||
x_int&=(MAP_RESOLUTION - 1);
|
||||
y_int&=(MAP_RESOLUTION - 1);
|
||||
|
||||
int32 a, b, c;
|
||||
uint8 *V9_h1_ptr = &m_uint8_V9[x_int*128 + x_int + y_int];
|
||||
if (x+y < 1)
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 1 triangle (h1, h2, h5 points)
|
||||
int32 h1 = V9_h1_ptr[ 0];
|
||||
int32 h2 = V9_h1_ptr[129];
|
||||
int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
|
||||
a = h2-h1;
|
||||
b = h5-h1-h2;
|
||||
c = h1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 triangle (h1, h3, h5 points)
|
||||
int32 h1 = V9_h1_ptr[0];
|
||||
int32 h3 = V9_h1_ptr[1];
|
||||
int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
|
||||
a = h5 - h1 - h3;
|
||||
b = h3 - h1;
|
||||
c = h1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 3 triangle (h2, h4, h5 points)
|
||||
int32 h2 = V9_h1_ptr[129];
|
||||
int32 h4 = V9_h1_ptr[130];
|
||||
int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
|
||||
a = h2 + h4 - h5;
|
||||
b = h4 - h2;
|
||||
c = h5 - h4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4 triangle (h3, h4, h5 points)
|
||||
int32 h3 = V9_h1_ptr[ 1];
|
||||
int32 h4 = V9_h1_ptr[130];
|
||||
int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
|
||||
a = h4 - h3;
|
||||
b = h3 + h4 - h5;
|
||||
c = h5 - h4;
|
||||
}
|
||||
}
|
||||
// Calculate height
|
||||
return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
|
||||
}
|
||||
|
||||
float GridMap::getHeightFromUint16(float x, float y) const
|
||||
{
|
||||
if (!m_uint16_V8 || !m_uint16_V9)
|
||||
return m_gridHeight;
|
||||
|
||||
x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
|
||||
y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
|
||||
|
||||
int x_int = (int)x;
|
||||
int y_int = (int)y;
|
||||
x -= x_int;
|
||||
y -= y_int;
|
||||
x_int&=(MAP_RESOLUTION - 1);
|
||||
y_int&=(MAP_RESOLUTION - 1);
|
||||
|
||||
int32 a, b, c;
|
||||
uint16 *V9_h1_ptr = &m_uint16_V9[x_int*128 + x_int + y_int];
|
||||
if (x+y < 1)
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 1 triangle (h1, h2, h5 points)
|
||||
int32 h1 = V9_h1_ptr[ 0];
|
||||
int32 h2 = V9_h1_ptr[129];
|
||||
int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
|
||||
a = h2-h1;
|
||||
b = h5-h1-h2;
|
||||
c = h1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 triangle (h1, h3, h5 points)
|
||||
int32 h1 = V9_h1_ptr[0];
|
||||
int32 h3 = V9_h1_ptr[1];
|
||||
int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
|
||||
a = h5 - h1 - h3;
|
||||
b = h3 - h1;
|
||||
c = h1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
// 3 triangle (h2, h4, h5 points)
|
||||
int32 h2 = V9_h1_ptr[129];
|
||||
int32 h4 = V9_h1_ptr[130];
|
||||
int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
|
||||
a = h2 + h4 - h5;
|
||||
b = h4 - h2;
|
||||
c = h5 - h4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4 triangle (h3, h4, h5 points)
|
||||
int32 h3 = V9_h1_ptr[ 1];
|
||||
int32 h4 = V9_h1_ptr[130];
|
||||
int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
|
||||
a = h4 - h3;
|
||||
b = h3 + h4 - h5;
|
||||
c = h5 - h4;
|
||||
}
|
||||
}
|
||||
// Calculate height
|
||||
return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
|
||||
}
|
||||
|
||||
float GridMap::getLiquidLevel(float x, float y)
|
||||
{
|
||||
if (!m_liquid_map)
|
||||
return m_liquidLevel;
|
||||
|
||||
x = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
|
||||
y = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
|
||||
|
||||
int cx_int = ((int)x & (MAP_RESOLUTION-1)) - m_liquid_offY;
|
||||
int cy_int = ((int)y & (MAP_RESOLUTION-1)) - m_liquid_offX;
|
||||
|
||||
if (cx_int < 0 || cx_int >=m_liquid_height)
|
||||
return INVALID_HEIGHT;
|
||||
if (cy_int < 0 || cy_int >=m_liquid_width )
|
||||
return INVALID_HEIGHT;
|
||||
|
||||
return m_liquid_map[cx_int*m_liquid_width + cy_int];
|
||||
}
|
||||
|
||||
uint8 GridMap::getTerrainType(float x, float y)
|
||||
{
|
||||
if (!m_liquid_type)
|
||||
return m_liquidType;
|
||||
|
||||
x = 16 * (32 - x/SIZE_OF_GRIDS);
|
||||
y = 16 * (32 - y/SIZE_OF_GRIDS);
|
||||
int lx = (int)x & 15;
|
||||
int ly = (int)y & 15;
|
||||
return m_liquid_type[lx*16 + ly];
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data)
|
||||
{
|
||||
// Check water type (if no water return)
|
||||
if (!m_liquid_type && !m_liquidType)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Get cell
|
||||
float cx = MAP_RESOLUTION * (32 - x/SIZE_OF_GRIDS);
|
||||
float cy = MAP_RESOLUTION * (32 - y/SIZE_OF_GRIDS);
|
||||
|
||||
int x_int = (int)cx & (MAP_RESOLUTION-1);
|
||||
int y_int = (int)cy & (MAP_RESOLUTION-1);
|
||||
|
||||
// Check water type in cell
|
||||
uint8 type = m_liquid_type ? m_liquid_type[(x_int>>3)*16 + (y_int>>3)] : m_liquidType;
|
||||
if (type == 0)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Check req liquid type mask
|
||||
if (ReqLiquidType && !(ReqLiquidType&type))
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Check water level:
|
||||
// Check water height map
|
||||
int lx_int = x_int - m_liquid_offY;
|
||||
int ly_int = y_int - m_liquid_offX;
|
||||
if (lx_int < 0 || lx_int >=m_liquid_height)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
if (ly_int < 0 || ly_int >=m_liquid_width )
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// Get water level
|
||||
float liquid_level = m_liquid_map ? m_liquid_map[lx_int*m_liquid_width + ly_int] : m_liquidLevel;
|
||||
// Get ground level (sub 0.2 for fix some errors)
|
||||
float ground_level = getHeight(x, y);
|
||||
|
||||
// Check water level and ground level
|
||||
if (liquid_level < ground_level || z < ground_level - 2)
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
|
||||
// All ok in water -> store data
|
||||
if (data)
|
||||
{
|
||||
data->type = type;
|
||||
data->level = liquid_level;
|
||||
data->depth_level = ground_level;
|
||||
}
|
||||
|
||||
// For speed check as int values
|
||||
int delta = (liquid_level - z) * 10;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 20) // Under water
|
||||
return LIQUID_MAP_UNDER_WATER;
|
||||
if (delta > 0 ) // In water
|
||||
return LIQUID_MAP_IN_WATER;
|
||||
if (delta > -1) // Walk on water
|
||||
return LIQUID_MAP_WATER_WALK;
|
||||
// Above water
|
||||
return LIQUID_MAP_ABOVE_WATER;
|
||||
}
|
||||
|
||||
inline GridMap *Map::GetGrid(float x, float y)
|
||||
{
|
||||
// half opt method
|
||||
int gx=(int)(32-x/SIZE_OF_GRIDS); //grid x
|
||||
int gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
|
||||
|
||||
float lx=MAP_RESOLUTION*(32 -x/SIZE_OF_GRIDS - gx);
|
||||
float ly=MAP_RESOLUTION*(32 -y/SIZE_OF_GRIDS - gy);
|
||||
|
||||
// ensure GridMap is loaded
|
||||
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
|
||||
return GridMaps[gx][gy];
|
||||
}
|
||||
|
||||
float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
|
||||
{
|
||||
// find raw .map surface under Z coordinates
|
||||
float mapHeight;
|
||||
if(GridMap* gmap = GridMaps[gx][gy])
|
||||
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
{
|
||||
int lx_int = (int)lx;
|
||||
int ly_int = (int)ly;
|
||||
lx -= lx_int;
|
||||
ly -= ly_int;
|
||||
|
||||
// Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
|
||||
// +--------------> X
|
||||
// | h1-------h2 Coordinates is:
|
||||
// | | \ 1 / | h1 0,0
|
||||
// | | \ / | h2 0,1
|
||||
// | | 2 h5 3 | h3 1,0
|
||||
// | | / \ | h4 1,1
|
||||
// | | / 4 \ | h5 1/2,1/2
|
||||
// | h3-------h4
|
||||
// V Y
|
||||
// For find height need
|
||||
// 1 - detect triangle
|
||||
// 2 - solve linear equation from triangle points
|
||||
|
||||
// Calculate coefficients for solve h = a*x + b*y + c
|
||||
float a,b,c;
|
||||
// Select triangle:
|
||||
if (lx+ly < 1)
|
||||
{
|
||||
if (lx > ly)
|
||||
{
|
||||
// 1 triangle (h1, h2, h5 points)
|
||||
float h1 = gmap->v9[lx_int][ly_int];
|
||||
float h2 = gmap->v9[lx_int+1][ly_int];
|
||||
float h5 = 2 * gmap->v8[lx_int][ly_int];
|
||||
a = h2-h1;
|
||||
b = h5-h1-h2;
|
||||
c = h1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 triangle (h1, h3, h5 points)
|
||||
float h1 = gmap->v9[lx_int][ly_int];
|
||||
float h3 = gmap->v9[lx_int][ly_int+1];
|
||||
float h5 = 2 * gmap->v8[lx_int][ly_int];
|
||||
a = h5 - h1 - h3;
|
||||
b = h3 - h1;
|
||||
c = h1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lx > ly)
|
||||
{
|
||||
// 3 triangle (h2, h4, h5 points)
|
||||
float h2 = gmap->v9[lx_int+1][ly_int];
|
||||
float h4 = gmap->v9[lx_int+1][ly_int+1];
|
||||
float h5 = 2 * gmap->v8[lx_int][ly_int];
|
||||
a = h2 + h4 - h5;
|
||||
b = h4 - h2;
|
||||
c = h5 - h4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4 triangle (h3, h4, h5 points)
|
||||
float h3 = gmap->v9[lx_int][ly_int+1];
|
||||
float h4 = gmap->v9[lx_int+1][ly_int+1];
|
||||
float h5 = 2 * gmap->v8[lx_int][ly_int];
|
||||
a = h4 - h3;
|
||||
b = h3 + h4 - h5;
|
||||
c = h5 - h4;
|
||||
}
|
||||
}
|
||||
// Calculate height
|
||||
float _mapheight = a * lx + b * ly + c;
|
||||
float _mapheight = gmap->getHeight(x,y);
|
||||
|
||||
// look from a bit higher pos to find the floor, ignore under surface case
|
||||
if(z + 2.0f > _mapheight)
|
||||
|
|
@ -1203,25 +1619,9 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
|
|||
|
||||
uint16 Map::GetAreaFlag(float x, float y, float z) const
|
||||
{
|
||||
//local x,y coords
|
||||
float lx,ly;
|
||||
int gx,gy;
|
||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||
|
||||
// half opt method
|
||||
gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
|
||||
gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
|
||||
|
||||
lx=16*(32 -x/SIZE_OF_GRIDS - gx);
|
||||
ly=16*(32 -y/SIZE_OF_GRIDS - gy);
|
||||
//DEBUG_LOG("my %d %d si %d %d",gx,gy,p.x_coord,p.y_coord);
|
||||
|
||||
// ensure GridMap is loaded
|
||||
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
|
||||
uint16 areaflag;
|
||||
if(GridMaps[gx][gy])
|
||||
areaflag = GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
|
||||
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
areaflag = gmap->getArea(x, y);
|
||||
// this used while not all *.map files generated (instances)
|
||||
else
|
||||
areaflag = GetAreaFlagByMapId(i_id);
|
||||
|
|
@ -1240,6 +1640,11 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
|||
case 856: // The Noxious Glade (Eastern Plaguelands)
|
||||
case 2456: // Death's Breach (Eastern Plaguelands)
|
||||
if(z > 350.0f) areaflag = 1950; break;
|
||||
// Dalaran
|
||||
case 1593:
|
||||
case 2484:
|
||||
case 2492:
|
||||
if( (x < 6116 && x > 5568) && (y < 982 && y > 282) && z > 563.0f) areaflag = 2153; break;
|
||||
}
|
||||
|
||||
return areaflag;
|
||||
|
|
@ -1247,49 +1652,29 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
|||
|
||||
uint8 Map::GetTerrainType(float x, float y ) const
|
||||
{
|
||||
//local x,y coords
|
||||
float lx,ly;
|
||||
int gx,gy;
|
||||
|
||||
// half opt method
|
||||
gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
|
||||
gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
|
||||
|
||||
lx=16*(32 -x/SIZE_OF_GRIDS - gx);
|
||||
ly=16*(32 -y/SIZE_OF_GRIDS - gy);
|
||||
|
||||
// ensure GridMap is loaded
|
||||
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
|
||||
if(GridMaps[gx][gy])
|
||||
return GridMaps[gx][gy]->terrain_type[(int)(lx)][(int)(ly)];
|
||||
if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
return gmap->getTerrainType(x, y);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data) const
|
||||
{
|
||||
if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
return gmap->getLiquidStatus(x, y, z, ReqLiquidType, data);
|
||||
else
|
||||
return LIQUID_MAP_NO_WATER;
|
||||
}
|
||||
|
||||
float Map::GetWaterLevel(float x, float y ) const
|
||||
{
|
||||
//local x,y coords
|
||||
float lx,ly;
|
||||
int gx,gy;
|
||||
|
||||
// half opt method
|
||||
gx=(int)(32-x/SIZE_OF_GRIDS) ; //grid x
|
||||
gy=(int)(32-y/SIZE_OF_GRIDS); //grid y
|
||||
|
||||
lx=128*(32 -x/SIZE_OF_GRIDS - gx);
|
||||
ly=128*(32 -y/SIZE_OF_GRIDS - gy);
|
||||
|
||||
// ensure GridMap is loaded
|
||||
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
|
||||
if(GridMaps[gx][gy])
|
||||
return GridMaps[gx][gy]->liquid_level[(int)(lx)][(int)(ly)];
|
||||
if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
return gmap->getLiquidLevel(x, y);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
|
||||
uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
|
||||
|
||||
|
|
@ -1299,7 +1684,7 @@ uint32 Map::GetAreaId(uint16 areaflag,uint32 map_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
|
||||
uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
|
||||
|
||||
|
|
@ -1309,26 +1694,37 @@ uint32 Map::GetZoneId(uint16 areaflag,uint32 map_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const *entry = GetAreaEntryByAreaFlagAndMap(areaflag,map_id);
|
||||
|
||||
areaid = entry ? entry->ID : 0;
|
||||
zoneid = entry ? (( entry->zone != 0 ) ? entry->zone : entry->ID) : 0;
|
||||
}
|
||||
|
||||
bool Map::IsInWater(float x, float y, float pZ) const
|
||||
{
|
||||
// This method is called too often to use vamps for that (4. parameter = false).
|
||||
// The pZ pos is taken anyway for future use
|
||||
float z = GetHeight(x,y,pZ,false); // use .map base surface height
|
||||
|
||||
// underground or instance without vmap
|
||||
if(z <= INVALID_HEIGHT)
|
||||
return false;
|
||||
|
||||
float water_z = GetWaterLevel(x,y);
|
||||
uint8 flag = GetTerrainType(x,y);
|
||||
return (z < (water_z-2)) && (flag & 0x01);
|
||||
// Check surface in x, y point for liquid
|
||||
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
{
|
||||
LiquidData liquid_status;
|
||||
if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, &liquid_status))
|
||||
{
|
||||
if (liquid_status.level - liquid_status.depth_level > 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::IsUnderWater(float x, float y, float z) const
|
||||
{
|
||||
float water_z = GetWaterLevel(x,y);
|
||||
uint8 flag = GetTerrainType(x,y);
|
||||
return (z < (water_z-2)) && (flag & 0x01);
|
||||
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
{
|
||||
if (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER|MAP_LIQUID_TYPE_OCEAN)&LIQUID_MAP_UNDER_WATER)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::CheckGridIntegrity(Creature* c, bool moved) const
|
||||
|
|
@ -1817,7 +2213,6 @@ bool InstanceMap::Add(Player *player)
|
|||
// first player enters (no players yet)
|
||||
SetResetSchedule(false);
|
||||
|
||||
player->SendInitWorldStates();
|
||||
sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName());
|
||||
// initialize unload state
|
||||
m_unloadTimer = 0;
|
||||
|
|
@ -1933,7 +2328,7 @@ void InstanceMap::PermBindAllPlayers(Player *player)
|
|||
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId());
|
||||
if(!save)
|
||||
{
|
||||
sLog.outError("Cannot bind players, no instance save available for map!\n");
|
||||
sLog.outError("Cannot bind players, no instance save available for map!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
152
src/game/Map.h
152
src/game/Map.h
|
|
@ -68,14 +68,135 @@ typedef RGuard<GridRWLock, ZThread::Lockable> GridReadGuard;
|
|||
typedef WGuard<GridRWLock, ZThread::Lockable> GridWriteGuard;
|
||||
typedef MaNGOS::SingleThreaded<GridRWLock>::Lock NullGuard;
|
||||
|
||||
typedef struct
|
||||
//******************************************
|
||||
// Map file format defines
|
||||
//******************************************
|
||||
#define MAP_MAGIC 'SPAM'
|
||||
#define MAP_VERSION_MAGIC '0.1w'
|
||||
#define MAP_AREA_MAGIC 'AERA'
|
||||
#define MAP_HEIGTH_MAGIC 'TGHM'
|
||||
#define MAP_LIQUID_MAGIC 'QILM'
|
||||
|
||||
struct map_fileheader{
|
||||
uint32 mapMagic;
|
||||
uint32 versionMagic;
|
||||
uint32 areaMapOffset;
|
||||
uint32 areaMapSize;
|
||||
uint32 heightMapOffset;
|
||||
uint32 heightMapSize;
|
||||
uint32 liquidMapOffset;
|
||||
uint32 liquidMapSize;
|
||||
};
|
||||
|
||||
#define MAP_AREA_NO_AREA 0x0001
|
||||
struct map_areaHeader{
|
||||
uint32 fourcc;
|
||||
uint16 flags;
|
||||
uint16 gridArea;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HIGHT 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_HIGHT 0x0002
|
||||
struct map_liquidHeader{
|
||||
uint32 fourcc;
|
||||
uint16 flags;
|
||||
uint16 liquidType;
|
||||
uint8 offsetX;
|
||||
uint8 offsetY;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
float liquidLevel;
|
||||
};
|
||||
|
||||
enum ZLiquidStatus{
|
||||
LIQUID_MAP_NO_WATER = 0x00000000,
|
||||
LIQUID_MAP_ABOVE_WATER = 0x00000001,
|
||||
LIQUID_MAP_WATER_WALK = 0x00000002,
|
||||
LIQUID_MAP_IN_WATER = 0x00000004,
|
||||
LIQUID_MAP_UNDER_WATER = 0x00000008
|
||||
};
|
||||
|
||||
#define MAP_LIQUID_TYPE_NO_WATER 0x00
|
||||
#define MAP_LIQUID_TYPE_WATER 0x01
|
||||
#define MAP_LIQUID_TYPE_OCEAN 0x02
|
||||
#define MAP_LIQUID_TYPE_MAGMA 0x04
|
||||
#define MAP_LIQUID_TYPE_SLIME 0x08
|
||||
|
||||
#define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)
|
||||
|
||||
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
|
||||
#define MAP_LIQUID_TYPE_WMO_WATER 0x20
|
||||
|
||||
struct LiquidData{
|
||||
uint32 type;
|
||||
float level;
|
||||
float depth_level;
|
||||
};
|
||||
|
||||
class GridMap
|
||||
{
|
||||
uint16 area_flag[16][16];
|
||||
uint8 terrain_type[16][16];
|
||||
float liquid_level[128][128];
|
||||
float v9[MAP_RESOLUTION + 1][MAP_RESOLUTION + 1];
|
||||
float v8[MAP_RESOLUTION][MAP_RESOLUTION];
|
||||
}GridMap;
|
||||
uint32 m_flags;
|
||||
// Area data
|
||||
uint16 m_gridArea;
|
||||
uint16 *m_area_map;
|
||||
// Height level data
|
||||
float m_gridHeight;
|
||||
float m_gridIntHeightMultiplier;
|
||||
union{
|
||||
float *m_V9;
|
||||
uint16 *m_uint16_V9;
|
||||
uint8 *m_uint8_V9;
|
||||
};
|
||||
union{
|
||||
float *m_V8;
|
||||
uint16 *m_uint16_V8;
|
||||
uint8 *m_uint8_V8;
|
||||
};
|
||||
// Liquid data
|
||||
uint16 m_liquidType;
|
||||
uint8 m_liquid_offX;
|
||||
uint8 m_liquid_offY;
|
||||
uint8 m_liquid_width;
|
||||
uint8 m_liquid_height;
|
||||
float m_liquidLevel;
|
||||
uint8 *m_liquid_type;
|
||||
float *m_liquid_map;
|
||||
|
||||
bool loadAreaData(FILE *in, uint32 offset, uint32 size);
|
||||
bool loadHeihgtData(FILE *in, uint32 offset, uint32 size);
|
||||
bool loadLiquidData(FILE *in, uint32 offset, uint32 size);
|
||||
|
||||
// Get height functions and pointers
|
||||
typedef float (GridMap::*pGetHeightPtr) (float x, float y) const;
|
||||
pGetHeightPtr m_gridGetHeight;
|
||||
float getHeightFromFloat(float x, float y) const;
|
||||
float getHeightFromUint16(float x, float y) const;
|
||||
float getHeightFromUint8(float x, float y) const;
|
||||
float getHeightFromFlat(float x, float y) const;
|
||||
|
||||
public:
|
||||
GridMap();
|
||||
~GridMap();
|
||||
bool loadData(char *filaname);
|
||||
void unloadData();
|
||||
|
||||
uint16 getArea(float x, float y);
|
||||
inline float getHeight(float x, float y) {return (this->*m_gridGetHeight)(x, y);}
|
||||
float getLiquidLevel(float x, float y);
|
||||
uint8 getTerrainType(float x, float y);
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0);
|
||||
};
|
||||
|
||||
struct CreatureMover
|
||||
{
|
||||
|
|
@ -190,22 +311,30 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
float GetHeight(float x, float y, float z, bool pCheckVMap=true) const;
|
||||
bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use
|
||||
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0) const;
|
||||
|
||||
uint16 GetAreaFlag(float x, float y, float z) const;
|
||||
uint8 GetTerrainType(float x, float y ) const;
|
||||
float GetWaterLevel(float x, float y ) const;
|
||||
bool IsUnderWater(float x, float y, float z) const;
|
||||
|
||||
static uint32 GetAreaId(uint16 areaflag,uint32 map_id);
|
||||
static uint32 GetZoneId(uint16 areaflag,uint32 map_id);
|
||||
static uint32 GetAreaIdByAreaFlag(uint16 areaflag,uint32 map_id);
|
||||
static uint32 GetZoneIdByAreaFlag(uint16 areaflag,uint32 map_id);
|
||||
static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag,uint32 map_id);
|
||||
|
||||
uint32 GetAreaId(float x, float y, float z) const
|
||||
{
|
||||
return GetAreaId(GetAreaFlag(x,y,z),i_id);
|
||||
return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
|
||||
}
|
||||
|
||||
uint32 GetZoneId(float x, float y, float z) const
|
||||
{
|
||||
return GetZoneId(GetAreaFlag(x,y,z),i_id);
|
||||
return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
|
||||
}
|
||||
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
|
||||
{
|
||||
GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
|
||||
}
|
||||
|
||||
virtual void MoveAllCreaturesInMoveList();
|
||||
|
|
@ -277,6 +406,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
private:
|
||||
void LoadVMap(int pX, int pY);
|
||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||
GridMap *GetGrid(float x, float y);
|
||||
|
||||
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
|
||||
//uint64 CalculateGridMask(const uint32 &y) const;
|
||||
|
|
|
|||
|
|
@ -50,8 +50,18 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
|
|||
Map const* m = GetBaseMap(mapid);
|
||||
return m->GetAreaFlag(x, y, z);
|
||||
}
|
||||
uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); }
|
||||
uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); }
|
||||
uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
|
||||
{
|
||||
return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
|
||||
}
|
||||
uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
|
||||
{
|
||||
return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z),mapid);
|
||||
}
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
|
||||
{
|
||||
Map::GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(mapid, x, y, z),mapid);
|
||||
}
|
||||
|
||||
void Initialize(void);
|
||||
void Update(uint32);
|
||||
|
|
|
|||
|
|
@ -34,11 +34,9 @@
|
|||
#include "Chat.h"
|
||||
#include "ScriptCalls.h"
|
||||
#include <zlib/zlib.h>
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Object.h"
|
||||
#include "BattleGround.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Pet.h"
|
||||
#include "SocialMgr.h"
|
||||
|
||||
|
|
@ -386,10 +384,10 @@ void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data )
|
|||
|
||||
sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
|
||||
|
||||
if(newZone != _player->GetZoneId())
|
||||
GetPlayer()->SendInitWorldStates(); // only if really enters to new zone, not just area change, works strange...
|
||||
|
||||
GetPlayer()->UpdateZone(newZone);
|
||||
// use server size data
|
||||
uint32 newzone, newarea;
|
||||
GetPlayer()->GetZoneAndAreaId(newzone,newarea);
|
||||
GetPlayer()->UpdateZone(newzone,newarea);
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data )
|
||||
|
|
@ -859,8 +857,16 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
|||
}
|
||||
|
||||
uint32 missingQuest = 0;
|
||||
if(at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest))
|
||||
missingQuest = at->requiredQuest;
|
||||
if(GetPlayer()->GetDifficulty() == DIFFICULTY_HEROIC)
|
||||
{
|
||||
if (at->requiredQuestHeroic && !GetPlayer()->GetQuestRewardStatus(at->requiredQuestHeroic))
|
||||
missingQuest = at->requiredQuestHeroic;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(at->requiredQuest && !GetPlayer()->GetQuestRewardStatus(at->requiredQuest))
|
||||
missingQuest = at->requiredQuest;
|
||||
}
|
||||
|
||||
if(missingLevel || missingItem || missingKey || missingQuest)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Log.h"
|
||||
#include "World.h"
|
||||
#include "Corpse.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "MapManager.h"
|
||||
#include "Transports.h"
|
||||
#include "BattleGround.h"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue