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++)
@ -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;
// < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
std::string ext3 = path.size() >= 4 ? path.substr(path.size()-4,4) : "";
std::transform( ext3.begin(), ext3.end(), ext3.begin(), ::tolower );
if(ext3 == ".mdx")
{
// replace .mdx -> .m2
path.erase(path.length()-2,2); path.erase(path.length()-2,2);
path.append("2"); path.append("2");
char* szLocalFile[512]; }
sprintf((char*)szLocalFile, ".\\buildings\\%s", s); // >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
FILE * output = fopen((char*)szLocalFile,"rb"); // 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

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

@ -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)
{ {

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

@ -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);
// extract data
ExtractWmo();
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //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

@ -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

@ -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

@ -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,
}; };
@ -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
{ {

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

@ -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

@ -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__