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 override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var nodeJson = JObject.Load(reader); var actorName = (string)nodeJson["Name"]; SerializableDOMNode newNode; if (m_parent is WDOMLayeredGroupNode) { if (actorName == null) { return(null); } WDOMLayeredGroupNode layerNode = m_parent as WDOMLayeredGroupNode; string unlayedFourCC = layerNode.FourCC.ToString(); MapLayer layer = ChunkHeader.FourCCToLayer(ref unlayedFourCC); FourCC fourcc = FourCCConversion.GetEnumFromString(unlayedFourCC); Type newObjType = WResourceManager.GetTypeByName(actorName); if (newObjType == typeof(Actor)) { return(null); } newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); newNode.Layer = layer; } else if (m_parent is WDOMGroupNode) { WDOMGroupNode groupNode = m_parent as WDOMGroupNode; FourCC fourcc = groupNode.FourCC; if (fourcc == FourCC.ACTR || fourcc == FourCC.SCOB || fourcc == FourCC.TRES) { return(null); } if (fourcc == FourCC.TGDR || fourcc == FourCC.TGSC || fourcc == FourCC.TGOB) { if (actorName == null) { return(null); } Type newObjType = WResourceManager.GetTypeByName(actorName); if (newObjType == typeof(Actor)) { return(null); } newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); } else { Type newObjType = FourCCConversion.GetTypeFromEnum(groupNode.FourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); } } else { return(null); } newNode.SetParent(m_parent); try { var wproperties = newNode.GetType().GetProperties().Where(prop => { CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); if (wproperty_attribute == null) { return(false); } CustomAttributeData jsonignore_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "JsonIgnoreAttribute"); if (jsonignore_attribute != null) { return(false); } return(true); }); foreach (var prop in wproperties) { JToken jsonValue = nodeJson[prop.Name]; if (jsonValue == null) { continue; } if (prop.PropertyType == typeof(WTransform)) { if (!(jsonValue is JObject)) { continue; } JObject jsonValueObject = (JObject)jsonValue; WTransform transform = prop.GetValue(newNode, null) as WTransform; if (transform != null) { if (jsonValueObject.ContainsKey("Position")) { var position = transform.Position; position.X = ((float?)jsonValueObject["Position"]["X"]).GetValueOrDefault(); position.Y = ((float?)jsonValueObject["Position"]["Y"]).GetValueOrDefault(); position.Z = ((float?)jsonValueObject["Position"]["Z"]).GetValueOrDefault(); transform.Position = position; } if (jsonValueObject.ContainsKey("Rotation")) { var rotation = transform.Rotation; rotation.X = ((float?)jsonValueObject["Rotation"]["X"]).GetValueOrDefault(); rotation.Y = ((float?)jsonValueObject["Rotation"]["Y"]).GetValueOrDefault(); rotation.Z = ((float?)jsonValueObject["Rotation"]["Z"]).GetValueOrDefault(); rotation.W = ((float?)jsonValueObject["Rotation"]["W"]).GetValueOrDefault(); transform.Rotation = rotation; } if (jsonValueObject.ContainsKey("LocalScale")) { var localScale = transform.LocalScale; localScale.X = ((float?)jsonValueObject["LocalScale"]["X"]).GetValueOrDefault(1.0f); localScale.Y = ((float?)jsonValueObject["LocalScale"]["Y"]).GetValueOrDefault(1.0f); localScale.Z = ((float?)jsonValueObject["LocalScale"]["Z"]).GetValueOrDefault(1.0f); transform.LocalScale = localScale; } } } else if (prop.PropertyType == typeof(MessageReference)) { ushort messageID = (ushort)jsonValue; MessageReference msgRef = new MessageReference(messageID); prop.SetValue(newNode, msgRef); } else if (prop.PropertyType == typeof(Path_v2)) { int pathIndex = (int)jsonValue; WDOMNode cur_object = m_parent; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } List <Path_v2> pathsList = cur_object.GetChildrenOfType <Path_v2>(); if (pathIndex < 0) { prop.SetValue(newNode, null); } else if (pathIndex < pathsList.Count) { Path_v2 path = pathsList[pathIndex]; prop.SetValue(newNode, path); } } else if (prop.PropertyType == typeof(ExitData)) { int exitIndex = (int)jsonValue; WScene scene; CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); SourceScene source_scene = (SourceScene)wproperty_attribute.ConstructorArguments[4].Value; if (source_scene == SourceScene.Stage) { scene = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WScene; } else { WDOMNode cur_object = m_parent; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } scene = cur_object as WScene; } List <ExitData> exitsList = scene.GetChildrenOfType <ExitData>(); if (exitIndex < 0) { prop.SetValue(newNode, null); } else if (exitIndex < exitsList.Count) { ExitData exit = exitsList[exitIndex]; prop.SetValue(newNode, exit); } } else if (prop.PropertyType == typeof(MapEvent)) { int eventIndex = (int)jsonValue; WStage stage = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WStage; List <MapEvent> eventsList = stage.GetChildrenOfType <MapEvent>(); if (eventIndex < 0) { prop.SetValue(newNode, null); } else if (eventIndex < eventsList.Count) { MapEvent evnt = eventsList[eventIndex]; prop.SetValue(newNode, evnt); } } else { var value = Convert.ChangeType(jsonValue, prop.PropertyType); if (value != null) { prop.SetValue(newNode, value); } } } newNode.PostLoad(); return(newNode); } catch (Exception e) { // Creating the entity failed, so remove it from the scene. newNode.SetParent(null); throw; } }
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 }