private void AddDataEntry(IResourceEntry entry)
        {
            var data = (IResourceData)entry;

            DataEntryTable.AddEntry(data);
            DataTable.Add(data.Contents);
        }
Exemple #2
0
        public Stream GetTextFileStream(string file, bool write)
        {
            if (NWN2ToolsetMainForm.App.Module == null)
            {
                throw new InvalidOperationException("Module not open.");
            }
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (file == String.Empty)
            {
                throw new ArgumentException("File name cannot be empty.", "file");
            }

            OEIResRef resRef = new OEIResRef(file);

            IResourceEntry resource = NWN2ToolsetMainForm.App.Module.Repository.FindResource(resRef, txtCode);

            if (resource == null)
            {
                throw new ApplicationException("Failed to retrieve resource.");
            }

            return(resource.GetStream(write));
        }
Exemple #3
0
        /// <summary>
        /// Creates a text file in the current module under the given name.
        /// </summary>
        /// <param name="file">The name to create a file under.</param>
        /// <remarks>MUST save the module after calling this method, or
        /// the resource will not be found.</remarks>
        public void CreateTextFile(string file)
        {
            if (NWN2ToolsetMainForm.App.Module == null)
            {
                throw new InvalidOperationException("Module not open.");
            }
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (file == String.Empty)
            {
                throw new ArgumentException("File name cannot be empty.", "file");
            }

            OEIResRef resRef = new OEIResRef(file);

            IResourceEntry resource = NWN2ToolsetMainForm.App.Module.Repository.FindResource(resRef, txtCode);

            if (resource != null)
            {
                throw new ArgumentException("File '" + file + "' already exists.", "file");
            }

            resource = NWN2ToolsetMainForm.App.Module.Repository.CreateResource(resRef, txtCode);

            if (resource == null)
            {
                throw new ApplicationException("Failed to retrieve or create resource.");
            }
        }
Exemple #4
0
        private void AssertStructure(ResourceEntryInfo expectedStructure, IResourceEntry directory)
        {
            var expectedStack = new Stack <ResourceEntryInfo>();
            var stack         = new Stack <IResourceEntry>();

            expectedStack.Push(expectedStructure);
            stack.Push(directory);

            while (stack.Count > 0)
            {
                var expected = expectedStack.Pop();
                var current  = stack.Pop();

                Assert.Equal(expected.Name, current.Name);
                Assert.Equal(expected.Id, current.Id);

                if (expected.IsData)
                {
                    Assert.IsAssignableFrom <IResourceData>(current);
                }
                else
                {
                    Assert.IsAssignableFrom <IResourceDirectory>(current);
                    var subEntries = ((IResourceDirectory)current).Entries;
                    Assert.Equal(expected.Entries.Count, subEntries.Count);

                    for (int i = 0; i < subEntries.Count; i++)
                    {
                        expectedStack.Push(expected.Entries[i]);
                        stack.Push(subEntries[i]);
                    }
                }
            }
        }
        public virtual void OnResourceRenamed(IResourceEntry cEntry, string sOldName)
        {
            m_ResourceAccessor.InvalidateResourceIndexes();

            if (m_OriginalVCPlugin != null)
            {
                m_OriginalVCPlugin.OnResourceRenamed(cEntry, sOldName);
            }
        }
Exemple #6
0
        private void WriteEntry(IBinaryStreamWriter writer, IResourceEntry entry)
        {
            writer.WriteUInt32(entry.Name != null
                ? _nameTable.GetEntryOffset(entry.Name) | 0x8000_0000
                : entry.Id);

            writer.WriteUInt32(entry.IsDirectory
                ? (GetEntryOffset((IResourceDirectory)entry) | 0x8000_0000)
                : _dataEntryTable.GetEntryOffset((IResourceData)entry));
        }
Exemple #7
0
        /// <summary>
        /// Open a 2DA resource by name
        /// </summary>
        /// <param name="ResRef">Supplies the resref to open</param>
        /// <param name="ResType">Supplies the restype code of the resource</param>
        /// <returns>The 2DA reader for the entry is returned on success, else
        /// null if the resource didn't exist</returns>
        public TwoDAFile OpenTwoDAResource(string ResRef, ushort ResType)
        {
            IResourceEntry ResEntry = GetResource(ResRef, ResType);

            if (ResEntry == null)
            {
                return(null);
            }

            return(new TwoDAFile(ResEntry.GetStream(false)));
        }
        /// <summary>
        /// Assigns an IResourceEntry and creates a SEFGroup for it.
        /// </summary>
        /// <param name="resent"></param>
        internal static void CreateSefgroup(IResourceEntry resent)
        {
            Resent = resent;

            Altgroup = null;
            Solgroup = null;

            Sefgroup = new SEFGroup();

            using (Stream bin = Resent.GetStream(false))
                Sefgroup.XmlUnserialize(bin);

            Resent.Release();
        }
 private void AddEntry(IResourceEntry entry)
 {
     if (entry.IsDirectory)
     {
         AddDirectory((IResourceDirectory)entry);
     }
     else if (entry.IsData)
     {
         AddDataEntry(entry);
     }
     else
     {
         throw new NotSupportedException();
     }
 }
Exemple #10
0
 public static void Generate(string resourceXml, string targetResourceDir)
 {
     try
     {
         // 加载多语文件
         XDocument xDocument = XDocument.Load(resourceXml);
         // 获取根目录
         XElement xResourceList = xDocument.Root;
         // 检查是否符合规范
         if (xResourceList != null)
         {
             if (!xResourceList.Name.LocalName.Equals("ResourceList"))
             {
                 return;
             }
             // 获取所有的资源列表
             IEnumerable <XElement> xResources = xResourceList.Elements();
             if (xResources.Count() > 0)
             {
                 // 获取资源名称
                 string resourceName = Path.GetFileNameWithoutExtension(resourceXml) + ".resources";
                 if (!Directory.Exists(targetResourceDir))
                 {
                     Directory.CreateDirectory(targetResourceDir);
                 }
                 string path = Path.Combine(targetResourceDir, resourceName);
                 using (IResourceWriter resourceWriter = new ResourceWriter(path))
                 {
                     foreach (XElement xResource in xResources)
                     {
                         IResourceEntry re = AbstractResourceEntry.CreateResourceEntry(xResource);
                         if (re != null)
                         {
                             re.Generate(resourceWriter, xResource);
                         }
                     }
                     resourceWriter.Generate();
                 }
             }
         }
     }
     catch (Exception e)
     {
         Log.Debug(e);
     }
 }
Exemple #11
0
        public bool HasTextFile(string file)
        {
            if (NWN2ToolsetMainForm.App.Module == null)
            {
                throw new InvalidOperationException("Module not open.");
            }
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (file == String.Empty)
            {
                throw new ArgumentException("File name cannot be empty.", "file");
            }

            OEIResRef resRef = new OEIResRef(file);

            IResourceEntry resource = NWN2ToolsetMainForm.App.Module.Repository.FindResource(resRef, txtCode);

            return(resource != null);
        }
Exemple #12
0
    //todo: just pass constructionZone, it's less params
    internal void ShowConstruction(List <IResourceEntry> requiresList, Dictionary <Matter, float> hasCount, Module toBeBuilt)
    {
        //show the name of the thing being built
        this.ConstructionPanel.gameObject.SetActive(true);
        this.ConstructionHeader.text = "Building a " + toBeBuilt.ToString();

        //show a list of resources gathered / resources required
        for (int i = 0; i < this.ConstructionRequirements.Length; i++)
        {
            if (i < requiresList.Count)
            {
                IResourceEntry resourceEntry = requiresList[i];
                string         output        = resourceEntry.ToStringWithAvailableVolume(hasCount[resourceEntry.Type]);
                this.ConstructionRequirementsText[i].text = output;
                this.ConstructionRequirements[i].gameObject.SetActive(true);
            }
            else
            {
                this.ConstructionRequirements[i].gameObject.SetActive(false);
            }
        }
    }
        public virtual void OnResourceRenamed(IResourceEntry cEntry, string sOldName)
        {
            m_ResourceAccessor.InvalidateResourceIndexes();

            if (m_OriginalVCPlugin != null)
                m_OriginalVCPlugin.OnResourceRenamed(cEntry, sOldName);
        }
Exemple #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="script"></param>
        /// <param name="attachment">Only return a script if it is attached
        /// in the manner indicated by this parameter.</param>
        /// <returns></returns>
        /// <remarks>This method expects that the NWN2GameScript is already Loaded
        /// (that is, the responsibility for calling Demand() falls to the client.)</remarks>
        public FlipScript GetFlipScript(NWN2GameScript script, Attachment attachment)
        {
            if (script == null)
            {
                throw new ArgumentNullException("script");
            }

            string code, address, naturalLanguage;

            ScriptWriter.ParseNWScript(script.Data, out code, out address, out naturalLanguage);

            ScriptType scriptType = GetScriptType(script);

            if (attachment == Attachment.Ignore)
            {
                return(new FlipScript(code, scriptType, script.Name));
            }

            NWN2GameModule mod = session.GetModule();

            if (mod == null)
            {
                throw new InvalidOperationException("No module is open.");
            }

            Nwn2Address             nwn2Address;
            Nwn2ConversationAddress nwn2ConversationAddress;

            switch (attachment)
            {
            case Attachment.Attached:
                nwn2Address             = Nwn2Address.TryCreate(address);
                nwn2ConversationAddress = Nwn2ConversationAddress.TryCreate(address);
                break;

            case Attachment.AttachedToConversation:
                nwn2Address             = null;
                nwn2ConversationAddress = Nwn2ConversationAddress.TryCreate(address);
                break;

            case Attachment.AttachedToScriptSlot:
                nwn2Address             = Nwn2Address.TryCreate(address);
                nwn2ConversationAddress = null;
                break;

            default:
                nwn2Address             = null;
                nwn2ConversationAddress = null;
                break;
            }

            if (nwn2Address != null)
            {
                try {
                    if (nwn2Address.TargetType == Nwn2Type.Module)
                    {
                        IResourceEntry resource = typeof(NWN2ModuleInformation).GetProperty(nwn2Address.TargetSlot).GetValue(mod.ModuleInfo, null) as IResourceEntry;
                        if (resource != null && resource.ResRef.Value == script.Name)
                        {
                            return(new FlipScript(code, scriptType, script.Name));
                        }
                    }

                    else if (nwn2Address.TargetType == Nwn2Type.Area)
                    {
                        NWN2GameArea area = session.GetArea(nwn2Address.AreaTag);

                        if (area != null)
                        {
                            IResourceEntry resource = typeof(NWN2GameArea).GetProperty(nwn2Address.TargetSlot).GetValue(area, null) as IResourceEntry;
                            if (resource != null && resource.ResRef.Value == script.Name)
                            {
                                return(new FlipScript(code, scriptType, script.Name));
                            }
                        }
                    }

                    else
                    {
                        /*
                         * The script might be attached to a Narrative Threads blueprint:
                         */

                        // First check that if a blueprint which uses this tag as resref exists, it was created by Narrative Threads:

                        if (nt.CreatedByNarrativeThreads(nwn2Address.TargetType, nwn2Address.InstanceTag))
                        {
                            NWN2ObjectType objectType = Nwn2ScriptSlot.GetObjectType(nwn2Address.TargetType).Value;
                            INWN2Blueprint blueprint  = session.GetBlueprint(nwn2Address.InstanceTag.ToLower(), objectType);

                            if (blueprint != null)
                            {
                                IResourceEntry resource = blueprint.GetType().GetProperty(nwn2Address.TargetSlot).GetValue(blueprint, null) as IResourceEntry;
                                if (resource != null && resource.ResRef.Value == script.Name)
                                {
                                    return(new FlipScript(code, scriptType, script.Name));
                                }
                            }
                        }

                        // Check through all OPEN areas.
                        foreach (NWN2GameArea area in mod.Areas.Values)
                        {
                            if (!session.AreaIsOpen(area))
                            {
                                continue;
                            }

                            NWN2InstanceCollection instances = session.GetObjectsByAddressInArea(nwn2Address, area.Tag);

                            if (instances != null)
                            {
                                // Check the script is still attached to the target object in the slot it claims to be,
                                // in at least one instance, and if so add it to the set of scripts to be opened:

                                foreach (INWN2Instance instance in instances)
                                {
                                    IResourceEntry resource = instance.GetType().GetProperty(nwn2Address.TargetSlot).GetValue(instance, null) as IResourceEntry;
                                    if (resource != null && resource.ResRef.Value == script.Name)
                                    {
                                        return(new FlipScript(code, scriptType, script.Name));
                                    }
                                }
                            }
                        }
                    }
                }

                catch (Exception x) {
                    throw new ApplicationException(String.Format("Failed to handle script + '{0}' properly.", script.Name), x);
                }
            }

            else if (nwn2ConversationAddress != null)               // Check through all conversations, regardless of whether they're open.

            {
                NWN2GameConversation conversation = session.GetConversation(nwn2ConversationAddress.Conversation);

                if (conversation == null)
                {
                    return(null);
                }

                if (NWN2Toolset.NWN2ToolsetMainForm.App.GetViewerForResource(conversation) == null)
                {
                    conversation.Demand();
                }

                NWN2ConversationLine line = conversation.GetLineFromGUID(nwn2ConversationAddress.LineID);

                if (line == null)
                {
                    return(null);
                }

                if (line.Actions.Count == 0)
                {
                    return(null);
                }

                IResourceEntry resource = line.Actions[0].Script;
                if (resource != null && resource.ResRef.Value == script.Name)
                {
                    return(new FlipScript(code, scriptType, script.Name));
                }
            }

            return(null);
        }
Exemple #15
0
 internal bool Has(IResourceEntry req)
 {
     return((LeftInput != null && LeftInput.Data.Container.MatterType == req.Type && LeftInput.Data.Container.CurrentAmount >= req.AmountByVolume) ||
            (RightInput != null && RightInput.Data.Container.MatterType == req.Type && RightInput.Data.Container.CurrentAmount >= req.AmountByVolume));
 }
Exemple #16
0
        /// <summary>
        /// This routine scans module.ifo for a campaign GUID.  If found, a
        /// campaign.cam file with the same GUID is searched for and its
        /// containing directory is added to the directory resource list.
        /// </summary>
        /// <param name="ModuleIfo">Supplies the module.ifo GFF reader.</param>
        /// <param name="HomeDirectory">Supplies the NWN2 home directory.</param>
        /// <param name="InstallDirectory">Supplies the NWN2 install directory.</param>
        private void AddModuleCampaign(GFFFile ModuleIfo, string HomeDirectory, string InstallDirectory)
        {
            byte[] GUIDData = ModuleIfo.TopLevelStruct.GetVoidDataSafe("Campaign_ID", null);

            if (GUIDData == null || GUIDData.Length != 16)
            {
                return;
            }

            Guid CampaignGUID = new Guid(GUIDData);

            string[] SearchDirs = new string[] { HomeDirectory, InstallDirectory };

            //
            // Attempt to locate a campaign.cam file with the same GUID as the
            // module.
            //

            foreach (string PathName in SearchDirs)
            {
                string CampaignFolder = String.Format("{0}\\Campaigns", PathName);

                if (!Directory.Exists(CampaignFolder))
                {
                    continue;
                }

                foreach (string CampaignDir in Directory.EnumerateDirectories(CampaignFolder))
                {
                    using (DirectoryResourceRepository Repository = new DirectoryResourceRepository(CampaignDir))
                    {
                        Repository.PopulateRepository();

                        IResourceEntry ResEntry = Repository.FindResource(new OEIResRef("campaign"), ResCAM);

                        if (ResEntry == null)
                        {
                            continue;
                        }

                        GFFFile CampaignCAM = new GFFFile(ResEntry.GetStream(false));

                        GUIDData = CampaignCAM.TopLevelStruct.GetVoidDataSafe("GUID", null);

                        if (GUIDData == null || GUIDData.Length != 16)
                        {
                            continue;
                        }

                        Guid ID = new Guid(GUIDData);

                        if (!CampaignGUID.Equals(ID))
                        {
                            continue;
                        }

                        Repositories.Add(new DirectoryResourceRepository(CampaignDir));
                        return;
                    }
                }
            }
        }
Exemple #17
0
        // NWN2Toolset.NWN2.Views.NWN2BlueprintView.ᐌ(object P_0, EventArgs P_1)
        // yeah whatever. Those idiots were too clever for anybody's good.
        /// <summary>
        /// Saves a specified blueprint to a user-labeled file.
        /// IMPORTANT: Allow only creature-blueprints to be saved!
        /// - NWN2ObjectType.Creature
        /// - resourcetype #2027
        /// @note Check that blueprint is valid before call.
        /// </summary>
        /// <param name="iblueprint">ElectronPanel_.Blueprint or .Instance
        /// converted to a blueprint</param>
        /// <param name="repo">null if Override</param>
        internal static void SaveBlueprintToFile(INWN2Blueprint iblueprint, DirectoryResourceRepository repo = null)
        {
            string fil = iblueprint.Resource.ResRef.Value;
            string ext = BWResourceTypes.GetFileExtension(iblueprint.Resource.ResourceType);

            var sfd = new SaveFileDialog();

            sfd.Title    = "Save blueprint as ...";
            sfd.FileName = fil + "." + ext;               // iblueprint.Resource.FullName
            sfd.Filter   = "blueprints (*." + ext + ")|*." + ext + "|all files (*.*)|*.*";
//			sfd.DefaultExt = ext;

            string dir;

            if (repo != null)
            {
                dir = repo.DirectoryName;
            }
            else
            {
                dir = String.Empty;
            }

            if (!String.IsNullOrEmpty(dir))
            {
                if (Directory.Exists(dir))
                {
                    sfd.InitialDirectory = dir;
                    sfd.RestoreDirectory = true;
                }
            }
            else if (!String.IsNullOrEmpty(CreatureVisualizerPreferences.that.LastSaveDirectory) &&
                     Directory.Exists(CreatureVisualizerPreferences.that.LastSaveDirectory))
            {
                sfd.InitialDirectory = CreatureVisualizerPreferences.that.LastSaveDirectory;
            }
            // else TODO: use NWN2ResourceManager.Instance.UserOverrideDirectory
            // else TODO: get BlueprintLocation dir if exists


            if (sfd.ShowDialog() == DialogResult.OK)
            {
                if (String.IsNullOrEmpty(dir))
                {
                    CreatureVisualizerPreferences.that.LastSaveDirectory = Path.GetDirectoryName(sfd.FileName);
                }


                // NOTE: Add 'AppearanceSEF' back in from the original blueprint
                // since it was removed when the original was duplicated by
                // ElectronPanel_.DuplicateBlueprint().
                (iblueprint as NWN2CreatureTemplate).AppearanceSEF = AppearanceSEF;


                IOEISerializable iserializable = iblueprint;
                if (iserializable != null)
                {
                    iserializable.OEISerialize(sfd.FileName);

                    if (File.Exists(sfd.FileName))                     // test that file exists before proceeding
                    {
                        INWN2BlueprintSet blueprintset;

                        dir = Path.GetDirectoryName(sfd.FileName).ToLower();
                        if (dir == NWN2ToolsetMainForm.App.Module.Repository.DirectoryName.ToLower())
                        {
                            repo         = NWN2ToolsetMainForm.App.Module.Repository;
                            blueprintset = NWN2ToolsetMainForm.App.Module as INWN2BlueprintSet;

                            iblueprint.BlueprintLocation = NWN2BlueprintLocationType.Module;
                        }
                        else if (NWN2CampaignManager.Instance.ActiveCampaign != null &&
                                 dir == NWN2CampaignManager.Instance.ActiveCampaign.Repository.DirectoryName.ToLower())
                        {
                            repo         = NWN2CampaignManager.Instance.ActiveCampaign.Repository;
                            blueprintset = NWN2CampaignManager.Instance.ActiveCampaign as INWN2BlueprintSet;

                            iblueprint.BlueprintLocation = NWN2BlueprintLocationType.Campaign;
                        }
                        else if (IsOverride(dir))
                        {
                            repo         = NWN2ResourceManager.Instance.UserOverrideDirectory;
                            blueprintset = NWN2GlobalBlueprintManager.Instance as INWN2BlueprintSet;

                            iblueprint.BlueprintLocation = NWN2BlueprintLocationType.Global;
                        }
                        else
                        {
                            return;
                        }


                        // so, which should be tested for first: resource or blueprint?
                        // and is there even any point in having one w/out the other?

                        string filelabel = Path.GetFileNameWithoutExtension(sfd.FileName);

                        NWN2BlueprintCollection collection = blueprintset.GetBlueprintCollectionForType(NWN2ObjectType.Creature);

                        INWN2Blueprint extantblueprint = NWN2GlobalBlueprintManager.FindBlueprint(NWN2ObjectType.Creature,
                                                                                                  new OEIResRef(filelabel),
                                                                                                  iblueprint.BlueprintLocation == NWN2BlueprintLocationType.Global,
                                                                                                  iblueprint.BlueprintLocation == NWN2BlueprintLocationType.Module,
                                                                                                  iblueprint.BlueprintLocation == NWN2BlueprintLocationType.Campaign);

                        if (extantblueprint != null && extantblueprint.Resource.Repository is DirectoryResourceRepository) // ie. exclude Data\Templates*.zip
                        {
                            collection.Remove(extantblueprint);                                                            // so, does removing a blueprint also remove its resource? no.
                        }

                        IResourceEntry extantresource = repo.FindResource(new OEIResRef(filelabel), 2027);                         // it's maaaaaagick
                        if (extantresource != null)
                        {
                            repo.Resources.Remove(extantresource);                             // so, does removing a resource also remove its blueprint? no.
                        }


                        iblueprint.Resource = repo.CreateResource(iblueprint.Resource.ResRef, iblueprint.Resource.ResourceType);
                        collection.Add(iblueprint);

                        var viewer = NWN2ToolsetMainForm.App.BlueprintView;
                        var list   = viewer.GetFocusedList();
                        list.Resort();

                        var objects = new object[1] {
                            iblueprint as INWN2Object
                        };
                        viewer.Selection = objects;
                    }
                }
            }
        }
Exemple #18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dict"></param>
        /// <param name="attachment"></param>
        /// <returns></returns>
        /// <remarks>Note that this automatically opens and closes areas/conversations etc. - it is only
        /// for use with analysis methods, not for users.</remarks>
        public List <ScriptTriggerTuple> GetAllScriptsFromModule(Attachment attachment)
        {
            NWN2GameModule mod = session.GetModule();

            if (mod == null)
            {
                throw new InvalidOperationException("No module is open.");
            }

            NWN2GameScriptDictionary dict = mod.Scripts;

            if (attachment == Attachment.Ignore)
            {
                return(GetTuples(dict));
            }

            Dictionary <Nwn2Address, FlipScript>             moduleScripts       = new Dictionary <Nwn2Address, FlipScript>();
            Dictionary <Nwn2Address, FlipScript>             areaScripts         = new Dictionary <Nwn2Address, FlipScript>();
            Dictionary <Nwn2ConversationAddress, FlipScript> conversationScripts = new Dictionary <Nwn2ConversationAddress, FlipScript>();

            foreach (NWN2GameScript nwn2Script in dict.Values)
            {
                try {
                    nwn2Script.Demand();

                    string code, address, naturalLanguage;
                    ScriptWriter.ParseNWScript(nwn2Script.Data, out code, out address, out naturalLanguage);

                    ScriptType scriptType = GetScriptType(nwn2Script);

                    FlipScript script = new FlipScript(code, scriptType, nwn2Script.Name);

                    Nwn2ConversationAddress ca = Nwn2ConversationAddress.TryCreate(address);
                    if (ca != null)
                    {
                        conversationScripts.Add(ca, script);
                    }

                    else
                    {
                        Nwn2Address a = Nwn2Address.TryCreate(address);

                        if (a != null)
                        {
                            if (a.TargetType == Nwn2Type.Module)
                            {
                                moduleScripts.Add(a, script);
                            }

                            else
                            {
                                areaScripts.Add(a, script);
                            }
                        }
                    }

                    nwn2Script.Release();
                }
                catch (Exception) {}
            }

            List <ScriptTriggerTuple> scripts = new List <ScriptTriggerTuple>(dict.Count);           // this is what we'll return

            if (attachment == Attachment.AttachedToConversation || attachment == Attachment.Attached)
            {
                // Index by conversation name, so we can check all the scripts for a conversation in one go.

                Dictionary <string, List <Nwn2ConversationAddress> > convNameIndex = new Dictionary <string, List <Nwn2ConversationAddress> >();

                foreach (Nwn2ConversationAddress address in conversationScripts.Keys)
                {
                    if (!convNameIndex.ContainsKey(address.Conversation))
                    {
                        convNameIndex.Add(address.Conversation, new List <Nwn2ConversationAddress>());
                    }

                    convNameIndex[address.Conversation].Add(address);
                }

                foreach (string convName in convNameIndex.Keys)
                {
                    NWN2GameConversation conv = mod.Conversations[convName];

                    if (conv == null)
                    {
                        continue;
                    }

                    conv.Demand();

                    foreach (Nwn2ConversationAddress address in convNameIndex[convName])
                    {
                        FlipScript script = conversationScripts[address];

                        NWN2ConversationLine line = conv.GetLineFromGUID(address.LineID);

                        if (line == null)
                        {
                            continue;
                        }

                        if (address.AttachedAs == ScriptType.Standard && line.Actions.Count > 0)
                        {
                            IResourceEntry resource = line.Actions[0].Script;
                            if (resource != null && resource.ResRef.Value == script.Name)
                            {
                                scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                            }
                        }

                        else if (address.AttachedAs == ScriptType.Conditional && line.OwningConnector.Conditions.Count > 0)
                        {
                            IResourceEntry resource = line.OwningConnector.Conditions[0].Script;
                            if (resource != null && resource.ResRef.Value == script.Name)
                            {
                                scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                            }
                        }
                    }

                    conv.Release();
                }
            }

            if (attachment == Attachment.AttachedToScriptSlot || attachment == Attachment.Attached)
            {
                // First, just check for scripts attached to the module - easy:

                foreach (Nwn2Address address in moduleScripts.Keys)
                {
                    FlipScript script = moduleScripts[address];

                    IResourceEntry resource = typeof(NWN2ModuleInformation).GetProperty(address.TargetSlot).GetValue(mod.ModuleInfo, null) as IResourceEntry;

                    if (resource != null && resource.ResRef.Value == script.Name)
                    {
                        scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                    }
                }


                // Next, check whether any script is attached to a Narrative Threads blueprint, and
                // if you find one, add it to the collection and remove it from consideration:

                List <Nwn2Address> processed = new List <Nwn2Address>();

                foreach (Nwn2Address address in areaScripts.Keys)
                {
                    if (Nwn2ScriptSlot.GetObjectType(address.TargetType) == null)
                    {
                        continue;                                                                               // ignore area, module etc.
                    }
                    FlipScript script = areaScripts[address];

                    // First check that if a blueprint which uses this tag as resref exists, it was created by Narrative Threads:
                    if (nt.CreatedByNarrativeThreads(address.TargetType, address.InstanceTag))
                    {
                        NWN2ObjectType objectType = Nwn2ScriptSlot.GetObjectType(address.TargetType).Value;
                        INWN2Blueprint blueprint  = session.GetBlueprint(address.InstanceTag.ToLower(), objectType);

                        if (blueprint != null)
                        {
                            IResourceEntry resource = blueprint.GetType().GetProperty(address.TargetSlot).GetValue(blueprint, null) as IResourceEntry;

                            if (resource != null && resource.ResRef.Value == script.Name)
                            {
                                scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                                processed.Add(address);
                            }
                        }
                    }
                }

                foreach (Nwn2Address p in processed)
                {
                    areaScripts.Remove(p);                                                  // has been added, so don't check for it more than once
                }
                // Then, open each area in turn, and see whether a script is attached to it. If it is, add
                // it to the collection and remove it from consideration:

                foreach (NWN2GameArea area in mod.Areas.Values)
                {
                    if (areaScripts.Count == 0)
                    {
                        break;
                    }

                    session.OpenArea(area);

                    processed = new List <Nwn2Address>();

                    foreach (Nwn2Address address in areaScripts.Keys)
                    {
                        FlipScript script = areaScripts[address];

                        if (address.TargetType == Nwn2Type.Area)
                        {
                            IResourceEntry resource = typeof(NWN2GameArea).GetProperty(address.TargetSlot).GetValue(area, null) as IResourceEntry;

                            if (resource != null && resource.ResRef.Value == script.Name)
                            {
                                scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                                processed.Add(address);                                 // don't check whether to add it more than once
                            }
                        }

                        else
                        {
                            NWN2InstanceCollection instances = session.GetObjectsByAddressInArea(address, area.Tag);

                            if (instances != null)
                            {
                                // Check the script is still attached to the target object in the slot it claims to be,
                                // in at least one instance, and if so add it to the set of scripts to be opened:

                                foreach (INWN2Instance instance in instances)
                                {
                                    IResourceEntry resource = instance.GetType().GetProperty(address.TargetSlot).GetValue(instance, null) as IResourceEntry;

                                    if (resource != null && resource.ResRef.Value == script.Name)
                                    {
                                        scripts.Add(new ScriptTriggerTuple(script, triggerFactory.GetTriggerFromAddress(address)));
                                        processed.Add(address);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    foreach (Nwn2Address p in processed)
                    {
                        areaScripts.Remove(p);                                                      // has been added, so don't check for it more than once
                    }
                    session.CloseArea(area);
                }
            }

            return(scripts);
        }