示例#1
0
        void AddActor(ObjectGuid actorGuid, ushort actorIdx)
        {
            ConversationActor actorField = m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors, actorIdx);

            SetUpdateFieldValue(ref actorField.ActorGUID, actorGuid);
            SetUpdateFieldValue(ref actorField.Type, ConversationActorType.WorldObjectActor);
        }
示例#2
0
        bool Create(ulong lowGuid, uint conversationEntry, Map map, Unit creator, Position pos, List <ObjectGuid> participants, SpellInfo spellInfo = null)
        {
            ConversationTemplate conversationTemplate = Global.ConversationDataStorage.GetConversationTemplate(conversationEntry);

            //ASSERT(conversationTemplate);

            _creatorGuid  = creator.GetGUID();
            _participants = participants;

            SetMap(map);
            Relocate(pos);

            _Create(ObjectGuid.Create(HighGuid.Conversation, GetMapId(), conversationEntry, lowGuid));
            PhasingHandler.InheritPhaseShift(this, creator);

            SetEntry(conversationEntry);
            SetObjectScale(1.0f);

            SetUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.LastLineEndTime), conversationTemplate.LastLineEndTime);
            _duration     = conversationTemplate.LastLineEndTime;
            _textureKitId = conversationTemplate.TextureKitId;

            for (ushort actorIndex = 0; actorIndex < conversationTemplate.Actors.Count; ++actorIndex)
            {
                ConversationActorTemplate actor = conversationTemplate.Actors[actorIndex];
                if (actor != null)
                {
                    ConversationActor actorField = new ConversationActor();
                    actorField.CreatureID            = actor.CreatureId;
                    actorField.CreatureDisplayInfoID = actor.CreatureModelId;
                    actorField.Type = ConversationActorType.CreatureActor;

                    AddDynamicUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Actors), actorField);
                }
            }

            for (ushort actorIndex = 0; actorIndex < conversationTemplate.ActorGuids.Count; ++actorIndex)
            {
                ulong actorGuid = conversationTemplate.ActorGuids[actorIndex];
                if (actorGuid == 0)
                {
                    continue;
                }

                foreach (var creature in map.GetCreatureBySpawnIdStore().LookupByKey(actorGuid))
                {
                    // we just need the last one, overriding is legit
                    AddActor(creature.GetGUID(), actorIndex);
                }
            }

            Global.ScriptMgr.OnConversationCreate(this, creator);

            List <ushort>           actorIndices = new List <ushort>();
            List <ConversationLine> lines        = new List <ConversationLine>();

            foreach (ConversationLineTemplate line in conversationTemplate.Lines)
            {
                actorIndices.Add(line.ActorIdx);

                ConversationLine lineField = new ConversationLine();
                lineField.ConversationLineID = line.Id;
                lineField.StartTime          = line.StartTime;
                lineField.UiCameraID         = line.UiCameraID;
                lineField.ActorIndex         = line.ActorIdx;
                lineField.Flags = line.Flags;

                lines.Add(lineField);
            }

            SetUpdateFieldValue(m_values.ModifyValue(m_conversationData).ModifyValue(m_conversationData.Lines), lines);

            Global.ScriptMgr.OnConversationCreate(this, creator);

            // All actors need to be set
            foreach (ushort actorIndex in actorIndices)
            {
                ConversationActor actor = actorIndex < m_conversationData.Actors.Size() ? m_conversationData.Actors[actorIndex] : null;
                if (actor == null || (actor.CreatureID == 0 && actor.ActorGUID.IsEmpty()))
                {
                    Log.outError(LogFilter.Conversation, $"Failed to create conversation (Id: {conversationEntry}) due to missing actor (Idx: {actorIndex}).");
                    return(false);
                }
            }

            if (!GetMap().AddToMap(this))
            {
                return(false);
            }

            return(true);
        }
        public void LoadConversationTemplates()
        {
            _conversationLineTemplateStorage.Clear();
            _conversationTemplateStorage.Clear();

            Dictionary <uint, ConversationActor[]> actorsByConversation     = new();
            Dictionary <uint, ulong[]>             actorGuidsByConversation = new();

            SQLResult lineTemplates = DB.World.Query("SELECT Id, UiCameraID, ActorIdx, Flags FROM conversation_line_template");

            if (!lineTemplates.IsEmpty())
            {
                uint oldMSTime = Time.GetMSTime();

                do
                {
                    uint id = lineTemplates.Read <uint>(0);

                    if (!CliDB.ConversationLineStorage.ContainsKey(id))
                    {
                        Log.outError(LogFilter.Sql, "Table `conversation_line_template` has template for non existing ConversationLine (ID: {0}), skipped", id);
                        continue;
                    }

                    ConversationLineTemplate conversationLine = new();
                    conversationLine.Id         = id;
                    conversationLine.UiCameraID = lineTemplates.Read <uint>(1);
                    conversationLine.ActorIdx   = lineTemplates.Read <byte>(2);
                    conversationLine.Flags      = lineTemplates.Read <byte>(3);

                    _conversationLineTemplateStorage[id] = conversationLine;
                }while (lineTemplates.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Conversation line templates in {1} ms", _conversationLineTemplateStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime));
            }
            else
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Conversation line templates. DB table `conversation_line_template` is empty.");
            }

            SQLResult actorResult = DB.World.Query("SELECT ConversationId, ConversationActorId, ConversationActorGuid, Idx, CreatureId, CreatureDisplayInfoId FROM conversation_actors");

            if (!actorResult.IsEmpty())
            {
                uint oldMSTime = Time.GetMSTime();
                uint count     = 0;

                do
                {
                    uint   conversationId        = actorResult.Read <uint>(0);
                    uint   actorId               = actorResult.Read <uint>(1);
                    ulong  actorGuid             = actorResult.Read <ulong>(2);
                    ushort idx                   = actorResult.Read <ushort>(3);
                    uint   creatureId            = actorResult.Read <uint>(4);
                    uint   creatureDisplayInfoId = actorResult.Read <uint>(5);

                    if (creatureId != 0 && actorGuid != 0)
                    {
                        Log.outError(LogFilter.Sql, $"Table `conversation_actors` references both actor (ID: {actorId}) and actorGuid (GUID: {actorGuid}) for Conversation {conversationId}, skipped.");
                        continue;
                    }

                    if (creatureId != 0)
                    {
                        if (creatureDisplayInfoId != 0)
                        {
                            ConversationActor conversationActor = new();
                            conversationActor.ActorId               = actorId;
                            conversationActor.CreatureId            = creatureId;
                            conversationActor.CreatureDisplayInfoId = creatureDisplayInfoId;

                            if (!actorsByConversation.ContainsKey(conversationId))
                            {
                                actorsByConversation[conversationId] = new ConversationActor[idx + 1];
                            }

                            ConversationActor[] actors = actorsByConversation[conversationId];
                            if (actors.Length <= idx)
                            {
                                Array.Resize(ref actors, idx + 1);
                            }

                            actors[idx] = conversationActor;
                            ++count;
                        }
                        else
                        {
                            Log.outError(LogFilter.Sql, $"Table `conversation_actors` references an actor (CreatureId: {creatureId}) without CreatureDisplayInfoId for Conversation {conversationId}, skipped");
                        }
                    }
                    else if (actorGuid != 0)
                    {
                        CreatureData creData = Global.ObjectMgr.GetCreatureData(actorGuid);
                        if (creData != null)
                        {
                            if (!actorGuidsByConversation.ContainsKey(conversationId))
                            {
                                actorGuidsByConversation[conversationId] = new ulong[idx + 1];
                            }

                            var guids = actorGuidsByConversation[conversationId];
                            if (guids.Length <= idx)
                            {
                                Array.Resize(ref guids, idx + 1);
                            }

                            guids[idx] = actorGuid;
                            ++count;
                        }
                        else
                        {
                            Log.outError(LogFilter.Sql, $"Table `conversation_actors` references an invalid creature guid (GUID: {actorGuid}) for Conversation {conversationId}, skipped");
                        }
                    }
                }while (actorResult.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Conversation actors in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }
            else
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Conversation actors. DB table `conversation_actors` is empty.");
            }

            SQLResult templateResult = DB.World.Query("SELECT Id, FirstLineId, TextureKitId, ScriptName FROM conversation_template");

            if (!templateResult.IsEmpty())
            {
                uint oldMSTime = Time.GetMSTime();

                do
                {
                    ConversationTemplate conversationTemplate = new();
                    conversationTemplate.Id           = templateResult.Read <uint>(0);
                    conversationTemplate.FirstLineId  = templateResult.Read <uint>(1);
                    conversationTemplate.TextureKitId = templateResult.Read <uint>(2);
                    conversationTemplate.ScriptId     = Global.ObjectMgr.GetScriptId(templateResult.Read <string>(3));

                    conversationTemplate.Actors     = actorsByConversation.TryGetValue(conversationTemplate.Id, out var actors) ? actors.ToList() : null;
                    conversationTemplate.ActorGuids = actorGuidsByConversation.TryGetValue(conversationTemplate.Id, out var actorGuids) ? actorGuids.ToList() : null;

                    ConversationLineRecord currentConversationLine = CliDB.ConversationLineStorage.LookupByKey(conversationTemplate.FirstLineId);
                    if (currentConversationLine == null)
                    {
                        Log.outError(LogFilter.Sql, "Table `conversation_template` references an invalid line (ID: {0}) for Conversation {1}, skipped", conversationTemplate.FirstLineId, conversationTemplate.Id);
                    }

                    while (currentConversationLine != null)
                    {
                        ConversationLineTemplate conversationLineTemplate = _conversationLineTemplateStorage.LookupByKey(currentConversationLine.Id);
                        if (conversationLineTemplate != null)
                        {
                            conversationTemplate.Lines.Add(conversationLineTemplate);
                        }
                        else
                        {
                            Log.outError(LogFilter.Sql, "Table `conversation_line_template` has missing template for line (ID: {0}) in Conversation {1}, skipped", currentConversationLine.Id, conversationTemplate.Id);
                        }

                        if (currentConversationLine.NextConversationLineID == 0)
                        {
                            break;
                        }

                        currentConversationLine = CliDB.ConversationLineStorage.LookupByKey(currentConversationLine.NextConversationLineID);
                    }

                    _conversationTemplateStorage[conversationTemplate.Id] = conversationTemplate;
                }while (templateResult.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Conversation templates in {1} ms", _conversationTemplateStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime));
            }
            else
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Conversation templates. DB table `conversation_template` is empty.");
            }
        }