mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +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
|
|
@ -752,7 +752,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||||
{
|
{
|
||||||
sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() );
|
sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() );
|
||||||
|
|
||||||
uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam(),true);
|
uint32 mountDisplayId = objmgr.GetTaxiMountDisplayId(sourceNode, pCurrChar->GetTeam(),true);
|
||||||
uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath();
|
uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath();
|
||||||
|
|
||||||
// search appropriate start path node
|
// search appropriate start path node
|
||||||
|
|
@ -794,7 +794,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendDoFlight( MountId, path, startNode );
|
SendDoFlight( mountDisplayId, path, startNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
|
// Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
|
||||||
|
|
|
||||||
|
|
@ -203,20 +203,20 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
|
||||||
// known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE
|
// known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE
|
||||||
SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
|
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
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has no model defined for Horde or Alliance in table `creature_template`, can't load. ",Entry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 display_id = objmgr.ChooseDisplayId(team, GetCreatureInfo(), data);
|
uint32 display_id = objmgr.ChooseDisplayId(team, GetCreatureInfo(), data);
|
||||||
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
|
if (!display_id) // Cancel load if no display id
|
||||||
if (!minfo)
|
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has model %u not found in table `creature_model_info`, can't load. ", Entry, display_id);
|
sLog.outErrorDb("Creature (Entry: %u) has model %u not found in table `creature_model_info`, can't load. ", Entry, display_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
|
||||||
|
if (!minfo) // Cancel load if no model defined
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ",Entry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
display_id = minfo->modelid; // it can be different (for another gender)
|
display_id = minfo->modelid; // it can be different (for another gender)
|
||||||
|
|
||||||
SetDisplayId(display_id);
|
SetDisplayId(display_id);
|
||||||
|
|
@ -1107,18 +1107,29 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||||
|
|
||||||
// check if it's a custom model and if not, use 0 for displayId
|
// check if it's a custom model and if not, use 0 for displayId
|
||||||
CreatureInfo const *cinfo = GetCreatureInfo();
|
CreatureInfo const *cinfo = GetCreatureInfo();
|
||||||
if(cinfo)
|
if (cinfo)
|
||||||
{
|
{
|
||||||
if(displayId != cinfo->DisplayID_A && displayId != cinfo->DisplayID_H)
|
if (displayId != cinfo->DisplayID_A[0] && displayId != cinfo->DisplayID_A[1] &&
|
||||||
|
displayId != cinfo->DisplayID_H[0] && displayId != cinfo->DisplayID_H[1])
|
||||||
{
|
{
|
||||||
CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_A);
|
if (cinfo->DisplayID_A[0])
|
||||||
if(!minfo || displayId != minfo->modelid_other_gender)
|
if (CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_A[0]))
|
||||||
{
|
if(displayId == minfo->modelid_other_gender)
|
||||||
minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_H);
|
|
||||||
if(minfo && displayId == minfo->modelid_other_gender)
|
|
||||||
displayId = 0;
|
displayId = 0;
|
||||||
}
|
|
||||||
else
|
if (displayId && cinfo->DisplayID_A[1])
|
||||||
|
if (CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_A[1]))
|
||||||
|
if(displayId == minfo->modelid_other_gender)
|
||||||
|
displayId = 0;
|
||||||
|
|
||||||
|
if (displayId && cinfo->DisplayID_H[0])
|
||||||
|
if (CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_H[0]))
|
||||||
|
if(displayId == minfo->modelid_other_gender)
|
||||||
|
displayId = 0;
|
||||||
|
|
||||||
|
if (displayId && cinfo->DisplayID_H[1])
|
||||||
|
if (CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_H[1]))
|
||||||
|
if(displayId == minfo->modelid_other_gender)
|
||||||
displayId = 0;
|
displayId = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,8 @@ struct CreatureInfo
|
||||||
uint32 HeroicEntry;
|
uint32 HeroicEntry;
|
||||||
uint32 unk1;
|
uint32 unk1;
|
||||||
uint32 unk2;
|
uint32 unk2;
|
||||||
uint32 DisplayID_A;
|
uint32 DisplayID_A[2];
|
||||||
uint32 DisplayID_A2;
|
uint32 DisplayID_H[2];
|
||||||
uint32 DisplayID_H;
|
|
||||||
uint32 DisplayID_H2;
|
|
||||||
char* Name;
|
char* Name;
|
||||||
char* SubName;
|
char* SubName;
|
||||||
char* IconName;
|
char* IconName;
|
||||||
|
|
|
||||||
|
|
@ -384,9 +384,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
||||||
{
|
{
|
||||||
if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatureId))
|
if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatureId))
|
||||||
{
|
{
|
||||||
//use default display
|
uint32 display_id = objmgr.ChooseDisplayId(0,ci);
|
||||||
if (ci->DisplayID_A)
|
m_creature->SetDisplayId(display_id);
|
||||||
m_creature->SetDisplayId(ci->DisplayID_A);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if no param1, then use value from param2 (modelId)
|
//if no param1, then use value from param2 (modelId)
|
||||||
|
|
|
||||||
|
|
@ -691,6 +691,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
|
||||||
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
|
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
|
||||||
if (minfo)
|
if (minfo)
|
||||||
display_id = minfo->modelid;
|
display_id = minfo->modelid;
|
||||||
|
|
||||||
if (data2->equipmentId == 0)
|
if (data2->equipmentId == 0)
|
||||||
itr->second.equipement_id_prev = cinfo->equipmentId;
|
itr->second.equipement_id_prev = cinfo->equipmentId;
|
||||||
else if (data2->equipmentId != -1)
|
else if (data2->equipmentId != -1)
|
||||||
|
|
|
||||||
|
|
@ -552,51 +552,74 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
|
sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
|
||||||
|
|
||||||
// used later for scale
|
// used later for scale
|
||||||
CreatureDisplayInfoEntry const* displayEntryA = cInfo->DisplayID_A ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A) : NULL;
|
CreatureDisplayInfoEntry const* displayScaleEntry = 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)
|
if (cInfo->DisplayID_A[0])
|
||||||
{
|
{
|
||||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A2);
|
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[0]);
|
||||||
if (!displayEntry)
|
if(!displayEntry)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A2);
|
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_A2 = 0;
|
const_cast<CreatureInfo*>(cInfo)->DisplayID_A[0] = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if(!displayScaleEntry)
|
||||||
|
displayScaleEntry = displayEntry;
|
||||||
|
|
||||||
// used later for scale
|
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[0]);
|
||||||
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)
|
|
||||||
{
|
|
||||||
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H2);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (!minfo)
|
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_A (%u)", cInfo->Entry, cInfo->DisplayID_A[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cInfo->DisplayID_H)
|
if (cInfo->DisplayID_A[1])
|
||||||
{
|
{
|
||||||
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H);
|
CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A[1]);
|
||||||
if (!minfo)
|
if(!displayEntry)
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H);
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A[1]);
|
||||||
|
if (!minfo)
|
||||||
|
sLog.outErrorDb("Creature (Entry: %u) not has model data for DisplayID_A2 (%u)", cInfo->Entry, cInfo->DisplayID_A[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cInfo->DisplayID_H[0])
|
||||||
|
{
|
||||||
|
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) 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)
|
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);
|
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 not set custom creature scale then load scale from CreatureDisplayInfo.dbc
|
||||||
if(cInfo->scale <= 0.0f)
|
if(cInfo->scale <= 0.0f)
|
||||||
{
|
{
|
||||||
if(displayEntryA)
|
if(displayScaleEntry)
|
||||||
const_cast<CreatureInfo*>(cInfo)->scale = displayEntryA->scale;
|
const_cast<CreatureInfo*>(cInfo)->scale = displayScaleEntry->scale;
|
||||||
else if(displayEntryH)
|
|
||||||
const_cast<CreatureInfo*>(cInfo)->scale = displayEntryH->scale;
|
|
||||||
else
|
else
|
||||||
const_cast<CreatureInfo*>(cInfo)->scale = 1.0f;
|
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*/)
|
uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data /*= NULL*/)
|
||||||
{
|
{
|
||||||
// Load creature model (display id)
|
// Load creature model (display id)
|
||||||
|
if (data && data->displayid)
|
||||||
|
return data->displayid;
|
||||||
|
|
||||||
|
// use defaults from the template
|
||||||
uint32 display_id;
|
uint32 display_id;
|
||||||
if (!data || data->displayid == 0) // use defaults from the template
|
|
||||||
{
|
|
||||||
// DisplayID_A is used if no team is given
|
// DisplayID_A is used if no team is given
|
||||||
if (team == HORDE)
|
if (team == HORDE)
|
||||||
{
|
{
|
||||||
display_id = (cinfo->DisplayID_H2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_H2 : cinfo->DisplayID_H;
|
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)
|
if(!display_id)
|
||||||
{
|
display_id = cinfo->DisplayID_A[0] ? cinfo->DisplayID_A[0] : cinfo->DisplayID_A[1];
|
||||||
display_id = cinfo->DisplayID_A;
|
|
||||||
if(!display_id)
|
|
||||||
display_id = cinfo->DisplayID_A2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
display_id = (cinfo->DisplayID_A2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_A2 : cinfo->DisplayID_A;
|
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)
|
if(!display_id)
|
||||||
{
|
display_id = cinfo->DisplayID_H[0] ? cinfo->DisplayID_H[0] : cinfo->DisplayID_H[1];
|
||||||
display_id = cinfo->DisplayID_H;
|
|
||||||
if(!display_id)
|
|
||||||
display_id = cinfo->DisplayID_H2;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else // overridden in creature data
|
|
||||||
display_id = data->displayid;
|
|
||||||
|
|
||||||
return display_id;
|
return display_id;
|
||||||
}
|
}
|
||||||
|
|
@ -931,6 +952,29 @@ void ObjectMgr::LoadCreatureModelInfo()
|
||||||
{
|
{
|
||||||
sCreatureModelStorage.Load();
|
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( ">> Loaded %u creature model based info", sCreatureModelStorage.RecordCount );
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
}
|
}
|
||||||
|
|
@ -4809,7 +4853,7 @@ void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, ui
|
||||||
path = dest_i->second.ID;
|
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;
|
uint16 mount_entry = 0;
|
||||||
|
|
||||||
|
|
@ -4840,17 +4884,9 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /*
|
||||||
if (!mount_id)
|
if (!mount_id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CreatureModelInfo const *minfo = GetCreatureModelInfo(mount_id);
|
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(mount_id);
|
||||||
if (!minfo)
|
if (minfo)
|
||||||
{
|
mount_id = minfo->modelid;
|
||||||
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;
|
|
||||||
|
|
||||||
return mount_id;
|
return mount_id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ class ObjectMgr
|
||||||
|
|
||||||
uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team );
|
uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team );
|
||||||
void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost);
|
void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost);
|
||||||
uint16 GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team = false);
|
uint32 GetTaxiMountDisplayId( uint32 id, uint32 team, bool allowed_alt_team = false);
|
||||||
void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds );
|
void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds );
|
||||||
void GetTransportPathNodes( uint32 path, TransportPath &pathnodes );
|
void GetTransportPathNodes( uint32 path, TransportPath &pathnodes );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't load taxi path without mount set (quest taxi path?)
|
// can't load taxi path without mount set (quest taxi path?)
|
||||||
if(!objmgr.GetTaxiMount(GetTaxiSource(),team,true))
|
if(!objmgr.GetTaxiMountDisplayId(GetTaxiSource(),team,true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -16915,10 +16915,10 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
|
||||||
}
|
}
|
||||||
|
|
||||||
// get mount model (in case non taximaster (npc==NULL) allow more wide lookup)
|
// get mount model (in case non taximaster (npc==NULL) allow more wide lookup)
|
||||||
uint16 mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), npc == NULL);
|
uint32 mount_display_id = objmgr.GetTaxiMountDisplayId(sourcenode, GetTeam(), npc == NULL);
|
||||||
|
|
||||||
// in spell case allow 0 model
|
// in spell case allow 0 model
|
||||||
if (mount_id == 0 && spellid == 0 || sourcepath == 0)
|
if (mount_display_id == 0 && spellid == 0 || sourcepath == 0)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
|
WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
|
||||||
data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR);
|
data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR);
|
||||||
|
|
@ -16955,7 +16955,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
|
||||||
|
|
||||||
sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY");
|
sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY");
|
||||||
|
|
||||||
GetSession()->SendDoFlight(mount_id, sourcepath);
|
GetSession()->SendDoFlight(mount_display_id, sourcepath);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,10 +187,10 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
|
||||||
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
|
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
|
||||||
data << uint32(ci->unk1); // new in 3.1, creature entry?
|
data << uint32(ci->unk1); // new in 3.1, creature entry?
|
||||||
data << uint32(ci->unk2); // new in 3.1, creature entry?
|
data << uint32(ci->unk2); // new in 3.1, creature entry?
|
||||||
data << uint32(ci->DisplayID_A); // modelid_male1
|
data << uint32(ci->DisplayID_A[0]); // modelid_male1
|
||||||
data << uint32(ci->DisplayID_H); // modelid_female1 ?
|
data << uint32(ci->DisplayID_H[0]); // modelid_female1 ?
|
||||||
data << uint32(ci->DisplayID_A2); // modelid_male2 ?
|
data << uint32(ci->DisplayID_A[1]); // modelid_male2 ?
|
||||||
data << uint32(ci->DisplayID_H2); // modelid_femmale2 ?
|
data << uint32(ci->DisplayID_H[1]); // modelid_femmale2 ?
|
||||||
data << float(ci->unk16); // unk
|
data << float(ci->unk16); // unk
|
||||||
data << float(ci->unk17); // unk
|
data << float(ci->unk17); // unk
|
||||||
data << uint8(ci->RacialLeader);
|
data << uint8(ci->RacialLeader);
|
||||||
|
|
|
||||||
|
|
@ -2857,7 +2857,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Will use the default model here
|
// Will use the default model here
|
||||||
m_target->SetDisplayId(ci->DisplayID_A);
|
m_target->SetDisplayId(ci->DisplayID_A[0]);
|
||||||
|
|
||||||
// Dragonmaw Illusion (set mount model also)
|
// Dragonmaw Illusion (set mount model also)
|
||||||
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
|
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
|
||||||
|
|
|
||||||
|
|
@ -117,17 +117,18 @@ void WorldSession::SendTaxiMenu( Creature* unit )
|
||||||
sLog.outDebug( "WORLD: Sent SMSG_SHOWTAXINODES" );
|
sLog.outDebug( "WORLD: Sent SMSG_SHOWTAXINODES" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode )
|
void WorldSession::SendDoFlight( uint32 mountDisplayId, uint32 path, uint32 pathNode )
|
||||||
{
|
{
|
||||||
// remove fake death
|
// remove fake death
|
||||||
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||||
|
|
||||||
while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
|
while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
|
||||||
GetPlayer()->GetMotionMaster()->MovementExpired(false);
|
GetPlayer()->GetMotionMaster()->MovementExpired(false);
|
||||||
|
|
||||||
if (MountId)
|
if (mountDisplayId)
|
||||||
GetPlayer()->Mount( MountId );
|
GetPlayer()->Mount( mountDisplayId );
|
||||||
|
|
||||||
GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path,pathNode);
|
GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path,pathNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,13 +242,13 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& /*recv_data*/)
|
||||||
|
|
||||||
sLog.outDebug( "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode );
|
sLog.outDebug( "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode );
|
||||||
|
|
||||||
uint16 MountId = objmgr.GetTaxiMount(sourcenode, GetPlayer()->GetTeam());
|
uint32 mountDisplayId = objmgr.GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam());
|
||||||
|
|
||||||
uint32 path, cost;
|
uint32 path, cost;
|
||||||
objmgr.GetTaxiPath( sourcenode, destinationnode, path, cost);
|
objmgr.GetTaxiPath( sourcenode, destinationnode, path, cost);
|
||||||
|
|
||||||
if(path && MountId)
|
if(path && mountDisplayId)
|
||||||
SendDoFlight( MountId, path, 1 ); // skip start fly node
|
SendDoFlight( mountDisplayId, path, 1 ); // skip start fly node
|
||||||
else
|
else
|
||||||
GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next
|
GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,11 @@ void Totem::Summon(Unit* owner)
|
||||||
CreatureInfo const *cinfo = GetCreatureInfo();
|
CreatureInfo const *cinfo = GetCreatureInfo();
|
||||||
if(owner->GetTypeId()==TYPEID_PLAYER && cinfo)
|
if(owner->GetTypeId()==TYPEID_PLAYER && cinfo)
|
||||||
{
|
{
|
||||||
if(((Player*)owner)->GetTeam()==HORDE)
|
uint32 display_id = objmgr.ChooseDisplayId(((Player*)owner)->GetTeam(),cinfo);
|
||||||
SetDisplayId(cinfo->DisplayID_H);
|
CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
|
||||||
else
|
if (minfo)
|
||||||
SetDisplayId(cinfo->DisplayID_A);
|
display_id = minfo->modelid;
|
||||||
|
SetDisplayId(display_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
|
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
//Taxi
|
//Taxi
|
||||||
void SendTaxiStatus( uint64 guid );
|
void SendTaxiStatus( uint64 guid );
|
||||||
void SendTaxiMenu( Creature* unit );
|
void SendTaxiMenu( Creature* unit );
|
||||||
void SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode = 0 );
|
void SendDoFlight( uint32 mountDisplayId, uint32 path, uint32 pathNode = 0 );
|
||||||
bool SendLearnNewTaxiNode( Creature* unit );
|
bool SendLearnNewTaxiNode( Creature* unit );
|
||||||
|
|
||||||
// Guild/Arena Team
|
// Guild/Arena Team
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8014"
|
#define REVISION_NR "8015"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue