[10289] Adjust creature models system

This change will:
* make it easier to use cached data directly without any modifications
* correct issues regarding invisible models
* simplify certain aspects of model selection itself and make it somehow easier to control and maintain special cases.

Two new fields added to creature_model_info, to store modelid_alternative and modelid_other_team
* _alternative holds an alt. model, for cases where gender are the same, or is not male/female.
* _other_team is generally used for totem models, but may have future use.

This commit will possibly break a few things (visually) and will require DB projects to update their creature_template models data.
It is advised to use cache data as-is, and in addition fill creature_model_info for certain models, totems in particular, for expected appearance.

Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
NoFantasy 2010-07-30 16:39:11 +02:00
parent 3099a99f9a
commit 2ae0badf48
15 changed files with 207 additions and 135 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_10286_01_mangos_creature_addon` bit(1) default NULL
`required_10289_02_mangos_creature_model_info` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -964,6 +964,8 @@ CREATE TABLE `creature_model_info` (
`combat_reach` float NOT NULL default '0',
`gender` tinyint(3) unsigned NOT NULL default '2',
`modelid_other_gender` mediumint(8) unsigned NOT NULL default '0',
`modelid_alternative` mediumint(8) unsigned NOT NULL default '0',
`modelid_other_team` mediumint(8) unsigned NOT NULL default '0',
PRIMARY KEY (`modelid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Creature System (Model related info)';
@ -974,27 +976,27 @@ CREATE TABLE `creature_model_info` (
LOCK TABLES `creature_model_info` WRITE;
/*!40000 ALTER TABLE `creature_model_info` DISABLE KEYS */;
INSERT INTO `creature_model_info` VALUES
(49, 0.3060, 1.5, 0, 50),
(50, 0.2080, 1.5, 1, 49),
(51, 0.3720, 1.5, 0, 52),
(52, 0.2360, 1.5, 1, 51),
(53, 0.3470, 1.5, 0, 54),
(54, 0.3470, 1.5, 1, 53),
(55, 0.3890, 1.5, 0, 56),
(56, 0.3060, 1.5, 1, 55),
(57, 0.3830, 1.5, 0, 58),
(58, 0.3830, 1.5, 1, 57),
(59, 0.9747, 1.5, 0, 60),
(60, 0.8725, 1.5, 1, 59),
(1478, 0.3060, 1.5, 0, 1479),
(1479, 0.3060, 1.5, 1, 1478),
(1563, 0.3519, 1.5, 0, 1564),
(1564, 0.3519, 1.5, 1, 1563),
(10045, 1.0000, 1.5, 2, 0),
(15475, 0.3830, 1.5, 1, 15476),
(15476, 0.3830, 1.5, 0, 15475),
(16125, 1.0000, 1.5, 0, 16126),
(16126, 1.0000, 1.5, 1, 16125);
(49, 0.3060, 1.5, 0, 50, 0, 0),
(50, 0.2080, 1.5, 1, 49, 0, 0),
(51, 0.3720, 1.5, 0, 52, 0, 0),
(52, 0.2360, 1.5, 1, 51, 0, 0),
(53, 0.3470, 1.5, 0, 54, 0, 0),
(54, 0.3470, 1.5, 1, 53, 0, 0),
(55, 0.3890, 1.5, 0, 56, 0, 0),
(56, 0.3060, 1.5, 1, 55, 0, 0),
(57, 0.3830, 1.5, 0, 58, 0, 0),
(58, 0.3830, 1.5, 1, 57, 0, 0),
(59, 0.9747, 1.5, 0, 60, 0, 0),
(60, 0.8725, 1.5, 1, 59, 0, 0),
(1478, 0.3060, 1.5, 0, 1479, 0, 0),
(1479, 0.3060, 1.5, 1, 1478, 0, 0),
(1563, 0.3519, 1.5, 0, 1564, 0, 0),
(1564, 0.3519, 1.5, 1, 1563, 0, 0),
(10045, 1.0000, 1.5, 2, 0, 0, 0),
(15475, 0.3830, 1.5, 1, 15476, 0, 0),
(15476, 0.3830, 1.5, 0, 15475, 0, 0),
(16125, 1.0000, 1.5, 0, 16126, 0, 0),
(16126, 1.0000, 1.5, 1, 16125, 0, 0);
/*!40000 ALTER TABLE `creature_model_info` ENABLE KEYS */;
UNLOCK TABLES;
@ -1146,10 +1148,10 @@ CREATE TABLE `creature_template` (
`difficulty_entry_3` mediumint(8) unsigned NOT NULL default '0',
`KillCredit1` int(11) unsigned NOT NULL default '0',
`KillCredit2` int(11) unsigned NOT NULL default '0',
`modelid_A` mediumint(8) unsigned NOT NULL default '0',
`modelid_A2` mediumint(8) unsigned NOT NULL default '0',
`modelid_H` mediumint(8) unsigned NOT NULL default '0',
`modelid_H2` mediumint(8) unsigned NOT NULL default '0',
`modelid_1` mediumint(8) unsigned NOT NULL default '0',
`modelid_2` mediumint(8) unsigned NOT NULL default '0',
`modelid_3` mediumint(8) unsigned NOT NULL default '0',
`modelid_4` mediumint(8) unsigned NOT NULL default '0',
`name` char(100) NOT NULL default '0',
`subname` char(100) default NULL,
`IconName` char(100) default NULL,
@ -1232,7 +1234,7 @@ CREATE TABLE `creature_template` (
LOCK TABLES `creature_template` WRITE;
/*!40000 ALTER TABLE `creature_template` DISABLE KEYS */;
INSERT INTO `creature_template` VALUES
(1,0,0,0,0,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,0,1,1,64,64,0,0,5,35,35,0,0.91,1.14286,1,0,2,3,0,10,1,2000,2200,8,4096,0,0,0,0,0,0,1,2,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1,1,0,0,0,0,0,0,0,0,1,0,0,130,'');
(1,0,0,0,0,0,10045,0,0,0,'Waypoint(Only GM can see it)','Visual',NULL,0,1,1,64,64,0,0,5,35,35,0,0.91,1.14286,1,0,2,3,0,10,1,2000,2200,8,4096,0,0,0,0,0,0,1,2,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1,1,0,0,0,0,0,0,0,0,1,0,0,130,'');
/*!40000 ALTER TABLE `creature_template` ENABLE KEYS */;
UNLOCK TABLES;

View file

@ -0,0 +1,8 @@
ALTER TABLE db_version CHANGE COLUMN required_10286_01_mangos_creature_addon required_10289_01_mangos_creature_template bit;
ALTER TABLE creature_template CHANGE COLUMN modelid_A modelid_1 mediumint(8) unsigned NOT NULL default '0';
ALTER TABLE creature_template CHANGE COLUMN modelid_A2 modelid_2 mediumint(8) unsigned NOT NULL default '0';
ALTER TABLE creature_template CHANGE COLUMN modelid_H modelid_3 mediumint(8) unsigned NOT NULL default '0';
ALTER TABLE creature_template CHANGE COLUMN modelid_H2 modelid_4 mediumint(8) unsigned NOT NULL default '0';
UPDATE creature_template SET modelid_3=0 WHERE entry=1;

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_10289_01_mangos_creature_template required_10289_02_mangos_creature_model_info bit;
ALTER TABLE creature_model_info ADD COLUMN modelid_alternative mediumint(8) unsigned NOT NULL default '0' AFTER modelid_other_gender;
ALTER TABLE creature_model_info ADD COLUMN modelid_other_team mediumint(8) unsigned NOT NULL default '0' AFTER modelid_alternative;

View file

@ -58,6 +58,8 @@ pkgdata_DATA = \
10263_03_mangos_pool_pool.sql \
10270_01_mangos_reputation_spillover_template.sql \
10286_01_mangos_creature_addon.sql \
10289_01_mangos_creature_template.sql \
10289_02_mangos_creature_model_info.sql \
README
## Additional files to include when running 'make dist'
@ -96,4 +98,6 @@ EXTRA_DIST = \
10263_03_mangos_pool_pool.sql \
10270_01_mangos_reputation_spillover_template.sql \
10286_01_mangos_creature_addon.sql \
10289_01_mangos_creature_template.sql \
10289_02_mangos_creature_model_info.sql \
README

View file

@ -245,9 +245,18 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
display_id = minfo->modelid; // it can be different (for another gender)
SetDisplayId(display_id);
SetNativeDisplayId(display_id);
// special case for totems (model for team==HORDE is stored in creature_template as the default)
if (team == ALLIANCE && cinfo->type == CREATURE_TYPE_TOTEM)
{
uint32 modelid_tmp = sObjectMgr.GetCreatureModelOtherTeamModel(display_id);
display_id = modelid_tmp ? modelid_tmp : display_id;
}
// normally the same as native, see above for the exeption
SetDisplayId(display_id);
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
// Load creature equipment
@ -929,27 +938,27 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
CreatureInfo const *cinfo = GetCreatureInfo();
if (cinfo)
{
if (displayId != cinfo->DisplayID_A[0] && displayId != cinfo->DisplayID_A[1] &&
displayId != cinfo->DisplayID_H[0] && displayId != cinfo->DisplayID_H[1])
if (displayId != cinfo->ModelId[0] && displayId != cinfo->ModelId[1] &&
displayId != cinfo->ModelId[2] && displayId != cinfo->ModelId[3])
{
if (cinfo->DisplayID_A[0])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->DisplayID_A[0]))
if(displayId == minfo->modelid_other_gender)
if (cinfo->ModelId[0])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->ModelId[0]))
if (displayId == minfo->modelid_other_gender)
displayId = 0;
if (displayId && cinfo->DisplayID_A[1])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->DisplayID_A[1]))
if(displayId == minfo->modelid_other_gender)
if (displayId && cinfo->ModelId[1])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->ModelId[1]))
if (displayId == minfo->modelid_other_gender)
displayId = 0;
if (displayId && cinfo->DisplayID_H[0])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->DisplayID_H[0]))
if(displayId == minfo->modelid_other_gender)
if (displayId && cinfo->ModelId[2])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->ModelId[2]))
if (displayId == minfo->modelid_other_gender)
displayId = 0;
if (displayId && cinfo->DisplayID_H[1])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->DisplayID_H[1]))
if(displayId == minfo->modelid_other_gender)
if (displayId && cinfo->ModelId[3])
if (CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelInfo(cinfo->ModelId[3]))
if (displayId == minfo->modelid_other_gender)
displayId = 0;
}
else
@ -960,7 +969,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.id = GetEntry();
data.mapid = mapid;
data.phaseMask = phaseMask;
data.displayid = displayId;
data.modelid_override = displayId;
data.equipmentId = GetEquipmentId();
data.posX = GetPositionX();
data.posY = GetPositionY();

View file

@ -66,8 +66,7 @@ struct CreatureInfo
uint32 Entry;
uint32 DifficultyEntry[MAX_DIFFICULTY - 1];
uint32 KillCredit[MAX_KILL_CREDIT];
uint32 DisplayID_A[2];
uint32 DisplayID_H[2];
uint32 ModelId[4];
char* Name;
char* SubName;
char* IconName;
@ -190,7 +189,7 @@ struct CreatureData
uint32 id; // entry in creature_template
uint16 mapid;
uint16 phaseMask;
uint32 displayid;
uint32 modelid_override; // overrides any model defined in creature_template
int32 equipmentId;
float posX;
float posY;
@ -230,7 +229,9 @@ struct CreatureModelInfo
float bounding_radius;
float combat_reach;
uint8 gender;
uint32 modelid_other_gender;
uint32 modelid_other_gender; // The oposite gender for this modelid (male/female)
uint32 modelid_alternative; // An alternative model. Generally same gender(2)
uint32 modelid_other_team; // The oposite team. Generally for alliance totem
};
enum InhabitTypeValues

View file

@ -779,12 +779,12 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
CreatureData& data2 = sObjectMgr.NewOrExistCreatureData(itr->first);
if (activate)
{
data2.displayid = itr->second.modelid;
data2.modelid_override = itr->second.modelid;
data2.equipmentId = itr->second.equipment_id;
}
else
{
data2.displayid = itr->second.modelid_prev;
data2.modelid_override = itr->second.modelid_prev;
data2.equipmentId = itr->second.equipement_id_prev;
}
}

View file

@ -592,72 +592,72 @@ void ObjectMgr::LoadCreatureTemplates()
// used later for scale
CreatureDisplayInfoEntry const* displayScaleEntry = NULL;
if (cInfo->DisplayID_A[0])
if (cInfo->ModelId[0])
{
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[0]);
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->ModelId[0]);
if(!displayEntry)
{
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_A (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A[0]);
const_cast<CreatureInfo*>(cInfo)->DisplayID_A[0] = 0;
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_1 (%u), can crash client", cInfo->Entry, cInfo->ModelId[0]);
const_cast<CreatureInfo*>(cInfo)->ModelId[0] = 0;
}
else if(!displayScaleEntry)
displayScaleEntry = displayEntry;
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[0]);
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->ModelId[0]);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) are using modelid_A (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->DisplayID_A[0]);
sLog.outErrorDb("Creature (Entry: %u) are using modelid_1 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->ModelId[0]);
}
if (cInfo->DisplayID_A[1])
if (cInfo->ModelId[1])
{
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[1]);
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->ModelId[1]);
if(!displayEntry)
{
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_A2 (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A[1]);
const_cast<CreatureInfo*>(cInfo)->DisplayID_A[1] = 0;
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_2 (%u), can crash client", cInfo->Entry, cInfo->ModelId[1]);
const_cast<CreatureInfo*>(cInfo)->ModelId[1] = 0;
}
else if(!displayScaleEntry)
displayScaleEntry = displayEntry;
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[1]);
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->ModelId[1]);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) are using modelid_A2 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->DisplayID_A[1]);
sLog.outErrorDb("Creature (Entry: %u) are using modelid_2 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->ModelId[1]);
}
if (cInfo->DisplayID_H[0])
if (cInfo->ModelId[2])
{
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H[0]);
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->ModelId[2]);
if(!displayEntry)
{
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_H (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H[0]);
const_cast<CreatureInfo*>(cInfo)->DisplayID_H[0] = 0;
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_3 (%u), can crash client", cInfo->Entry, cInfo->ModelId[2]);
const_cast<CreatureInfo*>(cInfo)->ModelId[2] = 0;
}
else if(!displayScaleEntry)
displayScaleEntry = displayEntry;
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H[0]);
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->ModelId[2]);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) are using modelid_H (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->DisplayID_H[0]);
sLog.outErrorDb("Creature (Entry: %u) are using modelid_3 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->ModelId[2]);
}
if (cInfo->DisplayID_H[1])
if (cInfo->ModelId[3])
{
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H[1]);
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->ModelId[3]);
if(!displayEntry)
{
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_H2 (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H[1]);
const_cast<CreatureInfo*>(cInfo)->DisplayID_H[1] = 0;
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid_4 (%u), can crash client", cInfo->Entry, cInfo->ModelId[3]);
const_cast<CreatureInfo*>(cInfo)->ModelId[3] = 0;
}
else if(!displayScaleEntry)
displayScaleEntry = displayEntry;
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H[1]);
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->ModelId[3]);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) are using modelid_H2 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->DisplayID_H[1]);
sLog.outErrorDb("Creature (Entry: %u) are using modelid_4 (%u), but creature_model_info are missing for this model.", cInfo->Entry, cInfo->ModelId[3]);
}
if (!displayScaleEntry)
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid in modelid_A/modelid_A2/modelid_H/modelid_A2", cInfo->Entry);
sLog.outErrorDb("Creature (Entry: %u) has nonexistent modelid in modelid_1/modelid_2/modelid_3/modelid_4", cInfo->Entry);
for(int k = 0; k < MAX_KILL_CREDIT; ++k)
{
@ -949,38 +949,73 @@ CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data /*= NULL*/)
{
// Load creature model (display id)
if (data && data->displayid)
return data->displayid;
// Use creature model explicit, override template (creature.modelid)
if (data && data->modelid_override)
return data->modelid_override;
// use defaults from the template
uint32 display_id;
uint32 display_id = 0;
// DisplayID_A is used if no team is given
if (team == HORDE)
// models may be categorized as (in this order):
// if mod4 && mod3 && mod2 && mod1 use any, by 25%-chance (other gender is selected and replaced after this function)
// if mod3 && mod2 && mod1 use mod3 unless mod2 has modelid_alt_model (then all by 33%-chance)
// if mod2 use mod2 unless mod2 has modelid_alt_model (then both by 50%-chance)
// if mod1 use mod1
// model selected here may be replaced with other_gender using own function
if (cinfo->ModelId[3] && cinfo->ModelId[2] && cinfo->ModelId[1] && cinfo->ModelId[0])
{
if(cinfo->DisplayID_H[0])
display_id = cinfo->DisplayID_H[1] ? cinfo->DisplayID_H[urand(0,1)] : cinfo->DisplayID_H[0];
else
display_id = cinfo->DisplayID_H[1];
if(!display_id)
display_id = cinfo->DisplayID_A[0] ? cinfo->DisplayID_A[0] : cinfo->DisplayID_A[1];
display_id = cinfo->ModelId[urand(0,3)];
}
else
else if (cinfo->ModelId[2] && cinfo->ModelId[1] && cinfo->ModelId[0])
{
if(cinfo->DisplayID_A[0])
display_id = cinfo->DisplayID_A[1] ? cinfo->DisplayID_A[urand(0,1)] : cinfo->DisplayID_A[0];
else
display_id = cinfo->DisplayID_A[1];
uint32 modelid_tmp = GetCreatureModelAlternativeModel(cinfo->ModelId[1]);
display_id = modelid_tmp ? cinfo->ModelId[urand(0,2)] : cinfo->ModelId[2];
}
else if (cinfo->ModelId[1])
{
// We use this to eliminate invisible models vs. "dummy" models (infernals, etc).
// Where it's expected to select one of two, model must have a alternative model defined (alternative model is normally the same as defined in ModelId1).
// Same pattern is used in the above model selection, but the result may be ModelId3 and not ModelId2 as here.
uint32 modelid_tmp = GetCreatureModelAlternativeModel(cinfo->ModelId[1]);
display_id = modelid_tmp ? modelid_tmp : cinfo->ModelId[1];
}
else if (cinfo->ModelId[0])
{
display_id = cinfo->ModelId[0];
}
if(!display_id)
display_id = cinfo->DisplayID_H[0] ? cinfo->DisplayID_H[0] : cinfo->DisplayID_H[1];
// fail safe, we use creature entry 1 and make error
if (!display_id)
{
sLog.outErrorDb("Call customer support, ChooseDisplayId can not select native model for creature entry %u, model from creature entry 1 will be used instead.", cinfo->Entry);
if (const CreatureInfo *creatureDefault = GetCreatureTemplate(1))
display_id = creatureDefault->ModelId[0];
}
return display_id;
}
// generally models that does not have a gender(2), or has alternative model for same gender
uint32 ObjectMgr::GetCreatureModelAlternativeModel(uint32 modelId)
{
if (const CreatureModelInfo *modelInfo = GetCreatureModelInfo(modelId))
return modelInfo->modelid_alternative;
return 0;
}
// generally for models having another model for the other team (totems)
uint32 ObjectMgr::GetCreatureModelOtherTeamModel(uint32 modelId)
{
if (const CreatureModelInfo *modelInfo = GetCreatureModelInfo(modelId))
return modelInfo->modelid_other_team;
return 0;
}
CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32 display_id)
{
CreatureModelInfo const *minfo = GetCreatureModelInfo(display_id);
@ -1015,19 +1050,31 @@ void ObjectMgr::LoadCreatureModelInfo()
continue;
if (!sCreatureDisplayInfoStore.LookupEntry(minfo->modelid))
sLog.outErrorDb("Table `creature_model_info` has model for not existed display id (%u).", minfo->modelid);
sLog.outErrorDb("Table `creature_model_info` has model for nonexistent model id (%u).", minfo->modelid);
if (minfo->gender >= MAX_GENDER)
{
sLog.outErrorDb("Table `creature_model_info` has wrong gender (%u) for display id (%u).", uint32(minfo->gender), minfo->modelid);
sLog.outErrorDb("Table `creature_model_info` has invalid gender (%u) for model id (%u).", uint32(minfo->gender), minfo->modelid);
const_cast<CreatureModelInfo*>(minfo)->gender = GENDER_MALE;
}
if (minfo->modelid_other_gender && !sCreatureDisplayInfoStore.LookupEntry(minfo->modelid_other_gender))
{
sLog.outErrorDb("Table `creature_model_info` has not existed alt.gender model (%u) for existed display id (%u).", minfo->modelid_other_gender, minfo->modelid);
sLog.outErrorDb("Table `creature_model_info` has nonexistent modelid_other_gender model (%u) defined for model id %u.", minfo->modelid_other_gender, minfo->modelid);
const_cast<CreatureModelInfo*>(minfo)->modelid_other_gender = 0;
}
if (minfo->modelid_alternative && !sCreatureDisplayInfoStore.LookupEntry(minfo->modelid_alternative))
{
sLog.outErrorDb("Table `creature_model_info` has nonexistent modelid_alternative model (%u) defined for model id %u.", minfo->modelid_alternative, minfo->modelid);
const_cast<CreatureModelInfo*>(minfo)->modelid_alternative = 0;
}
if (minfo->modelid_other_team && !sCreatureDisplayInfoStore.LookupEntry(minfo->modelid_other_team))
{
sLog.outErrorDb("Table `creature_model_info` has nonexistent modelid_other_team model (%u) defined for model id %u.", minfo->modelid_other_team, minfo->modelid);
const_cast<CreatureModelInfo*>(minfo)->modelid_other_team = 0;
}
}
// character races expected have model info data in table
@ -1150,25 +1197,25 @@ void ObjectMgr::LoadCreatures()
CreatureData& data = mCreatureDataMap[guid];
data.id = entry;
data.mapid = fields[ 2].GetUInt32();
data.displayid = fields[ 3].GetUInt32();
data.equipmentId = fields[ 4].GetUInt32();
data.posX = fields[ 5].GetFloat();
data.posY = fields[ 6].GetFloat();
data.posZ = fields[ 7].GetFloat();
data.orientation = fields[ 8].GetFloat();
data.spawntimesecs = fields[ 9].GetUInt32();
data.spawndist = fields[10].GetFloat();
data.currentwaypoint= fields[11].GetUInt32();
data.curhealth = fields[12].GetUInt32();
data.curmana = fields[13].GetUInt32();
data.is_dead = fields[14].GetBool();
data.movementType = fields[15].GetUInt8();
data.spawnMask = fields[16].GetUInt8();
data.phaseMask = fields[17].GetUInt16();
int16 gameEvent = fields[18].GetInt16();
int16 PoolId = fields[19].GetInt16();
data.id = entry;
data.mapid = fields[ 2].GetUInt32();
data.modelid_override = fields[ 3].GetUInt32();
data.equipmentId = fields[ 4].GetUInt32();
data.posX = fields[ 5].GetFloat();
data.posY = fields[ 6].GetFloat();
data.posZ = fields[ 7].GetFloat();
data.orientation = fields[ 8].GetFloat();
data.spawntimesecs = fields[ 9].GetUInt32();
data.spawndist = fields[10].GetFloat();
data.currentwaypoint = fields[11].GetUInt32();
data.curhealth = fields[12].GetUInt32();
data.curmana = fields[13].GetUInt32();
data.is_dead = fields[14].GetBool();
data.movementType = fields[15].GetUInt8();
data.spawnMask = fields[16].GetUInt8();
data.phaseMask = fields[17].GetUInt16();
int16 gameEvent = fields[18].GetInt16();
int16 PoolId = fields[19].GetInt16();
MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
if(!mapEntry)
@ -1193,6 +1240,12 @@ void ObjectMgr::LoadCreatures()
if (!ok)
continue;
if (data.modelid_override > 0 && !sCreatureDisplayInfoStore.LookupEntry(data.modelid_override))
{
sLog.outErrorDb("Table `creature` GUID %u (entry %u) has model for nonexistent model id (%u), set to 0.", guid, data.id, data.modelid_override);
data.modelid_override = 0;
}
if(data.equipmentId > 0) // -1 no equipment, 0 use default
{
if(!GetEquipmentInfo(data.equipmentId))

View file

@ -518,6 +518,8 @@ class ObjectMgr
static CreatureInfo const *GetCreatureTemplate( uint32 id );
CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
CreatureModelInfo const* GetCreatureModelRandomGender(uint32 display_id);
uint32 GetCreatureModelAlternativeModel(uint32 modelId);
uint32 GetCreatureModelOtherTeamModel(uint32 modelId);
uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data = NULL);
EquipmentInfo const *GetEquipmentInfo( uint32 entry );
static CreatureDataAddon const *GetCreatureAddon( uint32 lowguid )

View file

@ -184,10 +184,10 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit
data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit
data << uint32(ci->DisplayID_A[0]); // modelid_male1
data << uint32(ci->DisplayID_H[0]); // modelid_female1 ?
data << uint32(ci->DisplayID_A[1]); // modelid_male2 ?
data << uint32(ci->DisplayID_H[1]); // modelid_femmale2 ?
data << uint32(ci->ModelId[0]); //
data << uint32(ci->ModelId[1]); //
data << uint32(ci->ModelId[2]); //
data << uint32(ci->ModelId[3]); //
data << float(ci->unk16); // unk
data << float(ci->unk17); // unk
data << uint8(ci->RacialLeader);

View file

@ -3076,7 +3076,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
}
else
model_id = ci->DisplayID_A[0]; // Will use the default model here
model_id = sObjectMgr.ChooseDisplayId(0,ci);// Will use the default model here
// Polymorph (sheep/penguin case)
if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto()->SpellIconID == 82)

View file

@ -55,17 +55,6 @@ void Totem::Summon(Unit* owner)
{
owner->GetMap()->Add((Creature*)this);
// select totem model in dependent from owner team
CreatureInfo const *cinfo = GetCreatureInfo();
if(owner->GetTypeId() == TYPEID_PLAYER && cinfo)
{
uint32 display_id = sObjectMgr.ChooseDisplayId(((Player*)owner)->GetTeam(), cinfo);
CreatureModelInfo const *minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
if (minfo)
display_id = minfo->modelid;
SetDisplayId(display_id);
}
AIM_Initialize();
if (owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->AI())

View file

@ -28,7 +28,7 @@ extern DatabaseMysql WorldDatabase;
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis";
const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii";
const char CreatureDataAddonInfofmt[]="iiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureModelfmt[]="iffbiii";
const char CreatureInfoAddonInfofmt[]="iiiiiis";
const char EquipmentInfofmt[]="iiii";
const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis";

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10288"
#define REVISION_NR "10289"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10254_01_characters_auctionhouse"
#define REVISION_DB_MANGOS "required_10286_01_mangos_creature_addon"
#define REVISION_DB_MANGOS "required_10289_02_mangos_creature_model_info"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__