private void savePrefabMenuItem_Click(object sender, EventArgs e) { if (SelectedNode == null) { return; } // If it is a prefab instance, open this prefab. if (!string.IsNullOrEmpty(SelectedNode.Node.PrefabName)) { string fullpath = FileManagers.FileManager.GetFullPath(SelectedNode.Node.PrefabName); if (UIUtilities.ShowBehaviorTree(fullpath) != null) { return; } } if (SelectedNode == RootNodeView || RootNodeView.RootBehavior.FileManager == null) { return; } // Get the Prefabs folder. //string prefabGroupName = Plugin.GetResourceString("PrefabGroupName"); string prefabGroupName = "Prefabs"; string folder = Directory.GetParent(Workspace.Current.Folder).FullName; folder = Path.Combine(folder, prefabGroupName); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } // Get the full name of the file. string filename = Path.Combine(folder, "pf_" + SelectedNode.Node.ExportClass); string ext = Path.GetExtension(_rootNodeView.RootBehavior.FileManager.Filename); filename = Path.ChangeExtension(filename, ext); using(SaveAsDialog saveAsDialog = new SaveAsDialog(false)) { saveAsDialog.Text = Resources.SaveAsPrefab; saveAsDialog.FileName = _behaviorTreeList.GetUniqueFileName(filename); if (saveAsDialog.ShowDialog() == DialogResult.OK) { filename = saveAsDialog.FileName; // Create a new behavior node. BehaviorNode behaviorNode = Node.CreateBehaviorNode(SelectedNode.Node.ExportClass); behaviorNode.AgentType = _rootNodeView.RootBehavior.AgentType; ((Node)behaviorNode).AddChild(behaviorNode.GenericChildren, SelectedNode.Node.CloneBranch()); string prefabName = FileManagers.FileManager.GetRelativePath(filename); ((Node)behaviorNode).RestorePrefab(prefabName); SelectedNode.Node.SetPrefab(prefabName); SelectedNode.IsExpanded = false; if (string.IsNullOrEmpty(SelectedNode.Node.CommentText)) { string prefab = Path.GetFileNameWithoutExtension(prefabName); SelectedNode.Node.CommentText = string.Format("Prefab[{0}]", prefab); } // Copy the used Pars from the current behavior to the new one. foreach(ParInfo par in((Behavior)_rootNodeView.RootBehavior).LocalVars) { List<Node.ErrorCheck> result = new List<Node.ErrorCheck>(); Plugin.CheckPar(SelectedNode.Node, par, ref result); if (result.Count > 0) { ((Behavior)behaviorNode).LocalVars.Add(par); } } // Save the new behavior node. behaviorNode.FileManager = _behaviorTreeList.GetFileManagers()[0].Create(filename, behaviorNode); behaviorNode.FileManager.Save(); UndoManager.Save(this.RootNode); // Update the behavior list. _behaviorTreeList.RebuildBehaviorList(); } } }
/// <summary> /// Saves a given behavior under the filename which is stored in the behavior's file manager. /// If no file manager exists (new node), the user is asked to choose a name. /// </summary> /// <param name="node">The behavior node which will be saved.</param> /// <param name="saveas">If true, the user will always be asked for a filename, even when a file manager is already present.</param> /// <returns>Returns the result when the behaviour is saved.</returns> public FileManagers.SaveResult SaveBehavior(BehaviorNode node, bool saveas, bool showNode = true) { if (ShowBehavior == null) throw new Exception("Missing event handler ShowBehavior"); try { MainWindow.Instance.EnableFileWatcher(false); // store which behavior is currently shown BehaviorNode currNode = BehaviorTreeViewDock.LastFocused == null ? null : BehaviorTreeViewDock.LastFocused.BehaviorTreeView.RootNode; BehaviorTreeViewDock dock = null; BehaviorNode rootNode = node; if (showNode) { // show the behavior we want to save dock = ShowBehavior(node); // check if we need to show the save dialogue rootNode = dock.BehaviorTreeView.RootNode; } if (rootNode.FileManager == null || saveas) { Debug.Check(_fileManagers.Count > 0); string filename; // set the filename if (rootNode.FileManager != null && saveas) { filename = rootNode.Filename; } else { string dir = Directory.Exists(rootNode.Folder) ? rootNode.Folder : _behaviorFolder; filename = Path.Combine(dir, ((Node)rootNode).Label); filename = Path.ChangeExtension(filename, _fileManagers[0].FileExtension); } bool isValidFile = Path.IsPathRooted(filename); if (saveas || !isValidFile) { // Choose a valid file name. using (SaveAsDialog saveAsDialog = new SaveAsDialog(true)) { saveAsDialog.Text = Resources.SaveBehaviorAs; saveAsDialog.FileName = GetUniqueFileName(filename); // show the save dialogue isValidFile = (saveAsDialog.ShowDialog() == DialogResult.OK); if (isValidFile) { filename = saveAsDialog.FileName; } } } if (isValidFile) { // make sure we have the absolute filename Debug.Check(Path.IsPathRooted(filename)); // the file is new if it has no file manager bool isNew = (rootNode.FileManager == null); // create the selected file manager FileManagers.FileManager fm = _fileManagers[0].Create(filename, saveas ? (BehaviorNode)rootNode.Clone() : rootNode); if (fm == null) throw new Exception("Could not create file manager"); if (isNew) { // assign the new file manager and the new name rootNode.FileManager = fm; } // update the view so we get the new label if (dock != null) dock.BehaviorTreeView.Invalidate(); // save the behavior fm.Save(); // if the behavior was new, remove it from the list of new behaviors to the loaded ones if (isNew) { if (_newBehaviors.Remove(rootNode)) _loadedBehaviors.Add(rootNode); } if (saveas) { // rebuild the behaviors in the node explorer RebuildBehaviorList(); UIUtilities.ShowBehaviorTree(filename); } } else { // the user aborted return FileManagers.SaveResult.Cancelled; } } else { // simply save the behavior using the existing file manager FileManagers.SaveResult saveResult = rootNode.FileManager.Save(); if (FileManagers.SaveResult.Succeeded != saveResult) return saveResult; } CheckNode(rootNode, GetTreeNode(rootNode)); // if we were showing a different behavior before, return to it if (showNode && currNode != null) ShowBehavior(currNode); } finally { MainWindow.Instance.EnableFileWatcher(true); } return FileManagers.SaveResult.Succeeded; }
private void saveAsReferencedTree() { if (SelectedNode == null || SelectedNode == _rootNodeView || _rootNodeView.RootBehavior.FileManager == null) { return; } string folder = _rootNodeView.RootBehavior.Folder; if (string.IsNullOrEmpty(folder)) { folder = Path.GetDirectoryName(_rootNodeView.RootBehavior.FileManager.Filename); } string ext = Path.GetExtension(_rootNodeView.RootBehavior.FileManager.Filename); string filename = Path.Combine(folder, "rf_" + SelectedNode.Node.ExportClass); filename = Path.ChangeExtension(filename, ext); using(SaveAsDialog saveAsDialog = new SaveAsDialog(true)) { saveAsDialog.Text = Resources.SaveAsReference; saveAsDialog.FileName = _behaviorTreeList.GetUniqueFileName(filename); if (saveAsDialog.ShowDialog() == DialogResult.OK) { filename = saveAsDialog.FileName; // Remove the selected node. Node parentNode = SelectedNode.Node.Parent as Node; BaseNode.Connector parentConnector = SelectedNode.Node.ParentConnector; int index = parentConnector.GetChildIndex(SelectedNode.Node); parentNode.RemoveChild(parentConnector, SelectedNode.Node); // Create a new behavior node. BehaviorNode behaviorNode = Node.CreateBehaviorNode(SelectedNode.Node.ExportClass); ((Node)behaviorNode).AddChild(behaviorNode.GenericChildren, SelectedNode.Node); ((Behavior)behaviorNode).AgentType = ((Behavior)_rootNodeView.RootBehavior).AgentType; // Copy the used Pars from the current behavior to the new one. foreach(ParInfo par in((Behavior)_rootNodeView.RootBehavior).LocalVars) { List<Node.ErrorCheck> result = new List<Node.ErrorCheck>(); Plugin.CheckPar(SelectedNode.Node, par, ref result); if (result.Count > 0) { ((Behavior)behaviorNode).LocalVars.Add(par); } } // Save the new behavior node. behaviorNode.FileManager = _behaviorTreeList.GetFileManagers()[0].Create(filename, behaviorNode); behaviorNode.FileManager.Save(); _behaviorTreeList.RebuildBehaviorList(); // get the behavior we want to reference behaviorNode = _behaviorTreeList.LoadBehavior(filename); // Create a referenced node to hold the new behavior node. ReferencedBehavior refNode = Node.CreateReferencedBehaviorNode(_rootNodeView.RootBehavior, behaviorNode); // Add the new referenced node. Node newNode = refNode as Node; parentNode.AddChild(parentConnector, newNode, index); // Select the new node automatically. _selectedNodePending = newNode; _selectedNodePendingParent = SelectedNode.Parent; newNode.ResetId(true); UndoManager.Save(this.RootNode); LayoutChanged(); } } }