Merged and fixed some whitespaces.

This commit is contained in:
tomrus88 2009-05-29 10:40:13 +04:00
commit 84ed071e16
42 changed files with 283 additions and 141 deletions

View file

@ -15,7 +15,7 @@
* *
********************************************************************/ ********************************************************************/
#ifndef _WIN32 || _WIN64 #ifndef _WIN32
#include "StormPort.h" #include "StormPort.h"
#include "StormLib.h" #include "StormLib.h"

View file

@ -1,5 +1,6 @@
#include "adtfile.h" #include "adtfile.h"
#include <algorithm>
char * GetPlainName(char * FileName) char * GetPlainName(char * FileName)
{ {
char * szTemp; char * szTemp;
@ -22,6 +23,7 @@ void fixnamen(char *name, size_t len)
} }
} }
} }
void fixname2(char *name, size_t len) void fixname2(char *name, size_t len)
{ {
for (size_t i=0; i<len-3; i++) for (size_t i=0; i<len-3; i++)
@ -42,10 +44,10 @@ bool ADTFile::init(char *map_id)
return false; return false;
size_t size; size_t size;
string xMap; string xMap;
string yMap; string yMap;
Adtfilename.erase(Adtfilename.find(".adt"),4); Adtfilename.erase(Adtfilename.find(".adt"),4);
string TempMapNumber; string TempMapNumber;
TempMapNumber = Adtfilename.substr(Adtfilename.length()-6,6); TempMapNumber = Adtfilename.substr(Adtfilename.length()-6,6);
@ -100,18 +102,27 @@ bool ADTFile::init(char *map_id)
fixname2(s,strlen(s)); fixname2(s,strlen(s));
p=p+strlen(p)+1; p=p+strlen(p)+1;
ModelInstansName[t++] = s; ModelInstansName[t++] = s;
path.erase(path.length()-2,2);
path.append("2"); // < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
char* szLocalFile[512]; std::string ext3 = path.size() >= 4 ? path.substr(path.size()-4,4) : "";
sprintf((char*)szLocalFile, ".\\buildings\\%s", s); std::transform( ext3.begin(), ext3.end(), ext3.begin(), ::tolower );
FILE * output = fopen((char*)szLocalFile,"rb"); if(ext3 == ".mdx")
{
// replace .mdx -> .m2
path.erase(path.length()-2,2);
path.append("2");
}
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
// nothing do
char szLocalFile[MAX_PATH];
sprintf(szLocalFile, ".\\buildings\\%s", s);
FILE * output = fopen(szLocalFile,"rb");
if(!output) if(!output)
{ {
Model * m2 = new Model(path); Model * m2 = new Model(path);
if(m2->open()) if(m2->open())
{ m2->ConvertToVMAPModel(szLocalFile);
m2->ConvertToVMAPModel((char*)szLocalFile);
}
delete m2; delete m2;
} }
else else
@ -129,7 +140,7 @@ bool ADTFile::init(char *map_id)
char *p=buf; char *p=buf;
int q = 0; int q = 0;
WmoInstansName = new string[size]; WmoInstansName = new string[size];
while (p<buf+size) while (p<buf+size)
{ {
string path(p); string path(p);
char* s=GetPlainName(p); char* s=GetPlainName(p);
@ -171,7 +182,7 @@ bool ADTFile::init(char *map_id)
} }
} }
//====================== //======================
#if 0 #if 0
else if (!strcmp(fourcc,"MDDF")) else if (!strcmp(fourcc,"MDDF"))
{ {
if (size) if (size)

View file

@ -24,17 +24,17 @@ typedef struct
float z; float z;
}svec; }svec;
typedef struct struct vec
{ {
double x; double x;
double y; double y;
double z; double z;
}vec; };
typedef struc struct triangle
{ {
vec v[3]; vec v[3];
}triangle; };
typedef struct typedef struct
{ {

View file

@ -36,7 +36,7 @@ bool DBCFile::open()
f.read(&nb,4); // Number of fields f.read(&nb,4); // Number of fields
f.read(&es,4); // Size of a record f.read(&es,4); // Size of a record
f.read(&ss,4); // String size f.read(&ss,4); // String size
recordSize = es; recordSize = es;
recordCount = na; recordCount = na;
fieldCount = nb; fieldCount = nb;

View file

@ -91,7 +91,7 @@ public:
class Iterator class Iterator
{ {
public: public:
Iterator(DBCFile &file, unsigned char *offset): Iterator(DBCFile &file, unsigned char *offset):
record(file, offset) {} record(file, offset) {}
/// Advance (prefix only) /// Advance (prefix only)
Iterator & operator++() { Iterator & operator++() {

View file

@ -3,23 +3,16 @@
#include "Stormlib.h" #include "Stormlib.h"
#define __STORMLIB_SELF__ #define __STORMLIB_SELF__
typedef std::vector<MPQArchive*> ArchiveSet; MPQArchiveSet gOpenArchives;
ArchiveSet gOpenArchives;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MPQArchive::MPQArchive(const char* filename) MPQArchive::MPQArchive(const char* filename)
{ {
BOOL succ = SFileOpenArchive(filename, 0, 0,&hMPQ); BOOL succ = SFileOpenArchive(filename, 0, 0,&hMPQ);
if (succ) if (succ)
{
MPQArchive*ar = (MPQArchive*)(hMPQ);
printf("Opening %s\n", filename); printf("Opening %s\n", filename);
gOpenArchives.push_back(ar);
succ = true;
}
else else
{
printf("Error!!!Not open archive %s\n", filename); printf("Error!!!Not open archive %s\n", filename);
}
} }
void MPQArchive::close() void MPQArchive::close()
@ -27,16 +20,35 @@ void MPQArchive::close()
SFileCloseArchive(hMPQ); SFileCloseArchive(hMPQ);
} }
bool MPQArchiveSet::Open( std::vector<std::string> const& archiveNames )
{
for (size_t i=0; i < archiveNames.size(); ++i)
{
MPQArchive mpqarch(archiveNames[i].c_str());
if(mpqarch.isOpen())
archives.push_back(mpqarch);
}
return !archives.empty();
}
MPQArchiveSet::~MPQArchiveSet()
{
// close archives
for (ArchiveSet::iterator ar_itr = archives.begin(); ar_itr != archives.end(); ++ar_itr)
ar_itr->close();
}
MPQFile::MPQFile(const char* filename): MPQFile::MPQFile(const char* filename):
eof(false), eof(false),
buffer(0), buffer(0),
pointer(0), pointer(0),
size(0) size(0)
{ {
for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) for(ArchiveSet::const_iterator i=gOpenArchives.archives.begin(); i!=gOpenArchives.archives.end();++i)
{ {
HANDLE hFile = ""; HANDLE hFile = "";
MPQArchive*(hMPQ) = *i; hMPQ = i->hMPQ;
BOOL succ = SFileOpenFileEx(hMPQ,filename,0, &hFile); BOOL succ = SFileOpenFileEx(hMPQ,filename,0, &hFile);
if (succ) if (succ)
{ {
@ -54,7 +66,7 @@ MPQFile::MPQFile(const char* filename):
eof = false; eof = false;
return; return;
} }
} }
eof = true; eof = true;

View file

@ -17,12 +17,28 @@ typedef unsigned int uint32;
class MPQArchive class MPQArchive
{ {
public: public:
HANDLE hMPQ; HANDLE hMPQ;
MPQArchive(const char* filename); MPQArchive(const char* filename);
void close(); void close();
bool isOpen() const { return hMPQ != 0; }
}; };
typedef std::vector<MPQArchive> ArchiveSet;
class MPQArchiveSet
{
public:
MPQArchiveSet() {}
~MPQArchiveSet();
bool Open(std::vector<std::string> const& archiveNames);
ArchiveSet archives;
};
extern MPQArchiveSet gOpenArchives;
class MPQFile class MPQFile
{ {
HANDLE hFile; HANDLE hFile;

View file

@ -118,7 +118,7 @@ class Vec2D
{ {
public: public:
float x,y; float x,y;
Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {} Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {}
Vec2D(const Vec2D& v) : x(v.x), y(v.y) {} Vec2D(const Vec2D& v) : x(v.x), y(v.y) {}

View file

@ -90,6 +90,7 @@ static const char * GetPlainName(const char * szFileName)
static void ShowProcessedFile(const char * szFileName) static void ShowProcessedFile(const char * szFileName)
{ {
/* not truncate file names in output
char szLine[80]; char szLine[80];
size_t nLength = strlen(szFileName); size_t nLength = strlen(szFileName);
@ -100,13 +101,14 @@ static void ShowProcessedFile(const char * szFileName)
nLength = sizeof(szLine)-1; nLength = sizeof(szLine)-1;
memcpy(szLine, szFileName, nLength); memcpy(szLine, szFileName, nLength);
printf("\r%s\n", szLine); printf("\r%s\n", szLine);
*/
printf("\r%s\n", szFileName);
} }
int ExtractWmo(const std::vector<std::string>& pArchiveNames) int ExtractWmo()
{ {
char* szListFile = ""; char* szListFile = "";
char szLocalFile[MAX_PATH] = ""; char szLocalFile[MAX_PATH] = "";
HANDLE hMpq = "";
BOOL bResult = FALSE; BOOL bResult = FALSE;
//const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
@ -114,20 +116,14 @@ int ExtractWmo(const std::vector<std::string>& pArchiveNames)
int nError = ERROR_SUCCESS; int nError = ERROR_SUCCESS;
if(szListFile == NULL || *szListFile == 0) if(szListFile == NULL || *szListFile == 0)
szListFile = NULL; szListFile = NULL;
//char tmp[1024];
//for (size_t i=0; i<4; i++)
for (size_t i=0; i<pArchiveNames.size(); ++i)
{
//sprintf(tmp,"%s\\%s", input_path, ParsArchiveNames[i]);
//if(!SFileOpenArchive(tmp, 0, 0, &hMpq))
if(!SFileOpenArchive(pArchiveNames[i].c_str(), 0, 0, &hMpq))
printf("NOT open!!! %s\n",pArchiveNames[i].c_str());
for (ArchiveSet::const_iterator ar_itr = gOpenArchives.archives.begin(); ar_itr != gOpenArchives.archives.end(); ++ar_itr)
{
// Copy files from archive // Copy files from archive
if(nError == ERROR_SUCCESS) if(nError == ERROR_SUCCESS)
{ {
SFILE_FIND_DATA wf; SFILE_FIND_DATA wf;
HANDLE hFind = SFileFindFirstFile(hMpq,"*.wmo*", &wf, szListFile); HANDLE hFind = SFileFindFirstFile(ar_itr->hMPQ,"*.wmo*", &wf, szListFile);
bResult = TRUE; bResult = TRUE;
while(hFind != NULL && bResult == TRUE) while(hFind != NULL && bResult == TRUE)
@ -171,10 +167,10 @@ int ExtractWmo(const std::vector<std::string>& pArchiveNames)
{ {
for (int i=0; i<froot->nGroups; ++i) for (int i=0; i<froot->nGroups; ++i)
{ {
char temp[512]; char temp[MAX_PATH];
strcpy(temp, wf.cFileName); strcpy(temp, wf.cFileName);
temp[strlen(wf.cFileName)-4] = 0; temp[strlen(wf.cFileName)-4] = 0;
char groupFileName[512]; char groupFileName[MAX_PATH];
sprintf(groupFileName,"%s_%03d.wmo",temp, i); sprintf(groupFileName,"%s_%03d.wmo",temp, i);
printf("%s\n",groupFileName); printf("%s\n",groupFileName);
//printf("GroupWmo!\n"); //printf("GroupWmo!\n");
@ -212,12 +208,6 @@ int ExtractWmo(const std::vector<std::string>& pArchiveNames)
} }
} }
// Close both archives
if(hMpq != NULL)
{
//SFileCloseArchive(hMpq);
}
if(nError == ERROR_SUCCESS) if(nError == ERROR_SUCCESS)
printf("\nExtract wmo complete (No errors)\n"); printf("\nExtract wmo complete (No errors)\n");
@ -533,26 +523,30 @@ int main(int argc, char ** argv)
if(nError == ERROR_ALREADY_EXISTS) if(nError == ERROR_ALREADY_EXISTS)
nError = ERROR_SUCCESS; nError = ERROR_SUCCESS;
} }
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// patch goes first -> fake priority handling
std::vector<MPQArchive*> archives;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // prepare archive name list
std::vector<std::string> archiveNames; std::vector<std::string> archiveNames;
fillArchiveNameVector(archiveNames); fillArchiveNameVector(archiveNames);
for (size_t i=0; i<archiveNames.size(); ++i) if(!gOpenArchives.Open(archiveNames))
{ {
archives.push_back(new MPQArchive(archiveNames[i].c_str())); printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path);
return 1;
} }
ExtractWmo(archiveNames);
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // extract data
ExtractWmo();
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//map.dbc //map.dbc
if(nError == ERROR_SUCCESS) if(nError == ERROR_SUCCESS)
{ {
DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc"); DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
dbc->open(); if(!dbc->open())
{
delete dbc;
printf("FATAL ERROR: Map.dbc not found in data file.\n");
return 1;
}
map_count=dbc->getRecordCount (); map_count=dbc->getRecordCount ();
map_ids=new map_id[map_count]; map_ids=new map_id[map_count];
for(unsigned int x=0;x<map_count;++x) for(unsigned int x=0;x<map_count;++x)
@ -574,5 +568,6 @@ int main(int argc, char ** argv)
printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData); printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData);
_getch(); _getch();
} }
printf("Extract %s. Work complete. No errors.",versionString); printf("Extract %s. Work complete. No errors.",versionString);
} }

View file

@ -295,7 +295,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
{ {
int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU" int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
fwrite(LIQU_h,4,4,output); fwrite(LIQU_h,4,4,output);
fwrite(LiquEx,4,LiquEx_size/4,output); fwrite(LiquEx,4,LiquEx_size/4,output);
delete [] LiquEx; delete [] LiquEx;
} }
@ -305,7 +305,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
{ {
//printf("Convert GroupWmo...\n"); //printf("Convert GroupWmo...\n");
//-------GRP ------------------------------------- //-------GRP -------------------------------------
fwrite(&liquflags,sizeof(uint32),1,output); fwrite(&liquflags,sizeof(uint32),1,output);
char GRP[] = "GRP "; char GRP[] = "GRP ";
fwrite(GRP,1,4,output); fwrite(GRP,1,4,output);
int k = 0; int k = 0;
@ -317,7 +317,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
} }
delete [] MOBA; delete [] MOBA;
int moba_size_grp = moba_batch*4+4; int moba_size_grp = moba_batch*4+4;
fwrite(&moba_size_grp,4,1,output); fwrite(&moba_size_grp,4,1,output);
fwrite(&moba_batch,4,1,output); fwrite(&moba_batch,4,1,output);
fwrite(MobaEx,4,k,output); fwrite(MobaEx,4,k,output);
delete [] MobaEx; delete [] MobaEx;
@ -335,7 +335,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
continue; continue;
// Use only this triangles // Use only this triangles
if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT)) if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT))
{ {
MopyEx[n] = MOPY[i]; MopyEx[n] = MOPY[i];
MopyEx[(n+1)] = MOPY[(i+1)]; MopyEx[(n+1)] = MOPY[(i+1)];
IndexExTr[j] = i/2; IndexExTr[j] = i/2;
@ -454,7 +454,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
delete [] MovtEx; delete [] MovtEx;
delete [] MovtExSort; delete [] MovtExSort;
//--------------------------------------------- //---------------------------------------------
return IndexExTr_size; return IndexExTr_size;
} }
} }

View file

@ -37,7 +37,7 @@ public:
WMORoot(std::string &filename); WMORoot(std::string &filename);
~WMORoot(); ~WMORoot();
bool open(); bool open();
bool ConvertToVMAPRootWmo(FILE *output); bool ConvertToVMAPRootWmo(FILE *output);
private: private:

View file

@ -129,6 +129,7 @@ Params are always read from Param1, then Param2, then Param3.
37 ACTION_T_DIE No Params Kills the creature 37 ACTION_T_DIE No Params Kills the creature
38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances. 38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
39 ACTION_T_CALL_FOR_HELP Radius Call any friendly creatures (if its not in combat/etc) in radius attack creature target. 39 ACTION_T_CALL_FOR_HELP Radius Call any friendly creatures (if its not in combat/etc) in radius attack creature target.
40 ACTION_T_SET_SHEATH Sheath Let set sheath state for creature (0-no weapon show (not used mostly by creatures), 1-melee weapon show, 2-ranged weapon show)
* = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2) * = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
@ -684,6 +685,25 @@ This is commonly used if you need to Instakill the creature for one reason or an
-------------------------------- --------------------------------
Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances. Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
----------------------------
39 = ACTION_T_CALL_FOR_HELP:
----------------------------
Parameter 1: Radius - All friendly (not only same faction) creatures will go to help
Call any friendly creatures (if its not in combat/etc) in radius attack creature target.
Mostly used when call to help more wide that normal aggro radius or auto-used call for assistance, and need apply at some event.
-------------------------
40 ACTION_T_SET_SHEATH:
-------------------------
Parameter 1: Sheath state
0 SHEATH_STATE_UNARMED not prepared weapon show (not used mostly by creatures)
1 SHEATH_STATE_MELEE melee weapon prepared show
2 SHEATH_STATE_RANGED ranged weapon prepared show
Let set sheath state for creature.
Note: SHEATH_STATE_RANGED case work in combat state only if combat not start as melee commands.
This possible setup by set ar event AI start (single used EVENT_T_TIMER_OOC set ACTION_T_COMBAT_MOVEMENT 0 for creature that prefered ranged attack)
========================================= =========================================
Target Types Target Types

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`required_7902_02_mangos_pool_gameobject` bit(1) default NULL `required_7908_03_mangos_creature_template_addon` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -564,7 +564,6 @@ DROP TABLE IF EXISTS `creature_addon`;
CREATE TABLE `creature_addon` ( CREATE TABLE `creature_addon` (
`guid` int(11) NOT NULL default '0', `guid` int(11) NOT NULL default '0',
`mount` mediumint(8) unsigned NOT NULL default '0', `mount` mediumint(8) unsigned NOT NULL default '0',
`bytes0` int(10) unsigned NOT NULL default '0',
`bytes1` int(10) unsigned NOT NULL default '0', `bytes1` int(10) unsigned NOT NULL default '0',
`bytes2` int(10) unsigned NOT NULL default '0', `bytes2` int(10) unsigned NOT NULL default '0',
`emote` int(10) unsigned NOT NULL default '0', `emote` int(10) unsigned NOT NULL default '0',
@ -813,8 +812,10 @@ CREATE TABLE `creature_template` (
`maxdmg` float NOT NULL default '0', `maxdmg` float NOT NULL default '0',
`dmgschool` tinyint(4) NOT NULL default '0', `dmgschool` tinyint(4) NOT NULL default '0',
`attackpower` int(10) unsigned NOT NULL default '0', `attackpower` int(10) unsigned NOT NULL default '0',
`dmg_multiplier` float NOT NULL default '1',
`baseattacktime` int(10) unsigned NOT NULL default '0', `baseattacktime` int(10) unsigned NOT NULL default '0',
`rangeattacktime` int(10) unsigned NOT NULL default '0', `rangeattacktime` int(10) unsigned NOT NULL default '0',
`unit_class` tinyint(3) unsigned NOT NULL default '0',
`unit_flags` int(10) unsigned NOT NULL default '0', `unit_flags` int(10) unsigned NOT NULL default '0',
`dynamicflags` int(10) unsigned NOT NULL default '0', `dynamicflags` int(10) unsigned NOT NULL default '0',
`family` tinyint(4) NOT NULL default '0', `family` tinyint(4) NOT NULL default '0',
@ -864,7 +865,7 @@ CREATE TABLE `creature_template` (
LOCK TABLES `creature_template` WRITE; LOCK TABLES `creature_template` WRITE;
/*!40000 ALTER TABLE `creature_template` DISABLE KEYS */; /*!40000 ALTER TABLE `creature_template` DISABLE KEYS */;
INSERT INTO `creature_template` VALUES INSERT INTO `creature_template` VALUES
(1,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,2000,2200,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1.0,1.0,0,1,0,0,0x82,''); (1,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,1,2000,2200,8,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1.0,1.0,0,1,0,0,0x82,'');
/*!40000 ALTER TABLE `creature_template` ENABLE KEYS */; /*!40000 ALTER TABLE `creature_template` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@ -876,7 +877,6 @@ DROP TABLE IF EXISTS `creature_template_addon`;
CREATE TABLE `creature_template_addon` ( CREATE TABLE `creature_template_addon` (
`entry` mediumint(8) unsigned NOT NULL default '0', `entry` mediumint(8) unsigned NOT NULL default '0',
`mount` mediumint(8) unsigned NOT NULL default '0', `mount` mediumint(8) unsigned NOT NULL default '0',
`bytes0` int(10) unsigned NOT NULL default '0',
`bytes1` int(10) unsigned NOT NULL default '0', `bytes1` int(10) unsigned NOT NULL default '0',
`bytes2` int(10) unsigned NOT NULL default '0', `bytes2` int(10) unsigned NOT NULL default '0',
`emote` mediumint(8) unsigned NOT NULL default '0', `emote` mediumint(8) unsigned NOT NULL default '0',

View file

@ -1,4 +1,3 @@
ALTER TABLE db_version CHANGE COLUMN required_7884_02_mangos_playercreateinfo_action required_7886_01_mangos_petcreateinfo_spell bit; ALTER TABLE db_version CHANGE COLUMN required_7884_02_mangos_playercreateinfo_action required_7886_01_mangos_petcreateinfo_spell bit;
DROP TABLE IF EXISTS `petcreateinfo_spell`; DROP TABLE IF EXISTS `petcreateinfo_spell`;

View file

@ -1,4 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7896_01_mangos_creature_template required_7902_01_mangos_pool_creature bit; ALTER TABLE db_version CHANGE COLUMN required_7896_01_mangos_creature_template required_7902_01_mangos_pool_creature bit;
ALTER TABLE `pool_creature` ALTER TABLE `pool_creature`
ADD INDEX `idx_guid`(`guid`); ADD INDEX `idx_guid`(`guid`);

View file

@ -1,4 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7902_01_mangos_pool_creature required_7902_02_mangos_pool_gameobject bit; ALTER TABLE db_version CHANGE COLUMN required_7902_01_mangos_pool_creature required_7902_02_mangos_pool_gameobject bit;
ALTER TABLE `pool_gameobject` ALTER TABLE `pool_gameobject`
ADD INDEX `idx_guid`(`guid`); ADD INDEX `idx_guid`(`guid`);

View file

@ -0,0 +1,9 @@
ALTER TABLE db_version CHANGE COLUMN required_7902_02_mangos_pool_gameobject required_7904_01_mangos_creature_template bit;
ALTER TABLE creature_template
ADD COLUMN dmg_multiplier float NOT NULL default '1' AFTER attackpower;
UPDATE creature_template SET mindmg = round(mindmg + attackpower / 14);
UPDATE creature_template SET maxdmg = round(maxdmg + attackpower / 14);
UPDATE creature_template SET attackpower = round((maxdmg + mindmg) * 0.3);
UPDATE creature_template SET mindmg = round(mindmg * 0.7), maxdmg = round(maxdmg * 0.7);

View file

@ -0,0 +1,17 @@
ALTER TABLE db_version CHANGE COLUMN required_7904_01_mangos_creature_template required_7908_01_mangos_creature_template bit;
ALTER TABLE creature_template ADD COLUMN unit_class tinyint(3) unsigned NOT NULL default '0' AFTER rangeattacktime;
UPDATE creature_template ct
JOIN creature c ON ct.entry=c.id
JOIN creature_addon ad ON c.guid=ad.guid
SET ct.unit_class=(ad.bytes0 & 0x0000FF00) >> 8
WHERE ct.entry=c.id AND ct.unit_class=0;
UPDATE creature_template ct
JOIN creature_template_addon ad ON ct.entry=ad.entry
SET ct.unit_class=(ad.bytes0 & 0x0000FF00) >> 8
WHERE ct.entry=ad.entry AND ct.unit_class=0;
UPDATE creature_template a1, creature_template a2 SET a1.unit_class=a2.unit_class WHERE a1.unit_class=0 AND a2.unit_class!=0 AND a1.entry=a2.heroic_entry;
UPDATE creature_template a1, creature_template a2 SET a1.unit_class=a2.unit_class WHERE a1.unit_class=0 AND a2.unit_class!=0 AND a2.entry=a1.heroic_entry;

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7908_01_mangos_creature_template required_7908_02_mangos_creature_addon bit;
ALTER TABLE creature_addon
DROP COLUMN bytes0;

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7908_02_mangos_creature_addon required_7908_03_mangos_creature_template_addon bit;
ALTER TABLE creature_template_addon
DROP COLUMN bytes0;

View file

@ -204,6 +204,10 @@ pkgdata_DATA = \
7902_01_mangos_pool_creature.sql \ 7902_01_mangos_pool_creature.sql \
7902_02_mangos_pool_gameobject.sql \ 7902_02_mangos_pool_gameobject.sql \
7903_01_characters_character_pet.sql \ 7903_01_characters_character_pet.sql \
7904_01_mangos_creature_template.sql \
7908_01_mangos_creature_template.sql \
7908_02_mangos_creature_addon.sql \
7908_03_mangos_creature_template_addon.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -388,4 +392,8 @@ EXTRA_DIST = \
7902_01_mangos_pool_creature.sql \ 7902_01_mangos_pool_creature.sql \
7902_02_mangos_pool_gameobject.sql \ 7902_02_mangos_pool_gameobject.sql \
7903_01_characters_character_pet.sql \ 7903_01_characters_character_pet.sql \
7904_01_mangos_creature_template.sql \
7908_01_mangos_creature_template.sql \
7908_02_mangos_creature_addon.sql \
7908_03_mangos_creature_template_addon.sql \
README README

View file

@ -81,7 +81,13 @@ void WorldSession::HandleSetSheathedOpcode( WorldPacket & recv_data )
//sLog.outDebug( "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed ); //sLog.outDebug( "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed );
GetPlayer()->SetSheath(sheathed); if(sheathed >= MAX_SHEATH_STATE)
{
sLog.outError("Unknown sheath state %u ??",sheathed);
return;
}
GetPlayer()->SetSheath(SheathState(sheathed));
} }
void WorldSession::SendAttackStop(Unit const* enemy) void WorldSession::SendAttackStop(Unit const* enemy)

View file

@ -197,6 +197,12 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetEntry(Entry); // normal entry always SetEntry(Entry); // normal entry always
m_creatureInfo = cinfo; // map mode related always m_creatureInfo = cinfo; // map mode related always
// equal to player Race field, but creature does not have race
SetByteValue(UNIT_FIELD_BYTES_0, 0, 0);
// known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE
SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
if (cinfo->DisplayID_A == 0 || cinfo->DisplayID_H == 0) // Cancel load if no model defined if (cinfo->DisplayID_A == 0 || cinfo->DisplayID_H == 0) // Cancel load if no model defined
{ {
sLog.outErrorDb("Creature (Entry: %u) has no model defined for Horde or Alliance in table `creature_template`, can't load. ",Entry); sLog.outErrorDb("Creature (Entry: %u) has no model defined for Horde or Alliance in table `creature_template`, can't load. ",Entry);
@ -256,7 +262,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
m_regenHealth = GetCreatureInfo()->RegenHealth; m_regenHealth = GetCreatureInfo()->RegenHealth;
// creatures always have melee weapon ready if any // creatures always have melee weapon ready if any
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); SetSheath(SHEATH_STATE_MELEE);
SelectLevel(GetCreatureInfo()); SelectLevel(GetCreatureInfo());
if (team == HORDE) if (team == HORDE)
@ -1204,6 +1210,8 @@ void Creature::SelectLevel(const CreatureInfo *cinfo)
SetMaxPower(POWER_MANA, mana); //MAX Mana SetMaxPower(POWER_MANA, mana); //MAX Mana
SetPower(POWER_MANA, mana); SetPower(POWER_MANA, mana);
// TODO: set UNIT_FIELD_POWER*, for some creature class case (energy, etc)
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, health); SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, health);
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, mana); SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, mana);
@ -1860,9 +1868,6 @@ bool Creature::LoadCreaturesAddon(bool reload)
if (cainfo->mount != 0) if (cainfo->mount != 0)
Mount(cainfo->mount); Mount(cainfo->mount);
if (cainfo->bytes0 != 0)
SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
if (cainfo->bytes1 != 0) if (cainfo->bytes1 != 0)
SetUInt32Value(UNIT_FIELD_BYTES_1, cainfo->bytes1); SetUInt32Value(UNIT_FIELD_BYTES_1, cainfo->bytes1);

View file

@ -183,8 +183,10 @@ struct CreatureInfo
float maxdmg; float maxdmg;
uint32 dmgschool; uint32 dmgschool;
uint32 attackpower; uint32 attackpower;
float dmg_multiplier;
uint32 baseattacktime; uint32 baseattacktime;
uint32 rangeattacktime; uint32 rangeattacktime;
uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures.
uint32 unit_flags; // enum UnitFlags mask values uint32 unit_flags; // enum UnitFlags mask values
uint32 dynamicflags; uint32 dynamicflags;
uint32 family; // enum CreatureFamily values (optional) uint32 family; // enum CreatureFamily values (optional)
@ -299,7 +301,6 @@ struct CreatureDataAddon
{ {
uint32 guidOrEntry; uint32 guidOrEntry;
uint32 mount; uint32 mount;
uint32 bytes0;
uint32 bytes1; uint32 bytes1;
uint32 bytes2; uint32 bytes2;
uint32 emote; uint32 emote;

View file

@ -613,7 +613,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above %u. Phase mask cannot be used with phases past %u. CreatureEntry = %d", EventId, MAX_PHASE-1, MAX_PHASE-1, m_creature->GetEntry()); sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above %u. Phase mask cannot be used with phases past %u. CreatureEntry = %d", EventId, MAX_PHASE-1, MAX_PHASE-1, m_creature->GetEntry());
Phase = MAX_PHASE-1; Phase = MAX_PHASE-1;
} }
else else
Phase = new_phase; Phase = new_phase;
break; break;
@ -783,6 +783,11 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
break; break;
} }
case ACTION_T_SET_SHEATH:
{
m_creature->SetSheath(SheathState(action.set_sheath.sheath));
break;
}
} }
} }

View file

@ -102,7 +102,7 @@ enum EventAI_ActionType
ACTION_T_DIE = 37, // No Params ACTION_T_DIE = 37, // No Params
ACTION_T_ZONE_COMBAT_PULSE = 38, // No Params ACTION_T_ZONE_COMBAT_PULSE = 38, // No Params
ACTION_T_CALL_FOR_HELP = 39, // Radius ACTION_T_CALL_FOR_HELP = 39, // Radius
ACTION_T_SET_SHEATH = 40, // Sheath (0-passive,1-melee,2-ranged)
ACTION_T_END, ACTION_T_END,
}; };
@ -197,69 +197,69 @@ struct CreatureEventAI_Action
uint32 modelId; uint32 modelId;
} morph; } morph;
// ACTION_T_SOUND = 4 // ACTION_T_SOUND = 4
struct struct
{ {
uint32 soundId; uint32 soundId;
} sound; } sound;
// ACTION_T_EMOTE = 5 // ACTION_T_EMOTE = 5
struct struct
{ {
uint32 emoteId; uint32 emoteId;
} emote; } emote;
// ACTION_T_RANDOM_SOUND = 9 // ACTION_T_RANDOM_SOUND = 9
struct struct
{ {
int32 soundId1; // (-1 in any field means no output if randomed that field) int32 soundId1; // (-1 in any field means no output if randomed that field)
int32 soundId2; int32 soundId2;
int32 soundId3; int32 soundId3;
} random_sound; } random_sound;
// ACTION_T_RANDOM_EMOTE = 10 // ACTION_T_RANDOM_EMOTE = 10
struct struct
{ {
int32 emoteId1; // (-1 in any field means no output if randomed that field) int32 emoteId1; // (-1 in any field means no output if randomed that field)
int32 emoteId2; int32 emoteId2;
int32 emoteId3; int32 emoteId3;
} random_emote; } random_emote;
// ACTION_T_CAST = 11 // ACTION_T_CAST = 11
struct struct
{ {
uint32 spellId; uint32 spellId;
uint32 target; uint32 target;
uint32 castFlags; uint32 castFlags;
} cast; } cast;
// ACTION_T_SUMMON = 12 // ACTION_T_SUMMON = 12
struct struct
{ {
uint32 creatured; uint32 creatured;
uint32 target; uint32 target;
uint32 duration; uint32 duration;
} summon; } summon;
// ACTION_T_THREAT_SINGLE_PCT = 13 // ACTION_T_THREAT_SINGLE_PCT = 13
struct struct
{ {
int32 percent; int32 percent;
uint32 target; uint32 target;
} threat_single_pct; } threat_single_pct;
// ACTION_T_THREAT_ALL_PCT = 14 // ACTION_T_THREAT_ALL_PCT = 14
struct struct
{ {
int32 percent; int32 percent;
} threat_all_pct; } threat_all_pct;
// ACTION_T_QUEST_EVENT = 15 // ACTION_T_QUEST_EVENT = 15
struct struct
{ {
uint32 questId; uint32 questId;
uint32 target; uint32 target;
} quest_event; } quest_event;
// ACTION_T_CAST_EVENT = 16 // ACTION_T_CAST_EVENT = 16
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 spellId; uint32 spellId;
uint32 target; uint32 target;
} cast_event; } cast_event;
// ACTION_T_SET_UNIT_FIELD = 17 // ACTION_T_SET_UNIT_FIELD = 17
struct struct
{ {
uint32 field; uint32 field;
uint32 value; uint32 value;
@ -267,94 +267,94 @@ struct CreatureEventAI_Action
} set_unit_field; } set_unit_field;
// ACTION_T_SET_UNIT_FLAG = 18, // value provided mask bits that will be set // ACTION_T_SET_UNIT_FLAG = 18, // value provided mask bits that will be set
// ACTION_T_REMOVE_UNIT_FLAG = 19, // value provided mask bits that will be clear // ACTION_T_REMOVE_UNIT_FLAG = 19, // value provided mask bits that will be clear
struct struct
{ {
uint32 value; uint32 value;
uint32 target; uint32 target;
} unit_flag; } unit_flag;
// ACTION_T_AUTO_ATTACK = 20 // ACTION_T_AUTO_ATTACK = 20
struct struct
{ {
uint32 state; // 0 = stop attack, anything else means continue attacking uint32 state; // 0 = stop attack, anything else means continue attacking
} auto_attack; } auto_attack;
// ACTION_T_COMBAT_MOVEMENT = 21 // ACTION_T_COMBAT_MOVEMENT = 21
struct struct
{ {
uint32 state; // 0 = stop combat based movement, anything else continue attacking uint32 state; // 0 = stop combat based movement, anything else continue attacking
} combat_movement; } combat_movement;
// ACTION_T_SET_PHASE = 22 // ACTION_T_SET_PHASE = 22
struct struct
{ {
uint32 phase; uint32 phase;
} set_phase; } set_phase;
// ACTION_T_INC_PHASE = 23 // ACTION_T_INC_PHASE = 23
struct struct
{ {
int32 step; int32 step;
} set_inc_phase; } set_inc_phase;
// ACTION_T_QUEST_EVENT_ALL = 26 // ACTION_T_QUEST_EVENT_ALL = 26
struct struct
{ {
uint32 questId; uint32 questId;
} quest_event_all; } quest_event_all;
// ACTION_T_CAST_EVENT_ALL = 27 // ACTION_T_CAST_EVENT_ALL = 27
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 spellId; uint32 spellId;
} cast_event_all; } cast_event_all;
// ACTION_T_REMOVEAURASFROMSPELL = 28 // ACTION_T_REMOVEAURASFROMSPELL = 28
struct struct
{ {
uint32 target; uint32 target;
uint32 spellId; uint32 spellId;
} remove_aura; } remove_aura;
// ACTION_T_RANGED_MOVEMENT = 29 // ACTION_T_RANGED_MOVEMENT = 29
struct struct
{ {
uint32 distance; uint32 distance;
int32 angle; int32 angle;
} ranged_movement; } ranged_movement;
// ACTION_T_RANDOM_PHASE = 30 // ACTION_T_RANDOM_PHASE = 30
struct struct
{ {
uint32 phase1; uint32 phase1;
uint32 phase2; uint32 phase2;
uint32 phase3; uint32 phase3;
} random_phase; } random_phase;
// ACTION_T_RANDOM_PHASE_RANGE = 31 // ACTION_T_RANDOM_PHASE_RANGE = 31
struct struct
{ {
uint32 phaseMin; uint32 phaseMin;
uint32 phaseMax; uint32 phaseMax;
} random_phase_range; } random_phase_range;
// ACTION_T_SUMMON_ID = 32 // ACTION_T_SUMMON_ID = 32
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 target; uint32 target;
uint32 spawnId; uint32 spawnId;
} summon_id; } summon_id;
// ACTION_T_KILLED_MONSTER = 33 // ACTION_T_KILLED_MONSTER = 33
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 target; uint32 target;
} killed_monster; } killed_monster;
// ACTION_T_SET_INST_DATA = 34 // ACTION_T_SET_INST_DATA = 34
struct struct
{ {
uint32 field; uint32 field;
uint32 value; uint32 value;
} set_inst_data; } set_inst_data;
// ACTION_T_SET_INST_DATA64 = 35 // ACTION_T_SET_INST_DATA64 = 35
struct struct
{ {
uint32 field; uint32 field;
uint32 target; uint32 target;
} set_inst_data64; } set_inst_data64;
// ACTION_T_UPDATE_TEMPLATE = 36 // ACTION_T_UPDATE_TEMPLATE = 36
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 team; uint32 team;
@ -364,6 +364,11 @@ struct CreatureEventAI_Action
{ {
uint32 radius; uint32 radius;
} call_for_help; } call_for_help;
// ACTION_T_SET_SHEATH = 40
struct
{
uint32 sheath;
} set_sheath;
// RAW // RAW
struct struct
{ {
@ -497,7 +502,7 @@ struct CreatureEventAI_Event
} receive_emote; } receive_emote;
// RAW // RAW
struct struct
{ {
uint32 param1; uint32 param1;
uint32 param2; uint32 param2;

View file

@ -641,6 +641,13 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.update_template.creatureId)) if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.update_template.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId);
break; break;
case ACTION_T_SET_SHEATH:
if (action.set_sheath.sheath >= MAX_SHEATH_STATE)
{
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses wrong sheath state %u.", i, j+1, action.set_sheath.sheath);
action.set_sheath.sheath = SHEATH_STATE_UNARMED;
}
break;
case ACTION_T_EVADE: //No Params case ACTION_T_EVADE: //No Params
case ACTION_T_FLEE_FOR_ASSIST: //No Params case ACTION_T_FLEE_FOR_ASSIST: //No Params
case ACTION_T_DIE: //No Params case ACTION_T_DIE: //No Params

View file

@ -926,10 +926,10 @@ namespace MaNGOS
return false; return false;
if(!u->CanAssistTo(i_obj,i_enemy)) if(!u->CanAssistTo(i_obj,i_enemy))
return false; return false;
if(!i_obj->IsWithinDistInMap(u, i_range)) if(!i_obj->IsWithinDistInMap(u, i_range))
return false; return false;
if(!i_obj->IsWithinLOSInMap(u)) if(!i_obj->IsWithinLOSInMap(u))
return false; return false;

View file

@ -2000,7 +2000,7 @@ bool ChatHandler::HandleTeleNameCommand(const char * args)
extractOptFirstArg((char*)args,&nameStr,&teleStr); extractOptFirstArg((char*)args,&nameStr,&teleStr);
if(!teleStr) if(!teleStr)
return false; return false;
Player* target; Player* target;
uint64 target_guid; uint64 target_guid;
std::string target_name; std::string target_name;

View file

@ -3170,7 +3170,7 @@ bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
bool ChatHandler::HandleGuildCreateCommand(const char* args) bool ChatHandler::HandleGuildCreateCommand(const char* args)
{ {
if(!*args) if(!*args)
return false; return false;
// if not guild name only (in "") then player name // if not guild name only (in "") then player name
Player* target; Player* target;
@ -3209,7 +3209,7 @@ bool ChatHandler::HandleGuildCreateCommand(const char* args)
bool ChatHandler::HandleGuildInviteCommand(const char *args) bool ChatHandler::HandleGuildInviteCommand(const char *args)
{ {
if(!*args) if(!*args)
return false; return false;
// if not guild name only (in "") then player name // if not guild name only (in "") then player name
uint64 target_guid; uint64 target_guid;

View file

@ -491,6 +491,12 @@ void ObjectMgr::LoadCreatureTemplates()
continue; continue;
} }
if(cInfo->unit_class != heroicInfo->unit_class)
{
sLog.outErrorDb("Creature (Entry: %u, class %u) has different `unit_class` in heroic mode (Entry: %u, class %u).",i, cInfo->unit_class, cInfo->HeroicEntry, heroicInfo->unit_class);
continue;
}
if(cInfo->npcflag != heroicInfo->npcflag) if(cInfo->npcflag != heroicInfo->npcflag)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `npcflag` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry); sLog.outErrorDb("Creature (Entry: %u) has different `npcflag` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry);
@ -552,6 +558,9 @@ void ObjectMgr::LoadCreatureTemplates()
if (!minfo) if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H); sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H);
if (cInfo->unit_class && ((1 << (cInfo->unit_class-1)) & CLASSMASK_ALL_CREATURES) == 0)
sLog.outErrorDb("Creature (Entry: %u) has invalid unit_class(%u) for creature_template", cInfo->Entry, cInfo->unit_class);
if(cInfo->dmgschool >= MAX_SPELL_SCHOOL) if(cInfo->dmgschool >= MAX_SPELL_SCHOOL)
{ {
sLog.outErrorDb("Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`",cInfo->Entry,cInfo->dmgschool); sLog.outErrorDb("Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`",cInfo->Entry,cInfo->dmgschool);

View file

@ -197,7 +197,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
break; break;
case HUNTER_PET: case HUNTER_PET:
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); SetSheath(SHEATH_STATE_MELEE);
SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED); SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
@ -783,7 +783,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
if(cinfo->type == CREATURE_TYPE_BEAST) if(cinfo->type == CREATURE_TYPE_BEAST)
{ {
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); SetSheath(SHEATH_STATE_MELEE);
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED)); SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));
} }
@ -1762,7 +1762,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint3
if(!InitEntry(Entry)) if(!InitEntry(Entry))
return false; return false;
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); SetSheath(SHEATH_STATE_MELEE);
if(getPetType() == MINI_PET) // always non-attackable if(getPetType() == MINI_PET) // always non-attackable
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);

View file

@ -7906,7 +7906,7 @@ void Player::SetVirtualItemSlot( uint8 i, Item* item)
} }
} }
void Player::SetSheath( uint32 sheathed ) void Player::SetSheath( SheathState sheathed )
{ {
switch (sheathed) switch (sheathed)
{ {
@ -7932,7 +7932,7 @@ void Player::SetSheath( uint32 sheathed )
SetVirtualItemSlot(2,NULL); SetVirtualItemSlot(2,NULL);
break; break;
} }
SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); // this must visualize Sheath changing for other players... Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players...
} }
uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const

View file

@ -1006,7 +1006,7 @@ class MANGOS_DLL_SPEC Player : public Unit
/*********************************************************/ /*********************************************************/
void SetVirtualItemSlot( uint8 i, Item* item); void SetVirtualItemSlot( uint8 i, Item* item);
void SetSheath( uint32 sheathed ); void SetSheath( SheathState sheathed ); // overwrite Unit version
uint8 FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const; uint8 FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const;
uint32 GetItemCount( uint32 item, bool inBankAlso = false, Item* skipItem = NULL ) const; uint32 GetItemCount( uint32 item, bool inBankAlso = false, Item* skipItem = NULL ) const;
Item* GetItemByGuid( uint64 guid ) const; Item* GetItemByGuid( uint64 guid ) const;

View file

@ -89,6 +89,8 @@ enum Classes
(1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \ (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \
(1<<(CLASS_DEATH_KNIGHT-1)) ) (1<<(CLASS_DEATH_KNIGHT-1)) )
#define CLASSMASK_ALL_CREATURES ((1<<(CLASS_WARRIOR-1)) | (1<<(CLASS_PALADIN-1)) | (1<<(CLASS_ROGUE-1)) | (1<<(CLASS_MAGE-1)) )
#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) #define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1)))
#define PLAYER_MAX_BATTLEGROUND_QUEUES 3 #define PLAYER_MAX_BATTLEGROUND_QUEUES 3

View file

@ -3222,8 +3222,9 @@ void Aura::HandleModCharm(bool apply, bool Real)
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{ {
//does not appear to have relevance. Why code added initially? See note below at !apply
//to prevent client crash //to prevent client crash
m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048); //m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
//just to enable stat window //just to enable stat window
charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
//if charmed two demons the same session, the 2nd gets the 1st one's name //if charmed two demons the same session, the 2nd gets the 1st one's name
@ -3261,11 +3262,13 @@ void Aura::HandleModCharm(bool apply, bool Real)
// restore UNIT_FIELD_BYTES_0 // restore UNIT_FIELD_BYTES_0
if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON) if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
{ {
CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon(); //does not appear to have relevance. Why code added initially? Class, gender, powertype should be same.
//db field removed and replaced with better way to set class, restore using this if problems
/*CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
if(cainfo && cainfo->bytes0 != 0) if(cainfo && cainfo->bytes0 != 0)
m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0); m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
else else
m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048); m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);*/
if(m_target->GetCharmInfo()) if(m_target->GetCharmInfo())
m_target->GetCharmInfo()->SetPetNumber(0, true); m_target->GetCharmInfo()->SetPetNumber(0, true);

View file

@ -796,18 +796,17 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND;
float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType);
float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
float base_pct = GetModifierValue(unitMod, BASE_PCT); float base_pct = GetModifierValue(unitMod, BASE_PCT);
float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT); float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
float dmg_multiplier = GetCreatureInfo()->dmg_multiplier;
float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct ; float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct * dmg_multiplier;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct ; float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct * dmg_multiplier;
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage);
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage);

View file

@ -10420,7 +10420,7 @@ bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate)
} }
} }
// or use empty slot in other case // or use empty slot in other case
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
{ {
if (!PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell()) if (!PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())

View file

@ -191,6 +191,8 @@ enum SheathState
SHEATH_STATE_RANGED = 2 // prepared ranged weapon SHEATH_STATE_RANGED = 2 // prepared ranged weapon
}; };
#define MAX_SHEATH_STATE 3
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 // byte (1 from 0..3) of UNIT_FIELD_BYTES_2
enum UnitBytes2_Flags enum UnitBytes2_Flags
{ {
@ -967,6 +969,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void ApplyAttackTimePercentMod(WeaponAttackType att,float val, bool apply); void ApplyAttackTimePercentMod(WeaponAttackType att,float val, bool apply);
void ApplyCastTimePercentMod(float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply);
SheathState GetSheath() const { return SheathState(GetByteValue(UNIT_FIELD_BYTES_2, 0)); }
virtual void SetSheath( SheathState sheathed ) { SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); }
// faction template id // faction template id
uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); } uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); }
void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction ); } void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction ); }

View file

@ -25,11 +25,11 @@ extern DatabasePostgre WorldDatabase;
extern DatabaseMysql WorldDatabase; extern DatabaseMysql WorldDatabase;
#endif #endif
const char CreatureInfosrcfmt[]="iiiiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiis"; const char CreatureInfosrcfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiis";
const char CreatureInfodstfmt[]="iiiiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiii"; const char CreatureInfodstfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiii";
const char CreatureDataAddonInfofmt[]="iiiiiiis"; const char CreatureDataAddonInfofmt[]="iiiiiis";
const char CreatureModelfmt[]="iffbi"; const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiiis"; const char CreatureInfoAddonInfofmt[]="iiiiiis";
const char EquipmentInfofmt[]="iiii"; const char EquipmentInfofmt[]="iiii";
const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiis";
const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiii";

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7903" #define REVISION_NR "7910"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__