private void PasteSelection() { WDOMNode selected = EditorSelection.PrimarySelectedObject; WDOMNode parent; if (selected is SerializableDOMNode) { parent = selected.Parent; } else if (selected is WDOMLayeredGroupNode) { parent = selected; } else if (selected is WDOMGroupNode) { parent = selected; } else { return; } JsonSerializer serial = new JsonSerializer(); serial.Converters.Add(new StringEnumConverter()); serial.Converters.Add(new Vector2Converter()); serial.Converters.Add(new Vector3Converter()); serial.Converters.Add(new QuaternionConverter()); serial.Converters.Add(new WDOMNodeJsonConverter(World, parent)); serial.Formatting = Formatting.Indented; List <SerializableDOMNode> pastedEntities; try { string text = Clipboard.GetText(); StringReader sr = new StringReader(text); JsonTextReader reader = new JsonTextReader(sr); pastedEntities = serial.Deserialize <List <SerializableDOMNode> >(reader); } catch (Exception e) { string error = "Failed to paste entities from the clipboard.\n\nFull error:\n"; error += e.GetType().FullName + "\n"; error += e.Message + "\n"; error += e.StackTrace; System.Windows.Forms.MessageBox.Show( error, "Failed to paste entities", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error ); return; } pastedEntities = pastedEntities.Where(x => x != null).ToList(); // Remove entities that failed to convert if (pastedEntities.Count > 0) { WDOMNode[] entitiesToPaste = pastedEntities.ToArray(); WDOMNode[] parents = new WDOMNode[entitiesToPaste.Length]; for (int i = 0; i < entitiesToPaste.Length; i++) { parents[i] = entitiesToPaste[i].Parent; } World.UndoStack.BeginMacro($"Paste {pastedEntities.Count} entities"); var undoAction = new WCreateEntitiesAction(entitiesToPaste, parents); BroadcastUndoEventGenerated(undoAction); EditorSelection.ClearSelection(); EditorSelection.AddToSelection(pastedEntities); World.UndoStack.EndMacro(); OnSelectionChanged(); // Update the right sidebar to show the new entity's properties } foreach (SerializableDOMNode node in pastedEntities) { node.IsSelected = true; } }
public void CreateEntity(string fourccStr) { if (fourccStr == null && !EditorSelection.SingleObjectSelected) { return; } SerializableDOMNode newNode = null; WDOMNode parentNode = null; WDOMNode selected = EditorSelection.PrimarySelectedObject; WDOMNode previousSibling = null; if (fourccStr != null) { // Creating an entity via the top menu. FourCC fourcc = FourCCConversion.GetEnumFromString(fourccStr); if (fourcc == FourCC.ACTR || fourcc == FourCC.SCOB || fourcc == FourCC.TRES) { parentNode = World.Map.FocusedScene.GetChildrenOfType <WDOMLayeredGroupNode>().Find(x => x.FourCC == fourcc); } else { parentNode = World.Map.FocusedScene.GetChildrenOfType <WDOMGroupNode>().Find(x => x.FourCC == fourcc); } } else if (selected is SerializableDOMNode) { // Creating an entity with an existing entity selected. parentNode = selected.Parent; previousSibling = selected; } else { // Creating an entity with a group node selected. parentNode = selected; } if (parentNode is WDOMLayeredGroupNode) { WDOMLayeredGroupNode lyrNode = parentNode as WDOMLayeredGroupNode; Type actorType = null; string actorName = null; if (lyrNode.FourCC.ToString().StartsWith("TRE")) { // Only allow treasure chests in TRES. actorName = "takara"; actorType = WResourceManager.GetTypeByName(actorName); } else { WActorCreatorWindow actorCreator = new WActorCreatorWindow(); if (actorCreator.ShowDialog() == true && actorCreator.Descriptor != null) { actorName = actorCreator.Descriptor.ActorName; if (actorName == "") { return; } actorType = WResourceManager.GetTypeByName(actorName); } } if (actorType == null || actorType == typeof(Actor)) { return; } string unlayedFourCC = lyrNode.FourCC.ToString(); MapLayer layer = ChunkHeader.FourCCToLayer(ref unlayedFourCC); FourCC fourcc = FourCCConversion.GetEnumFromString(unlayedFourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(actorType, fourcc, World); newNode.SetParent(lyrNode); newNode.Name = actorName; newNode.Layer = layer; newNode.PostLoad(); } else if (parentNode is WDOMGroupNode) { WDOMGroupNode grpNode = parentNode as WDOMGroupNode; if (grpNode.FourCC == FourCC.ACTR || grpNode.FourCC == FourCC.SCOB || grpNode.FourCC == FourCC.TRES) { return; } if (grpNode.FourCC == FourCC.TGDR || grpNode.FourCC == FourCC.TGSC || grpNode.FourCC == FourCC.TGOB) { WActorCreatorWindow actorCreator = new WActorCreatorWindow(); if (actorCreator.ShowDialog() == true && actorCreator.Descriptor != null) { string actorName = actorCreator.Descriptor.ActorName; if (actorName == "") { return; } Type actorType = WResourceManager.GetTypeByName(actorName); if (actorType == typeof(Actor)) { return; } newNode = (SerializableDOMNode)Activator.CreateInstance(actorType, grpNode.FourCC, World); newNode.SetParent(grpNode); newNode.Name = actorName; newNode.PostLoad(); } } else { Type newObjType = FourCCConversion.GetTypeFromEnum(grpNode.FourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, grpNode.FourCC, World); newNode.SetParent(grpNode); newNode.Name = "New"; newNode.PostLoad(); } } else { return; } if (newNode == null) { return; } newNode.Transform.Position = GetNewEntityPositionFromCamera(); newNode.PopulateDefaultProperties(); WDOMNode[] entitiesToCreate = { newNode }; WDOMNode[] parents = { newNode.Parent }; WDOMNode[] previousSiblings = { previousSibling }; newNode.Parent.IsExpanded = true; World.UndoStack.BeginMacro($"Create {newNode.Name}"); var undoAction = new WCreateEntitiesAction(entitiesToCreate, parents, previousSiblings); BroadcastUndoEventGenerated(undoAction); EditorSelection.ClearSelection(); EditorSelection.AddToSelection(newNode); World.UndoStack.EndMacro(); OnSelectionChanged(); // Update the right sidebar to show the new entity's properties }
public void CreateEntity(string fourccStr) { if (fourccStr == null && !EditorSelection.SingleObjectSelected) { return; } SerializableDOMNode newNode = null; WDOMNode parentNode = null; WDOMNode selected = EditorSelection.PrimarySelectedObject; WDOMNode previousSibling = null; if (fourccStr != null) { // Creating an entity via the top menu. FourCC fourcc = FourCCConversion.GetEnumFromString(fourccStr); if (fourcc == FourCC.ACTR || fourcc == FourCC.SCOB || fourcc == FourCC.TRES) { parentNode = World.Map.FocusedScene.GetChildrenOfType <WDOMLayeredGroupNode>().Find(x => x.FourCC == fourcc); } else if (fourcc == FourCC.PLYR) { WScene targetScene; WScene stage = World.Map.SceneList.First(x => x is WStage); var rooms = World.Map.SceneList.Where(x => x is WRoom); if (stage.GetChildrenOfType <SpawnPoint>().Count > 0) { // If the stage file has any spawns, then room spawns will not work. So always add to the stage in this case. targetScene = stage; } else if (rooms.Any(x => x.GetChildrenOfType <SpawnPoint>().Count > 0)) { // If the stage has no spawns but at least one of the rooms does, we want to add the new spawn to a room. // Otherwise, if we added it to the stage, it would break all existing room spawns. if (World.Map.FocusedScene is WRoom) { targetScene = World.Map.FocusedScene; } else { targetScene = rooms.First(); } } else { // Otherwise there must not be any spawns in the map yet, so just put it in the scene the player has selected. targetScene = World.Map.FocusedScene; } parentNode = targetScene.GetChildrenOfType <WDOMGroupNode>().Find(x => x.FourCC == fourcc); } else { parentNode = World.Map.FocusedScene.GetChildrenOfType <WDOMGroupNode>().Find(x => x.FourCC == fourcc); } } else if (selected is SerializableDOMNode) { // Creating an entity with an existing entity selected. parentNode = selected.Parent; previousSibling = selected; } else { // Creating an entity with a group node selected. parentNode = selected; } if (parentNode is WDOMLayeredGroupNode) { WDOMLayeredGroupNode lyrNode = parentNode as WDOMLayeredGroupNode; Type actorType = null; string actorName = null; if (lyrNode.FourCC.ToString().StartsWith("TRE")) { // Only allow treasure chests in TRES. actorName = "takara"; actorType = WResourceManager.GetTypeByName(actorName); } else { WActorCreatorWindow actorCreator = new WActorCreatorWindow(); if (actorCreator.ShowDialog() == true && actorCreator.Descriptor != null) { actorName = actorCreator.Descriptor.ActorName; if (actorName == "") { return; } actorType = WResourceManager.GetTypeByName(actorName); } } if (actorType == null || actorType == typeof(Actor)) { return; } string unlayedFourCC = lyrNode.FourCC.ToString(); MapLayer layer = ChunkHeader.FourCCToLayer(ref unlayedFourCC); FourCC fourcc = FourCCConversion.GetEnumFromString(unlayedFourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(actorType, fourcc, World); newNode.SetParent(lyrNode); newNode.Name = actorName; newNode.Layer = layer; newNode.PostLoad(); } else if (parentNode is WDOMGroupNode) { WDOMGroupNode grpNode = parentNode as WDOMGroupNode; if (grpNode.FourCC == FourCC.ACTR || grpNode.FourCC == FourCC.SCOB || grpNode.FourCC == FourCC.TRES) { return; } if (grpNode.FourCC == FourCC.TGDR || grpNode.FourCC == FourCC.TGSC || grpNode.FourCC == FourCC.TGOB) { WActorCreatorWindow actorCreator = new WActorCreatorWindow(); if (actorCreator.ShowDialog() == true && actorCreator.Descriptor != null) { string actorName = actorCreator.Descriptor.ActorName; if (actorName == "") { return; } Type actorType = WResourceManager.GetTypeByName(actorName); if (actorType == typeof(Actor)) { return; } newNode = (SerializableDOMNode)Activator.CreateInstance(actorType, grpNode.FourCC, World); newNode.SetParent(grpNode); newNode.Name = actorName; newNode.PostLoad(); } } else if (grpNode.FourCC == FourCC.RTBL) { RoomTableEntryNode rtbl_entry = new RoomTableEntryNode(grpNode.FourCC, World); rtbl_entry.Index = grpNode.Count(); newNode = rtbl_entry; newNode.SetParent(grpNode); newNode.PostLoad(); } else { Type newObjType = FourCCConversion.GetTypeFromEnum(grpNode.FourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, grpNode.FourCC, World); newNode.SetParent(grpNode); newNode.Name = "New"; newNode.PostLoad(); } } else { return; } if (newNode == null) { return; } newNode.Transform.Position = GetNewEntityPositionFromCamera(); newNode.PopulateDefaultProperties(); WDOMNode[] entitiesToCreate = { newNode }; WDOMNode[] parents = { newNode.Parent }; WDOMNode[] previousSiblings = { previousSibling }; newNode.Parent.IsExpanded = true; World.UndoStack.BeginMacro($"Create {newNode.Name}"); var undoAction = new WCreateEntitiesAction(entitiesToCreate, parents, previousSiblings); BroadcastUndoEventGenerated(undoAction); EditorSelection.ClearSelection(); EditorSelection.AddToSelection(newNode); World.UndoStack.EndMacro(); World.Map.FocusedScene = parentNode.Scene; // Focus the scene the new entity was added to (in case it's not the already focused scene). OnSelectionChanged(); // Update the right sidebar to show the new entity's properties }