[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

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