Core/Unit: Update creature_template table and SMSG_CREATURE_QUERY_RESPONSE
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `creature_template` ADD `exp_unk` SMALLINT(2) NOT NULL DEFAULT '0' AFTER `exp`;
|
||||
ALTER TABLE `creature_template` ADD `type_flags2` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `type_flags`;
|
||||
@@ -95,6 +95,7 @@ struct CreatureTemplate
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
uint32 expansion;
|
||||
uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb
|
||||
uint32 faction_A;
|
||||
uint32 faction_H;
|
||||
uint32 npcflag;
|
||||
@@ -122,6 +123,7 @@ struct CreatureTemplate
|
||||
uint32 rangedattackpower;
|
||||
uint32 type; // enum CreatureType values
|
||||
uint32 type_flags; // enum CreatureTypeFlags mask values
|
||||
uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1)
|
||||
uint32 lootid;
|
||||
uint32 pickpocketLootId;
|
||||
uint32 SkinLootId;
|
||||
@@ -175,8 +177,8 @@ struct CreatureTemplate
|
||||
typedef UNORDERED_MAP<uint32, CreatureTemplate> CreatureTemplateContainer;
|
||||
|
||||
// Represents max amount of expansions.
|
||||
// TODO: Add MAX_EXPANSION constant.
|
||||
#define MAX_CREATURE_BASE_HP 3
|
||||
// TODO: Update to Cata, if required
|
||||
#define MAX_CREATURE_BASE_HP MAX_EXPANSION - 1
|
||||
|
||||
// Defines base stats for creatures (used to calculate HP/mana/armor).
|
||||
struct CreatureBaseStats
|
||||
|
||||
@@ -393,19 +393,19 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
|
||||
// 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
"modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, "
|
||||
// 22 23 24 25 26 27 28 29 30 31 32
|
||||
"scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, "
|
||||
// 33 34 35 36 37 38 39 40 41 42
|
||||
// 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
"modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, "
|
||||
// 22 23 24 25 26 27 28 29 30 31 32 33
|
||||
"speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, "
|
||||
// 34 35 36 37 38 39 40 41 42 43
|
||||
"dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, "
|
||||
// 43 44 45 46 47 48 49 50 51 52 53
|
||||
"type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, "
|
||||
// 54 55 56 57 58 59 60 61 62 63 64 65 66
|
||||
"spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
|
||||
// 67 68 69 70 71 72 73 74 75 76 77
|
||||
// 44 45 46 47 48 49 50 51 52 53 54
|
||||
"type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, "
|
||||
// 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
||||
"spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
|
||||
// 68 69 70 71 72 73 74 75 76 77 78
|
||||
"InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, "
|
||||
// 78 79 80 81 82 83
|
||||
// 79 80 81 82 83 84
|
||||
"movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName "
|
||||
"FROM creature_template;");
|
||||
|
||||
@@ -449,70 +449,66 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
creatureTemplate.minlevel = fields[14].GetUInt8();
|
||||
creatureTemplate.maxlevel = fields[15].GetUInt8();
|
||||
creatureTemplate.expansion = uint32(fields[16].GetUInt16());
|
||||
creatureTemplate.faction_A = uint32(fields[17].GetUInt16());
|
||||
creatureTemplate.faction_H = uint32(fields[18].GetUInt16());
|
||||
creatureTemplate.npcflag = fields[19].GetUInt32();
|
||||
creatureTemplate.speed_walk = fields[20].GetFloat();
|
||||
creatureTemplate.speed_run = fields[21].GetFloat();
|
||||
creatureTemplate.scale = fields[22].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[23].GetUInt8());
|
||||
creatureTemplate.mindmg = fields[24].GetFloat();
|
||||
creatureTemplate.maxdmg = fields[25].GetFloat();
|
||||
creatureTemplate.dmgschool = uint32(fields[26].GetInt8());
|
||||
creatureTemplate.attackpower = fields[27].GetUInt32();
|
||||
creatureTemplate.dmg_multiplier = fields[28].GetFloat();
|
||||
creatureTemplate.baseattacktime = fields[29].GetUInt32();
|
||||
creatureTemplate.rangeattacktime = fields[30].GetUInt32();
|
||||
creatureTemplate.unit_class = uint32(fields[31].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[32].GetUInt32();
|
||||
creatureTemplate.dynamicflags = fields[33].GetUInt32();
|
||||
creatureTemplate.family = uint32(fields[34].GetUInt8());
|
||||
creatureTemplate.trainer_type = uint32(fields[35].GetUInt8());
|
||||
creatureTemplate.trainer_spell = fields[36].GetUInt32();
|
||||
creatureTemplate.trainer_class = uint32(fields[37].GetUInt8());
|
||||
creatureTemplate.trainer_race = uint32(fields[38].GetUInt8());
|
||||
creatureTemplate.minrangedmg = fields[39].GetFloat();
|
||||
creatureTemplate.maxrangedmg = fields[40].GetFloat();
|
||||
creatureTemplate.rangedattackpower = uint32(fields[41].GetUInt16());
|
||||
creatureTemplate.type = uint32(fields[42].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[43].GetUInt32();
|
||||
creatureTemplate.lootid = fields[44].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[45].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[46].GetUInt32();
|
||||
creatureTemplate.expansionUnknown = uint32(fields[17].GetUInt16());
|
||||
creatureTemplate.faction_A = uint32(fields[18].GetUInt16());
|
||||
creatureTemplate.faction_H = uint32(fields[19].GetUInt16());
|
||||
creatureTemplate.npcflag = fields[20].GetUInt32();
|
||||
creatureTemplate.speed_walk = fields[21].GetFloat();
|
||||
creatureTemplate.speed_run = fields[22].GetFloat();
|
||||
creatureTemplate.scale = fields[23].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[24].GetUInt8());
|
||||
creatureTemplate.mindmg = fields[25].GetFloat();
|
||||
creatureTemplate.maxdmg = fields[26].GetFloat();
|
||||
creatureTemplate.dmgschool = uint32(fields[27].GetInt8());
|
||||
creatureTemplate.attackpower = fields[28].GetUInt32();
|
||||
creatureTemplate.dmg_multiplier = fields[29].GetFloat();
|
||||
creatureTemplate.baseattacktime = fields[30].GetUInt32();
|
||||
creatureTemplate.rangeattacktime = fields[31].GetUInt32();
|
||||
creatureTemplate.unit_class = uint32(fields[32].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[33].GetUInt32();
|
||||
creatureTemplate.dynamicflags = fields[34].GetUInt32();
|
||||
creatureTemplate.family = uint32(fields[35].GetUInt8());
|
||||
creatureTemplate.trainer_type = uint32(fields[36].GetUInt8());
|
||||
creatureTemplate.trainer_spell = fields[37].GetUInt32();
|
||||
creatureTemplate.trainer_class = uint32(fields[38].GetUInt8());
|
||||
creatureTemplate.trainer_race = uint32(fields[39].GetUInt8());
|
||||
creatureTemplate.minrangedmg = fields[40].GetFloat();
|
||||
creatureTemplate.maxrangedmg = fields[41].GetFloat();
|
||||
creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16());
|
||||
creatureTemplate.type = uint32(fields[43].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[44].GetUInt32();
|
||||
creatureTemplate.type_flags2 = fields[45].GetUInt32();
|
||||
creatureTemplate.lootid = fields[46].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[47].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[48].GetUInt32();
|
||||
|
||||
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
{
|
||||
creatureTemplate.resistance[i] = fields[47 + i -1].GetInt32();
|
||||
}
|
||||
creatureTemplate.resistance[i] = fields[50 + i -1].GetInt32();
|
||||
|
||||
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
||||
{
|
||||
creatureTemplate.spells[i] = fields[53 + i].GetUInt32();
|
||||
}
|
||||
creatureTemplate.spells[i] = fields[55 + i].GetUInt32();
|
||||
|
||||
creatureTemplate.PetSpellDataId = fields[61].GetUInt32();
|
||||
creatureTemplate.VehicleId = fields[62].GetUInt32();
|
||||
creatureTemplate.mingold = fields[63].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[64].GetUInt32();
|
||||
creatureTemplate.AIName = fields[65].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[66].GetUInt8());
|
||||
creatureTemplate.InhabitType = uint32(fields[67].GetUInt8());
|
||||
creatureTemplate.ModHealth = fields[68].GetFloat();
|
||||
creatureTemplate.ModMana = fields[69].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[70].GetFloat();
|
||||
creatureTemplate.RacialLeader = fields[71].GetBool();
|
||||
creatureTemplate.PetSpellDataId = fields[63].GetUInt32();
|
||||
creatureTemplate.VehicleId = fields[64].GetUInt32();
|
||||
creatureTemplate.mingold = fields[65].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[66].GetUInt32();
|
||||
creatureTemplate.AIName = fields[67].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[68].GetUInt8());
|
||||
creatureTemplate.InhabitType = uint32(fields[69].GetUInt8());
|
||||
creatureTemplate.ModHealth = fields[70].GetFloat();
|
||||
creatureTemplate.ModMana = fields[71].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[72].GetFloat();
|
||||
creatureTemplate.RacialLeader = fields[73].GetBool();
|
||||
|
||||
for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
|
||||
{
|
||||
creatureTemplate.questItems[i] = fields[72 + i].GetUInt32();
|
||||
}
|
||||
creatureTemplate.questItems[i] = fields[74 + i].GetUInt32();
|
||||
|
||||
creatureTemplate.movementId = fields[78].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[79].GetBool();
|
||||
creatureTemplate.equipmentId = fields[80].GetUInt32();
|
||||
creatureTemplate.MechanicImmuneMask = fields[81].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[82].GetUInt32();
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[83].GetCString());
|
||||
creatureTemplate.movementId = fields[80].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[81].GetBool();
|
||||
creatureTemplate.equipmentId = fields[82].GetUInt32();
|
||||
creatureTemplate.MechanicImmuneMask = fields[83].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[84].GetUInt32();
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[85].GetCString());
|
||||
|
||||
++count;
|
||||
}
|
||||
@@ -881,12 +877,18 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
|
||||
const_cast<CreatureTemplate*>(cInfo)->scale = 1.0f;
|
||||
}
|
||||
|
||||
if (cInfo->expansion > (MAX_CREATURE_BASE_HP - 1))
|
||||
if (cInfo->expansion > MAX_EXPANSION)
|
||||
{
|
||||
sLog->outErrorDb("Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
|
||||
sLog->outErrorDb("Table `creature_template` lists creature (Entry: %u) with `exp` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
|
||||
const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
|
||||
}
|
||||
|
||||
if (cInfo->expansionUnknown > MAX_EXPANSION)
|
||||
{
|
||||
sLog->outErrorDb("Table `creature_template` lists creature (Entry: %u) with `exp_unk` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansionUnknown);
|
||||
const_cast<CreatureTemplate*>(cInfo)->expansionUnknown = 0;
|
||||
}
|
||||
|
||||
if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED))
|
||||
{
|
||||
sLog->outErrorDb("Table `creature_template` lists creature (Entry: %u) with disallowed `flags_extra` %u, removing incorrect flag.", cInfo->Entry, badFlags);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "Define.h"
|
||||
#include <cassert>
|
||||
|
||||
#define MAX_EXPANSION 4
|
||||
|
||||
enum SpellEffIndex
|
||||
{
|
||||
EFFECT_0 = 0,
|
||||
@@ -33,14 +35,15 @@ enum SpellEffIndex
|
||||
#define EFFECT_FIRST_FOUND 254
|
||||
#define EFFECT_ALL 255
|
||||
|
||||
|
||||
// loot modes for creatures and gameobjects, bitmask!
|
||||
enum LootModes
|
||||
{
|
||||
LOOT_MODE_DEFAULT = 1,
|
||||
LOOT_MODE_HARD_MODE_1 = 2,
|
||||
LOOT_MODE_HARD_MODE_2 = 4,
|
||||
LOOT_MODE_HARD_MODE_3 = 8,
|
||||
LOOT_MODE_HARD_MODE_4 = 16
|
||||
LOOT_MODE_DEFAULT = 0x1,
|
||||
LOOT_MODE_HARD_MODE_1 = 0x2,
|
||||
LOOT_MODE_HARD_MODE_2 = 0x4,
|
||||
LOOT_MODE_HARD_MODE_3 = 0x8,
|
||||
LOOT_MODE_HARD_MODE_4 = 0x16
|
||||
};
|
||||
|
||||
enum Gender
|
||||
|
||||
@@ -128,10 +128,14 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
|
||||
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);
|
||||
data << uint32(entry); // creature entry
|
||||
data << Name;
|
||||
data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
data << uint8(0); // name2, ..., name8
|
||||
|
||||
data << SubName;
|
||||
data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
|
||||
data << uint32(ci->type_flags); // flags
|
||||
data << uint32(ci->type_flags2); // unknown meaning
|
||||
data << uint32(ci->type); // CreatureType.dbc
|
||||
data << uint32(ci->family); // CreatureFamily.dbc
|
||||
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
|
||||
@@ -147,6 +151,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
|
||||
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
|
||||
data << uint32(ci->questItems[i]); // itemId[6], quest drop
|
||||
data << uint32(ci->movementId); // CreatureMovementInfo.dbc
|
||||
data << uint32(ci->expansionUnknown); // unknown meaning
|
||||
SendPacket(&data);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user