public WActorCreatorWindow()
        {
            InitializeComponent();

            m_Descriptors             = WResourceManager.GetActorDescriptors();
            ActorTypeView.ItemsSource = m_Descriptors.Values;

            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(ActorTypeView.ItemsSource);

            view.Filter = FilterActorTypes;

            SearchFilter = "";
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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
        }
Beispiel #4
0
        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
        }