mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[8015] More dislpay id selection fixes...
* Allow have only A2 or H2 display ids for less strincted DB field data. * Check model data existance for all provided display ids atserver startup. * Avoid explicit access to creature info display fields but use display selection functions. * Rename GetTaxiMount to more clear for returned value GetTaxiMountDisplayId. * Check display ids in `creature_model_info` at server load.
This commit is contained in:
parent
a1b941b059
commit
08fe4933c5
14 changed files with 169 additions and 122 deletions
|
|
@ -552,52 +552,75 @@ void ObjectMgr::LoadCreatureTemplates()
|
|||
sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
|
||||
|
||||
// used later for scale
|
||||
CreatureDisplayInfoEntry const* displayEntryA = cInfo->DisplayID_A ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A) : NULL;
|
||||
if (cInfo->DisplayID_A && !displayEntryA)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A);
|
||||
|
||||
if (cInfo->DisplayID_A2)
|
||||
CreatureDisplayInfoEntry const* displayScaleEntry = NULL;
|
||||
|
||||
if (cInfo->DisplayID_A[0])
|
||||
{
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A2);
|
||||
if (!displayEntry)
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[0]);
|
||||
if(!displayEntry)
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A2);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_A2 = 0;
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A[0]);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_A[0] = 0;
|
||||
}
|
||||
else if(!displayScaleEntry)
|
||||
displayScaleEntry = displayEntry;
|
||||
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[0]);
|
||||
if (!minfo)
|
||||
sLog.outErrorDb("Creature (Entry: %u) not has model data for DisplayID_A (%u)", cInfo->Entry, cInfo->DisplayID_A[0]);
|
||||
}
|
||||
|
||||
// used later for scale
|
||||
CreatureDisplayInfoEntry const* displayEntryH = cInfo->DisplayID_H ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H) : NULL;
|
||||
if (cInfo->DisplayID_H && !displayEntryH)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H);
|
||||
|
||||
if (cInfo->DisplayID_H2)
|
||||
if (cInfo->DisplayID_A[1])
|
||||
{
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H2);
|
||||
if (!displayEntry)
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[1]);
|
||||
if(!displayEntry)
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H2);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_H2 = 0;
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A[1]);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_A[1] = 0;
|
||||
}
|
||||
}
|
||||
else if(!displayScaleEntry)
|
||||
displayScaleEntry = displayEntry;
|
||||
|
||||
if (!displayEntryA && !displayEntryH)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing both DisplayID_A and DisplayID_H", cInfo->Entry);
|
||||
|
||||
if (cInfo->DisplayID_A)
|
||||
{
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A);
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[1]);
|
||||
if (!minfo)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u)", cInfo->Entry, cInfo->DisplayID_A);
|
||||
sLog.outErrorDb("Creature (Entry: %u) not has model data for DisplayID_A2 (%u)", cInfo->Entry, cInfo->DisplayID_A[1]);
|
||||
}
|
||||
|
||||
if (cInfo->DisplayID_H)
|
||||
if (cInfo->DisplayID_H[0])
|
||||
{
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H);
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H[0]);
|
||||
if(!displayEntry)
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H[0]);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_H[0] = 0;
|
||||
}
|
||||
else if(!displayScaleEntry)
|
||||
displayScaleEntry = displayEntry;
|
||||
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H[0]);
|
||||
if (!minfo)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H);
|
||||
sLog.outErrorDb("Creature (Entry: %u) not has model data for DisplayID_H (%u)", cInfo->Entry, cInfo->DisplayID_H[0]);
|
||||
}
|
||||
|
||||
if (cInfo->DisplayID_H[1])
|
||||
{
|
||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H[1]);
|
||||
if(!displayEntry)
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H[1]);
|
||||
const_cast<CreatureInfo*>(cInfo)->DisplayID_H[1] = 0;
|
||||
}
|
||||
else if(!displayScaleEntry)
|
||||
displayScaleEntry = displayEntry;
|
||||
|
||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H[1]);
|
||||
if (!minfo)
|
||||
sLog.outErrorDb("Creature (Entry: %u) not has model data for DisplayID_H2 (%u)", cInfo->Entry, cInfo->DisplayID_H[1]);
|
||||
}
|
||||
|
||||
if (!displayScaleEntry)
|
||||
sLog.outErrorDb("Creature (Entry: %u) not has any existed display id in DisplayID_A/DisplayID_A2/DisplayID_H/DisplayID_H2", cInfo->Entry);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -669,10 +692,8 @@ void ObjectMgr::LoadCreatureTemplates()
|
|||
/// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
|
||||
if(cInfo->scale <= 0.0f)
|
||||
{
|
||||
if(displayEntryA)
|
||||
const_cast<CreatureInfo*>(cInfo)->scale = displayEntryA->scale;
|
||||
else if(displayEntryH)
|
||||
const_cast<CreatureInfo*>(cInfo)->scale = displayEntryH->scale;
|
||||
if(displayScaleEntry)
|
||||
const_cast<CreatureInfo*>(cInfo)->scale = displayScaleEntry->scale;
|
||||
else
|
||||
const_cast<CreatureInfo*>(cInfo)->scale = 1.0f;
|
||||
}
|
||||
|
|
@ -874,33 +895,33 @@ 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 defaults from the template
|
||||
uint32 display_id;
|
||||
if (!data || data->displayid == 0) // use defaults from the template
|
||||
|
||||
// DisplayID_A is used if no team is given
|
||||
if (team == HORDE)
|
||||
{
|
||||
// DisplayID_A is used if no team is given
|
||||
if (team == HORDE)
|
||||
{
|
||||
display_id = (cinfo->DisplayID_H2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_H2 : cinfo->DisplayID_H;
|
||||
if(!display_id)
|
||||
{
|
||||
display_id = cinfo->DisplayID_A;
|
||||
if(!display_id)
|
||||
display_id = cinfo->DisplayID_A2;
|
||||
}
|
||||
}
|
||||
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_A2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_A2 : cinfo->DisplayID_A;
|
||||
if(!display_id)
|
||||
{
|
||||
display_id = cinfo->DisplayID_H;
|
||||
if(!display_id)
|
||||
display_id = cinfo->DisplayID_H2;
|
||||
}
|
||||
}
|
||||
display_id = cinfo->DisplayID_H[1];
|
||||
|
||||
if(!display_id)
|
||||
display_id = cinfo->DisplayID_A[0] ? cinfo->DisplayID_A[0] : cinfo->DisplayID_A[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
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];
|
||||
|
||||
if(!display_id)
|
||||
display_id = cinfo->DisplayID_H[0] ? cinfo->DisplayID_H[0] : cinfo->DisplayID_H[1];
|
||||
}
|
||||
else // overridden in creature data
|
||||
display_id = data->displayid;
|
||||
|
||||
return display_id;
|
||||
}
|
||||
|
|
@ -931,6 +952,29 @@ void ObjectMgr::LoadCreatureModelInfo()
|
|||
{
|
||||
sCreatureModelStorage.Load();
|
||||
|
||||
// post processing
|
||||
for(uint32 i = 1; i < sCreatureModelStorage.MaxEntry; ++i)
|
||||
{
|
||||
CreatureModelInfo const *minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(i);
|
||||
if (!minfo)
|
||||
continue;
|
||||
|
||||
if (!sCreatureDisplayInfoStore.LookupEntry(minfo->modelid))
|
||||
sLog.outErrorDb("Table `creature_model_info` has model for not existed display id (%u).", minfo->modelid);
|
||||
|
||||
if (minfo->gender > GENDER_NONE)
|
||||
{
|
||||
sLog.outErrorDb("Table `creature_model_info` has wrong gender (%u) for display 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);
|
||||
const_cast<CreatureModelInfo*>(minfo)->modelid_other_gender = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sLog.outString( ">> Loaded %u creature model based info", sCreatureModelStorage.RecordCount );
|
||||
sLog.outString();
|
||||
}
|
||||
|
|
@ -4809,7 +4853,7 @@ void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, ui
|
|||
path = dest_i->second.ID;
|
||||
}
|
||||
|
||||
uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /* = false */)
|
||||
uint32 ObjectMgr::GetTaxiMountDisplayId( uint32 id, uint32 team, bool allowed_alt_team /* = false */)
|
||||
{
|
||||
uint16 mount_entry = 0;
|
||||
|
||||
|
|
@ -4840,17 +4884,9 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /*
|
|||
if (!mount_id)
|
||||
return 0;
|
||||
|
||||
CreatureModelInfo const *minfo = GetCreatureModelInfo(mount_id);
|
||||
if (!minfo)
|
||||
{
|
||||
sLog.outErrorDb("Taxi mount (Entry: %u) for taxi node (Id: %u) for team %u has model %u not found in table `creature_model_info`, can't load. ",
|
||||
mount_entry,id,team,mount_id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (minfo->modelid_other_gender != 0)
|
||||
mount_id = urand(0,1) ? mount_id : minfo->modelid_other_gender;
|
||||
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(mount_id);
|
||||
if (minfo)
|
||||
mount_id = minfo->modelid;
|
||||
|
||||
return mount_id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue