/// <summary> /// Get a script name which has not already been taken in the current module. /// </summary> /// <returns>An available script name.</returns> public string GetUnusedName() { NWN2GameModule module = session.GetModule(); if (module == null) { throw new ArgumentNullException("module"); } // MUST be 32 characters long or under! The module won't warn you of this, rather // it will simply truncate the filename without reporting that it has done so. // Naming format: // flip kn70 s47 string username = Environment.UserName.ToLower(); // upper-case script names cause errors if (username.Length > 16) { username = username.Substring(0, 16); } string ideal = String.Format("flip {0}", username); int count = 2; string name = ideal; while (session.HasUncompiled(name)) { name = ideal + " s" + count++; } return(name); }
static Globals() { mod = NWN2Toolset.NWN2ToolsetMainForm.App.Module; repository = mod.Repository; items = mod.GetBlueprintCollectionForType(NWN2Toolset.NWN2.Data.Templates.NWN2ObjectType.Item); customTlk = new OEIShared.IO.TalkTable.TalkTable(); customTlk.OpenCustom(OEIShared.Utils.BWLanguages.BWLanguage.English, "alfa_acr02.tlk"); tdaManager = TwoDAManager.Instance; spellschools2da = tdaManager.Get("spellschools"); nwn2_icons2da = tdaManager.Get("nwn2_icons"); iprp_spells2da = tdaManager.Get("iprp_spells"); spells = new NWN2Toolset.NWN2.Rules.CNWSpellArray(); spells.Load(); globalItemCollection = NWN2Toolset.NWN2.Data.Blueprints.NWN2GlobalBlueprintManager.GetBlueprintsOfType(NWN2Toolset.NWN2.Data.Templates.NWN2ObjectType.Item); iconHash = new Dictionary<string, int>(); int rowCount = Globals.nwn2_icons2da.RowCount; for (int i = 0; i < rowCount; i++) { string twodaString = Globals.nwn2_icons2da["ICON"][i]; if (!iconHash.ContainsKey(twodaString)) { iconHash.Add(twodaString, i); } } }
/// <summary> /// We do not yet have a storyNode /// </summary> /// <param name="giver">The current giver</param> /// <param name="villian">The current villian</param> /// <param name="extra">The current extras</param> /// <param name="props">The current items</param> /// <param name="prevStoryNodes">The previous story nodes</param> /// <param name="triggers">The current triggers</param> /// <param name="module">The module we are using</param> public StoryNodeForm(Actor giver, Actor villian, LinkedList<Actor> extra, LinkedList<Actor> props, LinkedList<StoryNode> prevStoryNodes, LinkedList<Actor> triggers, NWN2GameModule module) { InitializeComponent(); basicSetup(giver, villian, extra, props, prevStoryNodes, triggers, module); if (prevStoryNodes.Count > 0) { radioNoPreReq.Checked = false; radioSimpPreReq.Checked = true; } }
private NWN2AreaViewer getAreaViewer() { if (toolset == null) { toolset = NWN2Toolset.NWN2ToolsetMainForm.App; } if (module == null) { module = toolset.Module; } return((NWN2Toolset.NWN2.Views.NWN2AreaViewer)toolset.GetActiveViewer()); }
public List <ScriptTriggerTuple> GetAllScripts(Attachment attachment) { NWN2GameModule mod = NWN2ToolsetMainForm.App.Module; if (mod == null) { throw new InvalidOperationException("No module is open."); } List <ScriptTriggerTuple> tuples = new List <ScriptTriggerTuple>(); foreach (NWN2GameScript script in mod.Scripts.Values) { if (!WasCreatedByFlip(script)) { continue; } try { script.Demand(); FlipScript flipScript = GetFlipScript(script, attachment); if (flipScript != null) { TriggerControl trigger; if (attachment == Attachment.Ignore) { trigger = new BlankTrigger(flipScript.Name); } else { trigger = GetTrigger(script); } tuples.Add(new ScriptTriggerTuple(flipScript, trigger)); } } catch (Exception x) { MessageBox.Show("Something went wrong when trying to add " + script.Name + " to the set of openable scripts.\n\n" + x); } } return(tuples); }
public TriggerControl GetTriggerFromAddress(Nwn2ConversationAddress address) { if (address == null) { throw new ArgumentNullException("address"); } if (address.AttachedAs == Sussex.Flip.Core.ScriptType.Conditional) { return(null); } NWN2GameModule mod = NWN2Toolset.NWN2ToolsetMainForm.App.Module; if (mod == null) { throw new InvalidOperationException("No module is open."); } NWN2GameConversation conversation = session.GetConversation(address.Conversation); if (conversation == null) { throw new ArgumentException("Could not find conversation '" + address.Conversation + "' in this module.", "conversation"); } if (NWN2Toolset.NWN2ToolsetMainForm.App.GetViewerForResource(conversation) == null) { conversation.Demand(); } NWN2ConversationLine line = conversation.GetLineFromGUID(address.LineID); if (line == null) { throw new ArgumentException("Could not find a line with the given ID in conversation '" + address.Conversation + "'.", "conversation"); } return(new DialogueWasSpoken(line.OwningConnector, conversation)); }
// /// <summary> /// We have a story node /// </summary> /// <param name="sNode">The story node we are editing</param> /// <param name="giver">The current giver</param> /// <param name="villian">The current villian</param> /// <param name="extra">The current extras</param> /// <param name="props">The current items</param> /// <param name="prevStoryNodes">The previous story nodes</param> /// <param name="triggers">The current triggers</param> /// <param name="module">The module we are using</param> public StoryNodeForm(StoryNode sNode, Actor giver, Actor villian, LinkedList<Actor> extra, LinkedList<Actor> props, LinkedList<StoryNode> prevStoryNodes, LinkedList<Actor> triggers, NWN2GameModule module) { InitializeComponent(); storyNodeName.Text = sNode.Name; basicSetup(giver, villian, extra, props, prevStoryNodes, triggers, module); comboActor.SelectedItem = sNode.actor; if (comboActor.SelectedItem == null && comboActor.Items.Count > 0) { comboActor.SelectedIndex = 0; } comboTriggers.SelectedItem = trigger; // Look at this null comparison to see if it is correct if (comboTriggers.SelectedItem == null && comboTriggers.Items.Count > 0) { comboTriggers.SelectedIndex = 0; } // I add the data to the "What happens" field switch (sNode.happensEnum) { case EnumTypes.happens.Conv: radioConvs.Checked = true; break; case EnumTypes.happens.Conflict: radioVillian.Checked = true; break; case EnumTypes.happens.OpenDoor: radioDoor.Checked = true; break; case EnumTypes.happens.Trigger: triggerRadio.Checked = true; break; } /* I set options (radiobuttons and checkbuttons) These are independant of the above as the user may fiddle around */ // Conv: I set the escort/explore options checkExplore.Checked = (sNode.convHappens == StoryNode.convType.Explore); checkEscort.Checked = (sNode.convHappens == StoryNode.convType.Escort); // Villian checkVillianTalk.Checked = sNode.villianTalk; checkVillianItem.Checked = (sNode.villianGotItem && sNode.actor.type == EnumTypes.actorType.Creature); //Door or placable: checkContainerContains.Checked = (sNode.villianGotItem && sNode.actor.type == EnumTypes.actorType.Placeable); // Trigger: radioFinishEscort.Checked = (sNode.triggerHappens == StoryNode.convType.Escort); radioFinishExplore.Checked = (sNode.triggerHappens == StoryNode.convType.Explore); triggerPanel.Enabled = (sNode.happensEnum == EnumTypes.happens.Trigger); // I add the data to the "Conversation Type" field #region Conversation Type switch (sNode.convEnum) { case EnumTypes.conv.QuestInfo: radioQuestInfo.Checked = true; break; case EnumTypes.conv.Single: radioSingleStatement.Checked = true; break; case EnumTypes.conv.None: break; } #endregion #region Items if ((sNode.giveItem != null) || (sNode.giveGold > 0)) { comboGiveItem.SelectedItem = sNode.giveItem; giveItemNumber.Value = sNode.takeNumber; giveGold.Text = sNode.giveGold.ToString(); checkGive.Checked = true; } if ((sNode.takeItem != null) || (sNode.takeGold > 0)) { comboTakeItem.SelectedItem = sNode.takeItem; takeItemNumber.Value = sNode.takeNumber; takeGold.Text = sNode.takeGold.ToString(); checkTake.Checked = true; } if (sNode.villianItem != null) { comboDropItem.SelectedItem = sNode.villianItem; } #endregion #region convesation greetBox.Text = sNode.greeting; acceptBox.Text = sNode.acceptence; actionBox.Text = sNode.action; rejectBox.Text = sNode.rejection; #endregion #region Prerequisite switch (sNode.preReq) { case EnumTypes.prereq.NoPrereq: radioNoPreReq.Checked = true; break; case EnumTypes.prereq.SimplePrereq: radioSimpPreReq.Checked = true; // if(prevStoryNodes.Contains(sNode.preReq) { comboPreRec.SelectedItem = sNode.preReqNode; // } break; case EnumTypes.prereq.CastSpecificPrereq: radioCastSpecPreReq.Checked = true; // if(prevStoryNodes.Contains(sNode.preReq) { comboPreRec.SelectedItem = sNode.preReqNode; // } break; } #endregion // Journal field JournalBox.Text = sNode.journal; checkJournal.Checked = sNode.journalCheck; // EndPoint? checkEndPoint.Checked = sNode.endPoint; XP.Text = sNode.xp.ToString(); }
/// <summary> /// /// </summary> /// <param name="giver"></param> /// <param name="villian"></param> /// <param name="extra"></param> /// <param name="props"></param> /// <param name="prevStoryNodes"></param> /// <param name="triggers"></param> /// <param name="module"></param> private void basicSetup(Actor giver, Actor villian, LinkedList<Actor> extra, LinkedList<Actor> props, LinkedList<StoryNode> prevStoryNodes, LinkedList<Actor> triggers, NWN2GameModule module) { this.giver = giver; this.villian = villian; this.extra = extra; this.props = props; this.module = module; this.triggers = triggers; creatures = loadActors(EnumTypes.actorType.Creature); placeables = loadActors(EnumTypes.actorType.Placeable); doors = loadActors(EnumTypes.actorType.Door); if (creatures.Count > 0) { comboActorType.Items.Add("Creatures"); } if (placeables.Count > 0) { comboActorType.Items.Add("Placeables"); } if (doors.Count > 0) { comboActorType.Items.Add("Doors"); } comboActorType.SelectedIndex = 0; changeActors(); // I add the props foreach (Actor item in props) { comboTakeItem.Items.Add(item); comboGiveItem.Items.Add(item); comboDropItem.Items.Add(item); } if (comboTakeItem.Items.Count > 0) { debug("selectedIndex"); comboTakeItem.SelectedIndex = 0; comboGiveItem.SelectedIndex = 0; comboDropItem.SelectedIndex = 0; } // I insert the previous story nodes foreach (StoryNode sNode in prevStoryNodes) { comboPreRec.Items.Add(sNode); } if (prevStoryNodes.Count == 0) { radioSimpPreReq.Enabled = false; radioCastSpecPreReq.Enabled = false; } else { comboPreRec.SelectedIndex = 0; } foreach (Actor trig in triggers) { comboTriggers.Items.Add(trig); } if (comboTriggers.Items.Count > 0) { comboTriggers.SelectedIndex = 0; } else { checkEscort.Enabled = false; checkExplore.Enabled = false; triggerRadio.Enabled = false; } }
/// <summary> /// The constructor for the area continer - gets the actors from the module given /// </summary> /// <param name="module">The module from where I have to create the area list from</param> public AreaContainer(NWN2GameModule module) { Actor act; tag = "Module"; if (module == null) return; foreach (NWN2CreatureBlueprint creature in module.Creatures) { act = new Actor(creature, EnumTypes.actorType.Creature); creaturePrints.AddLast(act); } foreach (NWN2DoorBlueprint door in module.Doors) { act = new Actor(door, EnumTypes.actorType.Door); doorPrints.AddLast(act); } foreach (NWN2PlaceableBlueprint place in module.Placeables) { act = new Actor(place, EnumTypes.actorType.Placeable); placePrints.AddLast(act); } foreach (NWN2TriggerBlueprint trigger in module.Triggers) { act = new Actor(trigger, EnumTypes.actorType.TriggerRegion); triggerPrints.AddLast(act); } foreach (NWN2ItemBlueprint item in module.Items) { act = new Actor(item, EnumTypes.actorType.Item); itemPrints.AddLast(act); } }
/// <summary> /// Translates Flip source into NWScript, compiles it, /// and attaches the results to a Neverwinter Nights 2 module. /// </summary> /// <param name="source">The Flip source to be compiled.</param> /// <param name="address">An address representing the location /// to attach this script to.</param> /// <returns>The name the script was saved under.</returns> public override string Attach(FlipScript source, string address) { if (source == null) { throw new ArgumentNullException("source"); } if (address == null) { throw new ArgumentNullException("address"); } if (address == String.Empty) { throw new ArgumentException("Must provide a valid address for attaching script.", "address"); } if (!Nwn2ToolsetFunctions.ToolsetIsOpen()) { throw new InvalidOperationException("Toolset must be open to attach scripts."); } NWN2GameModule module = session.GetModule(); if (module == null) { throw new InvalidOperationException("No module is currently open in the toolset."); } string name = GetUnusedName(); try { if (name.Length > 32) { throw new ApplicationException("Cannot attach script under the generated name ('" + name + "') " + "because it is of length " + name.Length + ", and the maximum " + "valid length of a resource name for NWN2 is 32."); } NWN2GameScript script = session.AddScript(name, source.Code); session.CompileScript(script); if (address.StartsWith("Conversation")) { Nwn2ConversationAddress convAddress = new Nwn2ConversationAddress(address); NWN2GameConversation conversation = session.GetConversation(convAddress.Conversation); if (conversation == null) { throw new ArgumentException("Conversation '" + convAddress.Conversation + "' was not found in current module.", "address"); } // foreach (NWN2Toolset.NWN2.Views.INWN2Viewer v in NWN2Toolset.NWN2ToolsetMainForm.App.GetAllViewers()) { // NWN2Toolset.NWN2.Views.NWN2ConversationViewer cv = v as NWN2Toolset.NWN2.Views.NWN2ConversationViewer; // if (cv != null) { // System.Windows.MessageBox.Show("From viewer...\n" + cv.Conversation.Name + // "\nConnectors: " + cv.Conversation.AllConnectors.Count + "\n" + // "Entries: " + cv.Conversation.Entries.Count + "\n" + // "Replies: " + cv.Conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); // } // } // // // System.Windows.MessageBox.Show("From module, before insisting on load...\n" + conversation.Name + // "\nConnectors: " + conversation.AllConnectors.Count + "\n" + // "Entries: " + conversation.Entries.Count + "\n" + // "Replies: " + conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); // // // // if (!conversation.Loaded) conversation.Demand(); // // // System.Windows.MessageBox.Show("From module, after insisting on load...\n" + conversation.Name + // "\nConnectors: " + conversation.AllConnectors.Count + "\n" + // "Entries: " + conversation.Entries.Count + "\n" + // "Replies: " + conversation.Replies.Count + "\n" + // "Loaded: " + conversation.Loaded); NWN2ConversationLine line = session.GetConversationLine(conversation, convAddress.LineID); if (line == null) { throw new ArgumentException("Line with ID " + convAddress.LineID + " was not found in current module.", "address"); } if (convAddress.AttachedAs == ScriptType.Conditional) { session.AttachScriptToConversationAsCondition(script, line, conversation); } else { session.AttachScriptToConversation(script, line, conversation); } } else { Nwn2Address nwn2Address = new Nwn2Address(address); if (!Scripts.IsEventRaiser(nwn2Address.TargetType)) { throw new ArgumentException("Cannot attach scripts to a " + nwn2Address.TargetType + "."); } if (nwn2Address.TargetType == Nwn2Type.Module) { session.AttachScriptToModule(script, nwn2Address.TargetSlot); } else if (nwn2Address.TargetType == Nwn2Type.Area) { NWN2GameArea area = session.GetArea(nwn2Address.AreaTag); if (area == null) { throw new ArgumentException("Area '" + nwn2Address.AreaTag + "' was not found in current module.", "address"); } session.AttachScriptToArea(script, area, nwn2Address.TargetSlot); } else { /* * We want to attach to ALL instances matching the address in ALL OPEN areas, ignoring AreaTag and UseIndex. */ NWN2ObjectType nwn2ObjectType = Nwn2ScriptSlot.GetObjectType(nwn2Address.TargetType).Value; bool attached = false; foreach (NWN2GameArea a in module.Areas.Values) { if (!session.AreaIsOpen(a)) { continue; } NWN2InstanceCollection instances = session.GetObjectsByTag(a, nwn2ObjectType, nwn2Address.InstanceTag); foreach (INWN2Instance instance in instances) { session.AttachScriptToObject(script, instance, nwn2Address.TargetSlot); attached = true; } } /* * We also want to attach to any blueprints which use this tag as their resref. */ // First check that if a blueprint which uses this tag as resref exists, it was created by Narrative Threads: if (nt.CreatedByNarrativeThreads(Nwn2ScriptSlot.GetNwn2Type(nwn2ObjectType), nwn2Address.InstanceTag)) { INWN2Blueprint blueprint = session.GetBlueprint(nwn2Address.InstanceTag.ToLower(), nwn2ObjectType); if (blueprint != null) { session.AttachScriptToBlueprint(script, blueprint, nwn2Address.TargetSlot); attached = true; } } if (!attached) { string error; if (nt.IsLoaded) { error = String.Format("There isn't a {0} with tag '{1}' in any of the areas that are open, or " + "in the blueprints collection.", nwn2Address.TargetType, nwn2Address.InstanceTag); } else { error = String.Format("There isn't a {0} with tag '{1}' in any of the areas that are open.", nwn2Address.TargetType, nwn2Address.InstanceTag); } throw new MatchingInstanceNotFoundException(error, nwn2Address); } } } } catch (MatchingInstanceNotFoundException x) { throw x; } catch (Exception x) { throw new ApplicationException("Something went wrong while saving and attaching script.", x); } if (backups != null) { if (!Directory.Exists(backups)) { try { Directory.CreateDirectory(backups); } catch (Exception) { return(name); } } string saveTo; if (createFoldersForUsers) { try { saveTo = Path.Combine(backups, Environment.UserName); if (!Directory.Exists(saveTo)) { Directory.CreateDirectory(saveTo); } saveTo = Path.Combine(saveTo, module.Name); if (!Directory.Exists(saveTo)) { Directory.CreateDirectory(saveTo); } } catch (Exception) { saveTo = backups; } } else { saveTo = backups; } try { WriteBackup(name, saveTo, source.Code); } catch (Exception) { } } return(name); }
/// <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); }
/// <summary> /// Constructor for the story node /// </summary> /// <param name="name">The name of the story node</param> /// <param name="actor">The actor who will be principal in the story node</param> /// <param name="trigger">The trigger, if any, that will be associated with the story node</param> /// <param name="inModule">The module that is connected to the story node</param> public StoryNode(String name, Actor actor, Actor trigger, NWN2GameModule inModule) { this.name = name; this.actor = actor; this.trigger = trigger; module = inModule; }
/// <summary> /// Sets the module that the story node is connected to /// </summary> public static void setModule() { module = NWN2ToolsetMainForm.App.Module; }
/// <summary> /// The constructor for the form /// </summary> /// <param name="filePath">The path to where quests must be saved to and loaded from</param> public QuestMain(ref String filePath) { InitializeComponent(); this.filePath = filePath; extra = new LinkedList<Actor>(); props = new LinkedList<Actor>(); triggers = new LinkedList<Actor>(); debug("Plug-Started"); comboPri.SelectedIndex = 0; comboLang.SelectedIndex = 0; this.module = NWN2Toolset.NWN2ToolsetMainForm.App.Module; genderBox.SelectedIndex = 0; if (nwn2IconsFile == null) { nwn2IconsFile = TwoDAManager.Instance.Get("nwn2_icons"); nwn2IconsColumnCollection = nwn2IconsFile.Columns; } }
protected void WatchModule(NWN2GameModule mod) { /* Only tracking blueprints which are added to and removed from the module... * this is correct for our purposes! Narrative Threads only uses the module blueprint collections. */ if (mod != null) { /* There seems to be a bug where the following events events fire at a later stage... they do * fire when they should, but when the paused test is allowed to complete, they fire again. */ foreach (NWN2BlueprintCollection bc in mod.BlueprintCollections) { bc.Inserted += delegate(OEICollectionWithEvents cList, int index, object value) { OnBlueprintAdded(bc, new BlueprintEventArgs((INWN2Blueprint)value)); }; bc.Removed += delegate(OEICollectionWithEvents cList, int index, object value) { OnBlueprintRemoved(bc, new BlueprintEventArgs((INWN2Blueprint)value)); }; } List <OEIDictionaryWithEvents> dictionaries; dictionaries = new List <OEIDictionaryWithEvents> { mod.Areas, mod.Conversations, mod.Scripts }; OEIDictionaryWithEvents.ChangeHandler dAdded = new OEIDictionaryWithEvents.ChangeHandler(ResourceInsertedIntoCollection); OEIDictionaryWithEvents.ChangeHandler dRemoved = new OEIDictionaryWithEvents.ChangeHandler(ResourceRemovedFromCollection); foreach (OEIDictionaryWithEvents dictionary in dictionaries) { dictionary.Inserted += dAdded; dictionary.Removed += dRemoved; } // Watch for changes to the names of areas, conversations and scripts: foreach (NWN2GameArea area in mod.Areas) { Watch(area); } foreach (NWN2GameConversation conversation in mod.Conversations) { Watch(conversation); } foreach (NWN2GameScript script in mod.Scripts) { Watch(script); } mod.Areas.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameArea area = value as NWN2GameArea; if (area != null) { Watch(area); } }; mod.Conversations.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameConversation conversation = value as NWN2GameConversation; if (conversation != null) { Watch(conversation); } }; mod.Scripts.Inserted += delegate(OEIDictionaryWithEvents cDictionary, object key, object value) { NWN2GameScript script = value as NWN2GameScript; if (script != null) { Watch(script); } }; } }
private NWN2AreaViewer getAreaViewer() { if (toolset == null) toolset = NWN2Toolset.NWN2ToolsetMainForm.App; if (module == null) module = toolset.Module; return (NWN2Toolset.NWN2.Views.NWN2AreaViewer)toolset.GetActiveViewer(); }
/// <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); }