private void AddDataEntry(IResourceEntry entry) { var data = (IResourceData)entry; DataEntryTable.AddEntry(data); DataTable.Add(data.Contents); }
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)); }
/// <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."); } }
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); } }
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)); }
/// <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(); } }
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); } }
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); }
//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); }
/// <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); }
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)); }
/// <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; } } } }
// 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; } } } }
/// <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); }