public Nwn2MoveableProvider(Nwn2ObjectBlockFactory blocks, Nwn2StatementFactory statements, Nwn2TriggerFactory triggers, ToolsetEventReporter reporter) : this(blocks, statements, triggers) { if (reporter != null) { TrackToolsetChanges(reporter); } }
protected void TrackToolsetChanges(ToolsetEventReporter reporter) { if (!reporter.IsRunning) { reporter.Start(); } reporter.ModuleChanged += delegate(object oSender, ModuleChangedEventArgs eArgs) { /* Fires when a module closes, but that doesn't mean that the new module has * been fully opened yet... usually takes a while! */ Action action = new Action ( delegate() { if (manager != null) { manager.EmptyBag(AreasBagName); foreach (NWN2ObjectType type in Enum.GetValues(typeof(NWN2ObjectType))) { string bag = String.Format(InstanceBagNamingFormat, type); if (manager.HasBag(bag)) { manager.EmptyBag(bag); } } manager.AddMoveable("Creatures", blocks.CreatePlayerBlock()); } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); }; reporter.InstanceAdded += delegate(object sender, InstanceEventArgs e) { if (manager == null) { return; } string bag = String.Format(InstanceBagNamingFormat, e.Instance.ObjectType.ToString()); if (!manager.HasBag(bag)) { return; } ObjectBlock block = blocks.CreateInstanceBlock(e.Instance, e.Area); manager.AddMoveable(bag, block); }; reporter.InstanceRemoved += delegate(object sender, InstanceEventArgs e) { if (manager == null || e.Instance == null) { return; } string bag = String.Format(InstanceBagNamingFormat, Nwn2ScriptSlot.GetNwn2Type(e.Instance.ObjectType)); if (!manager.HasBag(bag)) { return; } try { UIElementCollection collection = manager.GetMoveables(bag); ObjectBlock lost = blocks.CreateInstanceBlock(e.Instance, e.Area); foreach (ObjectBlock block in collection) { if (block.Equals(lost)) { manager.RemoveMoveable(bag, block); return; } } } catch (Exception) {} }; reporter.BlueprintAdded += delegate(object sender, BlueprintEventArgs e) { if (manager == null || e.Blueprint == null) { return; } if (nt.CreatedByNarrativeThreads(e.Blueprint)) { Thread thread = new Thread(new ParameterizedThreadStart(CreateNarrativeThreadsBlock)); thread.IsBackground = true; thread.Start(e.Blueprint); } if (loadBlueprints) { Action action = new Action ( delegate() { string bag = String.Format(BlueprintBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock block = blocks.CreateBlueprintBlock(e.Blueprint); manager.AddMoveable(bag, block); } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } }; reporter.BlueprintRemoved += delegate(object sender, BlueprintEventArgs e) { if (manager == null || e.Blueprint == null) { return; } if (nt.CreatedByNarrativeThreads(e.Blueprint)) { Action action = new Action ( delegate() { string bag = String.Format(InstanceBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock lost = blocks.CreateInstanceBlockFromBlueprint(e.Blueprint); ObjectBlock removing = null; foreach (ObjectBlock block in manager.GetMoveables(bag)) { if (block.Equals(lost)) { removing = block; break; } } if (removing != null) { manager.RemoveMoveable(bag, removing); } } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } if (loadBlueprints) { Action action = new Action ( delegate() { string bag = String.Format(BlueprintBagNamingFormat, e.Blueprint.ObjectType.ToString()); if (manager.HasBag(bag)) { ObjectBlock lost = blocks.CreateBlueprintBlock(e.Blueprint); ObjectBlock removing = null; foreach (ObjectBlock block in manager.GetMoveables(bag)) { if (block.Equals(lost)) { removing = block; break; } } if (removing != null) { manager.RemoveMoveable(bag, removing); } } } ); uiThreadAccess.Dispatcher.Invoke(DispatcherPriority.Normal, action); } }; reporter.AreaOpened += delegate(object sender, AreaEventArgs e) { if (manager == null) { return; } Thread thread = new Thread(new ParameterizedThreadStart(CreateBlocksWhenAreaIsReady)); thread.IsBackground = true; thread.Start(e.Area); }; reporter.ResourceViewerClosed += delegate(object sender, ResourceViewerClosedEventArgs e) { if (manager == null) { return; } foreach (Moveable moveable in manager.GetMoveables(AreasBagName)) { ObjectBlock block = moveable as ObjectBlock; if (block == null) { continue; } AreaBehaviour area = block.Behaviour as AreaBehaviour; if (area == null) { continue; } // Assumes that there are no conversations or scripts with the same name as an // area, but there's no immediately apparent way around this: // (TODO: Could check that module doesn't have a script or conversation of the same name.) if (area.Identifier == e.ResourceName) { manager.RemoveMoveable(AreasBagName, moveable); break; } } if (NWN2ToolsetMainForm.App.Module != null && NWN2ToolsetMainForm.App.Module.Areas.ContainsCaseInsensitive(e.ResourceName)) { // At this point we think it's an area that's been closed, so remove // any instances associated with that area: foreach (NWN2ObjectType type in Enum.GetValues(typeof(NWN2ObjectType))) { string bag = String.Format(InstanceBagNamingFormat, type); if (manager.HasBag(bag)) { List <Moveable> removing = new List <Moveable>(); foreach (Moveable moveable in manager.GetMoveables(bag)) { ObjectBlock block = moveable as ObjectBlock; if (block == null) { continue; } InstanceBehaviour instance = block.Behaviour as InstanceBehaviour; if (instance == null) { continue; } if (instance.AreaTag.ToLower() == e.ResourceName.ToLower()) { removing.Add(moveable); } } foreach (Moveable moveable in removing) { manager.RemoveMoveable(bag, moveable); } } } } }; // Ensure that an area always has the same resource name and tag: reporter.AreaNameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { NWN2GameArea area = eArgs.Item as NWN2GameArea; if (area == null) { return; } string blockHasTag = area.Tag; if (area.Tag != area.Name) { area.Tag = area.Name; } OEIShared.Utils.OEIExoLocString oeiStr = Nwn2Strings.GetOEIStringFromString(area.Name); if (area.DisplayName != oeiStr) { area.DisplayName = oeiStr; } // Note that this will only work for areas that are currently open... // we'll deal with changing the name of closed areas when they open. // Update the area block, if the area is open: bool open = false; foreach (NWN2AreaViewer av in NWN2ToolsetMainForm.App.GetAllAreaViewers()) { if (av.Area == area) { open = true; break; } } if (!open) { return; } AreaBehaviour behaviour = blocks.CreateAreaBehaviour(area); if (manager.HasBag(AreasBagName)) { UIElementCollection existingBlocks = manager.GetMoveables(AreasBagName); bool updated = false; foreach (UIElement u in existingBlocks) { ObjectBlock existing = u as ObjectBlock; if (existing == null) { continue; } AreaBehaviour existingBehaviour = existing.Behaviour as AreaBehaviour; if (existingBehaviour == null) { continue; } // If you find an area with the same tag, replace its behaviour to update it: if (existingBehaviour.Tag == blockHasTag) { existing.Behaviour = behaviour; updated = true; break; } } if (!updated) { ObjectBlock block = blocks.CreateAreaBlock(behaviour); manager.AddMoveable(AreasBagName, block, false); } } }; // If a script has its name changed, change it back: reporter.ScriptNameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { Thread thread = new Thread(new ParameterizedThreadStart(ReverseScriptNameChange)); thread.IsBackground = false; thread.Start(eArgs); }; }
/// <summary> /// Construct a new instance of FlipWindow, and forbid it from closing fully. /// </summary> protected void InitialiseFlip() { session = new Nwn2Session(); FlipTranslator translator = new NWScriptTranslator(); attacher = new NWScriptAttacher(translator, session, scriptsFolder); Nwn2Fitters fitters = new Nwn2Fitters(); triggers = new Nwn2TriggerFactory(fitters); scriptHelper = new ScriptHelper(triggers); Nwn2StatementFactory statements = new Nwn2StatementFactory(fitters); Nwn2ImageProvider images = new Nwn2ImageProvider(new NarrativeThreadsHelper()); blocks = new Nwn2ObjectBlockFactory(images); ToolsetEventReporter reporter = new ToolsetEventReporter(); provider = new Nwn2MoveableProvider(blocks, statements, triggers, reporter); window = new FlipWindow(provider, images, new FlipWindow.OpenDeleteScriptDelegate(OpenDeleteScriptDialog), new FlipWindow.SaveScriptDelegate(SaveScript), new Nwn2DeserialisationHelper()); window.Closing += delegate(object sender, CancelEventArgs e) { // Hide the window instead of closing it: e.Cancel = true; // Unless the user changes their mind about closing the script, // in which case don't even do that: if (window.AskWhetherToSaveCurrentScript() != MessageBoxResult.Cancel) { //window.CloseScript(); window.Visibility = Visibility.Hidden; //window.LeaveConditionMode(); Log.WriteAction(LogAction.exited, "flip"); } }; reporter.ModuleChanged += delegate { Action action = new Action ( delegate() { if (window == null) { return; } try { window.CloseScript(); window.Close(); } catch (Exception) {} } ); if (window != null) { window.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, action); } }; MenuItem addWildcardBlock = new MenuItem(); addWildcardBlock.Header = "Add Wildcard block"; addWildcardBlock.Click += delegate { try { CreateWildcardDialog dialog = new CreateWildcardDialog(); dialog.ShowDialog(); if (!String.IsNullOrEmpty(dialog.WildcardTag)) { ObjectBlock block = blocks.CreateWildcardBlock(dialog.WildcardTag); window.BlockBox.AddMoveable(Nwn2MoveableProvider.ValuesBagName, block, true); //ActivityLog.Write(new Activity("CreatedWildcardBlock","Block",block.GetLogText())); Log.WriteMessage("created wildcard block (" + block.GetLogText() + ")"); } } catch (Exception x) { MessageBox.Show("Something went wrong when creating a Wildcard block.\n\n" + x); } }; window.EditMenu.Items.Add(addWildcardBlock); MenuItem openTriggerlessScripts = new MenuItem(); openTriggerlessScripts.Header = "Open unattached script"; openTriggerlessScripts.Click += delegate { try { OpenAnyScriptViaDialog(); } catch (Exception x) { MessageBox.Show("Something went wrong when opening a script via its filename.\n\n" + x); } }; window.DevelopmentMenu.Items.Add(openTriggerlessScripts); // MenuItem analyseAllScripts = new MenuItem(); // analyseAllScripts.Header = "Analyse all scripts"; // analyseAllScripts.Click += delegate // { // try { // AnalyseAllScripts(); // } // catch (Exception x) { // MessageBox.Show("Something went wrong when analysing scripts.\n\n" + x); // } // }; // window.DevelopmentMenu.Items.Add(analyseAllScripts); // // MenuItem analyseScript = new MenuItem(); // analyseScript.Header = "Analyse script"; // analyseScript.Click += delegate // { // try { // AnalyseScript(); // } // catch (Exception x) { // MessageBox.Show("Something went wrong when analysing script.\n\n" + x); // } // }; // window.DevelopmentMenu.Items.Add(analyseScript); // MenuItem showLogWindow = new MenuItem(); // showLogWindow.Header = "Show log window"; // showLogWindow.Click += delegate // { // try { // new ActivityLogWindow().Show(); // } // catch (Exception x) { // MessageBox.Show("Something went wrong when launching the log window.\n\n" + x); // } // }; // window.DevelopmentMenu.Items.Add(showLogWindow); // Start recording debug messages and user actions: try { LogWriter.StartRecording("flip"); } catch (Exception x) { MessageBox.Show("Something went wrong when setting up a Flip user log.\n" + x); } reporter.AreaNameChanged += delegate(object oObject, NameChangedEventArgs eArgs) { UpdateScriptsFollowingTagChange(oObject, eArgs.OldName, eArgs.NewName, false); }; }