aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Creature.cpp43
-rw-r--r--src/game/Creature.h10
-rw-r--r--src/game/Object.cpp4
-rw-r--r--src/game/ObjectMgr.cpp73
-rw-r--r--src/game/QueryHandler.cpp8
-rw-r--r--src/game/SpellAuras.cpp3
-rw-r--r--src/game/Totem.cpp22
7 files changed, 93 insertions, 70 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 9ec48f9da90..f0b0023d696 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -94,6 +94,28 @@ VendorItem const* VendorItemData::FindItem(uint32 item_id) const
return NULL;
}
+uint32 CreatureInfo::GetRandomValidModelId() const
+{
+ uint32 c = 0;
+ uint32 modelIDs[4];
+
+ if (Modelid1) modelIDs[c++] = Modelid1;
+ if (Modelid2) modelIDs[c++] = Modelid2;
+ if (Modelid3) modelIDs[c++] = Modelid3;
+ if (Modelid4) modelIDs[c++] = Modelid4;
+
+ return ((c>0) ? modelIDs[urand(0,c-1)] : 0);
+}
+
+uint32 CreatureInfo::GetFirstValidModelId() const
+{
+ if(Modelid1) return Modelid1;
+ if(Modelid2) return Modelid2;
+ if(Modelid3) return Modelid3;
+ if(Modelid4) return Modelid4;
+ return 0;
+}
+
Creature::Creature() :
Unit(), i_AI(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
@@ -187,9 +209,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetUInt32Value(OBJECT_FIELD_ENTRY, Entry); // normal entry always
m_creatureInfo = cinfo; // map mode related always
- if (cinfo->DisplayID_A == 0 || cinfo->DisplayID_H == 0) // Cancel load if no model defined
+ // Cancel load if no model defined
+ if (!(cinfo->GetFirstValidModelId()))
{
- sLog.outErrorDb("Creature (Entry: %u) has no model defined for Horde or Alliance in table `creature_template`, can't load. ",Entry);
+ sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ",Entry);
return false;
}
@@ -1116,20 +1139,8 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
CreatureInfo const *cinfo = GetCreatureInfo();
if(cinfo)
{
- if(displayId != cinfo->DisplayID_A && displayId != cinfo->DisplayID_H)
- {
- CreatureModelInfo const *minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_A);
- if(!minfo || displayId != minfo->modelid_other_gender)
- {
- minfo = objmgr.GetCreatureModelInfo(cinfo->DisplayID_H);
- if(minfo && displayId == minfo->modelid_other_gender)
- displayId = 0;
- }
- else
- displayId = 0;
- }
- else
- displayId = 0;
+ if(displayId == cinfo->Modelid1 || displayId == cinfo->Modelid2 ||
+ displayId == cinfo->Modelid3 || displayId == cinfo->Modelid4) displayId = 0;
}
// data->guid = guid don't must be update at save
diff --git a/src/game/Creature.h b/src/game/Creature.h
index e74c250e83c..f8e51a58328 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -140,10 +140,10 @@ struct CreatureInfo
{
uint32 Entry;
uint32 HeroicEntry;
- uint32 DisplayID_A;
- uint32 DisplayID_A2;
- uint32 DisplayID_H;
- uint32 DisplayID_H2;
+ uint32 Modelid1;
+ uint32 Modelid2;
+ uint32 Modelid3;
+ uint32 Modelid4;
char* Name;
char* SubName;
char* IconName;
@@ -203,6 +203,8 @@ struct CreatureInfo
uint32 MechanicImmuneMask;
uint32 flags_extra;
char const* ScriptName;
+ uint32 GetRandomValidModelId() const;
+ uint32 GetFirstValidModelId() const;
};
struct CreatureLocale
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 2d6a5786471..834c958e662 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -601,9 +601,9 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if(cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
{
if(target->isGameMaster())
- *data << cinfo->DisplayID_A;
+ *data << cinfo->Modelid1;
else
- *data << cinfo->DisplayID_H;
+ *data << cinfo->Modelid3;
}
else
*data << m_uint32Values[ index ];
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index af452932456..0d290c26876 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -710,12 +710,27 @@ void ObjectMgr::LoadCreatureTemplates()
if(!factionTemplate)
sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
- CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A);
- if (!minfo)
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u)", cInfo->Entry, cInfo->DisplayID_A);
- minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H);
- if (!minfo)
- sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H);
+ // check model ids, supplying and sending non-existent ids to the client might crash them
+ if(!sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid1))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u), setting it to 0", cInfo->Entry, cInfo->Modelid1);
+ const_cast<CreatureInfo*>(cInfo)->Modelid1 = 0;
+ }
+ if(!sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid2))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid2);
+ const_cast<CreatureInfo*>(cInfo)->Modelid2 = 0;
+ }
+ if(!sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid3))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u), setting it to 0", cInfo->Entry, cInfo->Modelid3);
+ const_cast<CreatureInfo*>(cInfo)->Modelid3 = 0;
+ }
+ if(!sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid4))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid4);
+ const_cast<CreatureInfo*>(cInfo)->Modelid4 = 0;
+ }
if(cInfo->dmgschool >= MAX_SPELL_SCHOOL)
{
@@ -763,7 +778,8 @@ void ObjectMgr::LoadCreatureTemplates()
/// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
if(cInfo->scale <= 0.0f)
{
- CreatureDisplayInfoEntry const* ScaleEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A);
+ uint32 modelid = cInfo->GetFirstValidModelId();
+ CreatureDisplayInfoEntry const* ScaleEntry = sCreatureDisplayInfoStore.LookupEntry(modelid);
const_cast<CreatureInfo*>(cInfo)->scale = ScaleEntry ? ScaleEntry->scale : 1.0f;
}
}
@@ -904,17 +920,12 @@ CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
uint32 ObjectMgr::ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data)
{
// Load creature model (display id)
- uint32 display_id;
- if (!data || data->displayid == 0) // use defaults from the template
+ uint32 display_id = 0;
+
+ if (!data || data->displayid == 0) // use defaults from the template
{
- // 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;
- else
- display_id = (cinfo->DisplayID_A2 != 0 && urand(0,1) == 0) ? cinfo->DisplayID_A2 : cinfo->DisplayID_A;
- }
- else // overriden in creature data
- display_id = data->displayid;
+ display_id = cinfo->GetRandomValidModelId();
+ } else display_id = data->displayid; // overwritten from creature data
return display_id;
}
@@ -4599,25 +4610,23 @@ void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, ui
uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
{
- uint16 mount_entry = 0;
- uint16 mount_id = 0;
+ uint32 mount_entry = 0;
+ uint32 mount_id = 0;
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
- if(node)
+ if (node)
{
- if (team == ALLIANCE)
- {
- mount_entry = node->alliance_mount_type;
- CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
- if(ci)
- mount_id = ci->DisplayID_A;
- }
- if (team == HORDE)
+ if (team == ALLIANCE) mount_entry = node->alliance_mount_type;
+ else mount_entry = node->horde_mount_type;
+
+ CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry);
+ if (cinfo)
{
- mount_entry = node->horde_mount_type;
- CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
- if(ci)
- mount_id = ci->DisplayID_H;
+ if(! (mount_id = cinfo->GetRandomValidModelId()))
+ {
+ sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry);
+ return false;
+ }
}
}
diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp
index 50a44ee7a98..fe38ac2bdc7 100644
--- a/src/game/QueryHandler.cpp
+++ b/src/game/QueryHandler.cpp
@@ -187,10 +187,10 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
data << (uint32)ci->rank; // rank wdbFeild10
data << (uint32)0; // unknown wdbFeild11
data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12
- data << (uint32)ci->DisplayID_A; // modelid_male1
- data << (uint32)ci->DisplayID_H; // modelid_female1 ?
- data << (uint32)ci->DisplayID_A2; // modelid_male2 ?
- data << (uint32)ci->DisplayID_H2; // modelid_femmale2 ?
+ data << (uint32)ci->Modelid1; // Modelid1
+ data << (uint32)ci->Modelid2; // Modelid2
+ data << (uint32)ci->Modelid3; // Modelid3
+ data << (uint32)ci->Modelid4; // Modelid4
data << (float)1.0f; // unk
data << (float)1.0f; // unk
data << (uint8)ci->RacialLeader;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 7e255d25a62..31132246e3f 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -2696,8 +2696,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
else
{
- // Will use the default model here
- m_target->SetDisplayId(ci->DisplayID_A);
+ if (uint32 modelid = ci->GetRandomValidModelId()) m_target->SetDisplayId(modelid);
// Dragonmaw Illusion (set mount model also)
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index 077dec45cde..f1629d4e6a2 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -56,21 +56,23 @@ void Totem::Update( uint32 time )
void Totem::Summon(Unit* owner)
{
- sLog.outDebug("AddObject at Totem.cpp line 49");
-
- SetInstanceId(owner->GetInstanceId());
- owner->GetMap()->Add((Creature*)this);
-
- // select totem model in dependent from owner team
CreatureInfo const *cinfo = GetCreatureInfo();
- if(owner->GetTypeId()==TYPEID_PLAYER && cinfo)
+ if (owner->GetTypeId()==TYPEID_PLAYER && cinfo)
{
- if(((Player*)owner)->GetTeam()==HORDE)
- SetDisplayId(cinfo->DisplayID_H);
+ if (uint32 modelid = cinfo->GetRandomValidModelId())
+ SetDisplayId(modelid);
else
- SetDisplayId(cinfo->DisplayID_A);
+ {
+ sLog.outErrorDb("No displayid found for the totem with the entry %u! Can't summon it!", GetEntry());
+ return;
+ }
}
+ // Only add if a display exists.
+ sLog.outDebug("AddObject at Totem.cpp line 49");
+ SetInstanceId(owner->GetInstanceId());
+ owner->GetMap()->Add((Creature*)this);
+
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
data << GetGUID();
SendMessageToSet(&data,true);