private static void BuildActorMap(Dictionary <NameReference, ActorLookup> findActorMap, SeqTools.VarLinkInfo sourceLink, int newSourceLinkEntryUindex)
        {
            var         originalInfo = GetLookupInfo(sourceLink.LinkedNodes[0] as ExportEntry, sourceLink);
            ActorLookup lookupInfo   = GetLookupInfo(sourceLink.LinkedNodes[0].FileRef.GetUExport(newSourceLinkEntryUindex), sourceLink);

            if (lookupInfo != null && originalInfo != null && !lookupInfo.CouldNotResolve && !originalInfo.CouldNotResolve)
            {
                // Some dynamically set objects we won't be able to do. RIP
                // May make it return something so we can tell if we should randomize this conversation at all
                findActorMap[originalInfo.FindActor] = lookupInfo;
            }
        }
        private static ActorLookup GetLookupInfo(ExportEntry entry, SeqTools.VarLinkInfo varilink)
        {
            ActorLookup lookupInfo = new ActorLookup();

            if (entry.ClassName == "SeqVar_Player")
            {
                // We now look for 'Player'
                lookupInfo.FindActor = "Player";
                entry.WriteProperty(new BoolProperty(true, "bReturnPawns")); // This is required for moved links to work. So just always add it
            }
            else
            {
                if (varilink.LinkDesc.StartsWith("Node"))
                {
                    if (entry.ClassName == "BioSeqVar_ObjectFindByTag")
                    {
                        var tag = entry.GetProperty <StrProperty>("m_sObjectTagToFind");
                        if (tag != null)
                        {
                            lookupInfo.FindActor = tag.Value;
                        }
                        else
                        {
                            // ??
                            Debug.WriteLine("Could not find object by tag, tag was missing!");
                        }
                    }
                    else if (entry.ClassName == "SeqVar_Object")
                    {
                        // Pinned object.
                        var resolvedEntry = entry.GetProperty <ObjectProperty>("ObjValue")?.ResolveToEntry(entry.FileRef) as ExportEntry;
                        if (resolvedEntry != null)
                        {
                            // Look for it's tag and use that cause it's what will probably be used in the
                            // conversation
                            var tag = resolvedEntry.GetProperty <NameProperty>("Tag");
                            if (tag != null)
                            {
                                lookupInfo.FindActor = tag.Value;
                            }
                            else
                            {
                                //Debug.WriteLine("No tag on resolved object! Is it dynamic?");
                                //lookupInfo.FindActor = entry.GetProperty<NameProperty>("m_nmFindActor").Value; // keep the original value, I guess
                                lookupInfo.CouldNotResolve = true;
                            }
                        }
                        else
                        {
                            //Debug.WriteLine("Could not resolve object! Is it dynamic?");
                            //lookupInfo.FindActor = entry.GetProperty<NameProperty>("m_nmFindActor").Value; // keep the original value, I guess
                            lookupInfo.CouldNotResolve = true;
                        }
                    }
                    else if (entry.ClassName == "SeqVar_ScopedNamed")
                    {
                        // We have to find an object in the sequence that has the VarName
                        // What a dumb system
                        var findVarName = entry.GetProperty <NameProperty>("FindVarName");
                        if (findVarName == null)
                        {
                            Debugger.Break();
                        }

                        var seqObjs = SeqTools.GetAllSequenceElements(entry).OfType <ExportEntry>();
                        foreach (var seqObj in seqObjs)
                        {
                            var props   = seqObj.GetProperties();
                            var varname = props.GetProp <NameProperty>("VarName");
                            if (varname != null && varname.Value == findVarName.Value)
                            {
                                // Pinned object.
                                var resolvedEntry = props.GetProp <ObjectProperty>("ObjValue")?.ResolveToEntry(entry.FileRef) as ExportEntry;
                                if (resolvedEntry != null)
                                {
                                    // Look for it's tag and use that cause it's what will probably be used in the
                                    // conversation
                                    var tag = resolvedEntry.GetProperty <NameProperty>("Tag");
                                    if (tag != null)
                                    {
                                        lookupInfo.FindActor = tag.Value;
                                    }
                                    else
                                    {
                                        //Debug.WriteLine("No tag on resolved object! Is it dynamic?");
                                        //lookupInfo.FindActor = entry.GetProperty<NameProperty>("m_nmFindActor").Value; // keep the original value, I guess
                                        lookupInfo.CouldNotResolve = true;
                                    }
                                }
                                else
                                {
                                    //Debug.WriteLine("Could not resolve object! Is it dynamic?");
                                    //lookupInfo.FindActor = entry.GetProperty<NameProperty>("m_nmFindActor").Value; // keep the original value, I guess
                                    lookupInfo.CouldNotResolve = true;
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine($"Unknown type on Node convo item: {entry.ClassName}");
                    }
                }
                else
                {
                    switch (varilink.LinkDesc)
                    {
                    // We don't need to do owner as everything for Owner seems to be always pointing
                    // to the input of the SfxSeqAct_StartConversation
                    // So if we change it there, it... in theory should change
                    case "Owner":
                        lookupInfo.FindActor = "Owner";     // Special case. We should not change owner to something else. We should only update what owner now points to
                        // or something... this shit is so confusing
                        break;

                    case "Puppet1_1":
                        lookupInfo.FindActor = new NameReference("Pup1", 2);
                        lookupInfo.FindMode  = EActorTrackFindActorMode.ActorTrack_FindActorByNode;
                        break;

                    case "Puppet1_2":
                        lookupInfo.FindActor = new NameReference("Pup1", 3);
                        lookupInfo.FindMode  = EActorTrackFindActorMode.ActorTrack_FindActorByNode;
                        break;

                    case "Puppet2_1":
                        lookupInfo.FindActor = new NameReference("Pup2", 2);
                        lookupInfo.FindMode  = EActorTrackFindActorMode.ActorTrack_FindActorByNode;
                        break;

                    case "Puppet2_2":
                        lookupInfo.FindActor = new NameReference("Pup2", 3);
                        lookupInfo.FindMode  = EActorTrackFindActorMode.ActorTrack_FindActorByNode;
                        break;

                    default:
                        Debugger.Break();
                        break;
                    }
                }
            }

            return(lookupInfo);
        }