예제 #1
0
        /* Display an entity hierarchy as a string */
        public static string HierarchyToString(List <cGUID> hierarchy)
        {
            CathodeFlowgraph currentFlowgraphToSearch = CurrentInstance.selectedFlowgraph;
            CathodeEntity    entity         = null;
            string           combinedString = "";

            for (int i = 0; i < hierarchy.Count; i++)
            {
                if (hierarchy[i] == new cGUID("00-00-00-00"))
                {
                    break;
                }
                entity = currentFlowgraphToSearch.GetEntityByID(hierarchy[i]);
                if (entity != null)
                {
                    combinedString += NodeDBEx.GetEntityName(entity.nodeID) + " -> ";
                }
                if (entity != null && entity.variant == EntityVariant.FUNCTION)
                {
                    CathodeFlowgraph flowRef = CurrentInstance.commandsPAK.GetFlowgraph(((FunctionEntity)entity).function);
                    if (flowRef != null)
                    {
                        currentFlowgraphToSearch = flowRef;
                    }
                }
            }
            if (combinedString.Length >= 4)
            {
                combinedString = combinedString.Substring(0, combinedString.Length - 4);
            }
            return(combinedString);
        }
예제 #2
0
        private static string GenerateNodeNameInternal(CathodeEntity entity, CathodeFlowgraph currentFlowgraph)
        {
            string desc = "";

            switch (entity.variant)
            {
            case EntityVariant.DATATYPE:
                desc = NodeDBEx.GetParameterName(((DatatypeEntity)entity).parameter) + " (DataType " + ((DatatypeEntity)entity).type.ToString() + ")";
                break;

            case EntityVariant.FUNCTION:
                desc = NodeDBEx.GetEntityName(entity.nodeID) + " (" + NodeDBEx.GetParameterName(((FunctionEntity)entity).function) + ")";
                break;

            case EntityVariant.OVERRIDE:
                //desc = NodeDBEx.GetEntityName(entity.nodeID) + " (" + HierarchyToString(((OverrideEntity)entity).hierarchy, currentFlowgraph) + ")";
                desc = NodeDBEx.GetEntityName(entity.nodeID) + " (*OVERRIDE*)";
                break;

            case EntityVariant.PROXY:
                //desc = NodeDBEx.GetEntityName(entity.nodeID) + " (" + HierarchyToString(((ProxyEntity)entity).hierarchy, currentFlowgraph) + ")";
                desc = NodeDBEx.GetEntityName(entity.nodeID) + " (*PROXY*)";
                break;

            case EntityVariant.NOT_SETUP:
                //desc = NodeDBEx.GetEntityName(entity.nodeID);
                desc = NodeDBEx.GetEntityName(entity.nodeID) + " (*NOT SETUP*)";
                break;
            }
            return("[" + entity.nodeID.ToString() + "] " + desc);
        }
예제 #3
0
        private void LoadFlowgraph(string FileName)
        {
            ClearUI(false, true, true);
            CathodeFlowgraph entry = CurrentInstance.commandsPAK.Flowgraphs[CurrentInstance.commandsPAK.GetFileIndex(FileName)];

            CurrentInstance.selectedFlowgraph = entry;
            Cursor.Current = Cursors.WaitCursor;

            flowgraph_content.BeginUpdate();
            List <CathodeEntity> entities = entry.GetEntities();

            for (int i = 0; i < entities.Count; i++)
            {
                string desc = EditorUtils.GenerateNodeName(entities[i], CurrentInstance.selectedFlowgraph);
                flowgraph_content.Items.Add(desc);
                flowgraph_content_RAW.Add(desc);
            }
            flowgraph_content.EndUpdate();

#if DEBUG //TODO: PULL THIS INTO STABLE
            editFlowgraphResources.Visible = true;
#endif

            groupBox1.Text = entry.name;
            Cursor.Current = Cursors.Default;
        }
예제 #4
0
        public CathodeEditorGUI_AddOrEditResource(CathodeFlowgraph flowgraph)
        {
            _flow = flowgraph;

            //FOR TESTING ONLY
            resRef.AddRange(_flow.resources);

            Setup();
        }
        public CathodeEditorGUI_AddNode(CathodeFlowgraph _flow, List <CathodeFlowgraph> _flows)
        {
            flow              = _flow;
            availableFlows    = _flows.OrderBy(o => o.name).ToList();
            availableEntities = CathodeEntityDatabase.GetEntities();
            InitializeComponent();

            //quick hack to reload dropdown
            createDatatypeEntity.Checked = true;
            createFunctionEntity.Checked = true;
        }
예제 #6
0
 /* Utility: generate nice entity name to display in UI */
 public static string GenerateNodeName(CathodeEntity entity, CathodeFlowgraph currentFlowgraph)
 {
     if (CurrentInstance.commandsPAK == null)
     {
         return("");
     }
     if (hasFinishedCachingEntityNames && cachedEntityName.ContainsKey(entity.nodeID))
     {
         return(cachedEntityName[entity.nodeID]);
     }
     return(GenerateNodeNameInternal(entity, currentFlowgraph));
 }
예제 #7
0
    private string GetFlowgraphAssetPath(CathodeFlowgraph flowgraph, bool resourcePath = false)
    {
        string basePath = SharedVals.instance.LevelName + "/Flowgraphs/" + flowgraph.name.Replace("\\", "/").Replace(":", "_");

        if (resourcePath)
        {
            return(basePath);
        }
        else
        {
            return("Assets/Resources/" + basePath + ".prefab");
        }
    }
예제 #8
0
    private IEnumerator LoadPlayerTriggerBoxNodes(CathodeFlowgraph flowgraph, GameObject parentTransform, System.Action <int, GameObject> loadModelCallback)
    {
        PreloadedFlowgraphContent content = preloadedPlayerTriggerBoxNodes.FirstOrDefault(o => o.flowraphID == flowgraph.nodeID);

        for (int i = 0; i < content.nodeNames.Count; i++)
        {
            GameObject thisNodeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
            thisNodeGO.name                    = content.nodeNames[i];
            thisNodeGO.transform.parent        = parentTransform.transform;
            thisNodeGO.transform.localPosition = content.nodeTransforms[i].position;
            thisNodeGO.transform.localRotation = content.nodeTransforms[i].rotation;
            thisNodeGO.transform.localScale    = new Vector3(content.half_dimensions.y, content.half_dimensions.z, content.half_dimensions.x) * 2; //i dont think this is right
        }
        yield break;
    }
예제 #9
0
    private PreloadedFlowgraphContent PreloadFlowgraphContent(CathodeFlowgraph flowgraph, uint typeID)
    {
        PreloadedFlowgraphContent content = new PreloadedFlowgraphContent();

        content.flowraphID = flowgraph.nodeID;
        List <CathodeNodeEntity> models = GetAllOfType(ref flowgraph, typeID);

        for (int i = 0; i < models.Count; i++)
        {
            CathodeNodeEntity thisNode     = models[i];
            List <int>        modelIndexes = new List <int>();
            List <UInt32>     resourceID   = new List <UInt32>();
            foreach (CathodeParameterReference paramRef in thisNode.nodeParameterReferences)
            {
                CathodeParameter param = commandsPAK.GetParameter(paramRef.offset);
                if (param == null)
                {
                    continue;
                }
                if (param.dataType != CathodeDataType.SHORT_GUID)
                {
                    continue;
                }
                resourceID.Add(((CathodeResource)param).resourceID);
            }
            for (int x = 0; x < resourceID.Count; x++)
            {
                List <CathodeResourceReference> resRef = flowgraph.GetResourceReferencesByID(resourceID[x]);
                for (int y = 0; y < resRef.Count; y++)
                {
                    if (resRef[y].entryType != CathodeResourceReferenceType.RENDERABLE_INSTANCE)
                    {
                        continue;                                                                          //Ignoring collision maps, etc, for now
                    }
                    for (int p = 0; p < resRef[y].entryCountREDS; p++)
                    {
                        modelIndexes.Add(redsBIN[resRef[y].entryIndexREDS] + p);
                    }
                }
            }
            content.nodeModelIDs.Add(modelIndexes);
            content.nodeTransforms.Add(GetTransform(ref thisNode));
            content.half_dimensions = GetHalfDimensions(ref thisNode);
            content.nodeNames.Add(NodeDB.GetNodeTypeName(thisNode.nodeType, ref commandsPAK) + ": " + NodeDB.GetFriendlyName(thisNode.nodeID));
        }
        return(content);
    }
예제 #10
0
    private IEnumerator LoadModelReferenceNodes(CathodeFlowgraph flowgraph, GameObject parentTransform, System.Action <int, GameObject> loadModelCallback)
    {
        PreloadedFlowgraphContent content = preloadedModelReferenceNodes.FirstOrDefault(o => o.flowraphID == flowgraph.nodeID);

        for (int i = 0; i < content.nodeNames.Count; i++)
        {
            GameObject thisNodeGO = new GameObject(content.nodeNames[i]);
            thisNodeGO.transform.parent        = parentTransform.transform;
            thisNodeGO.transform.localPosition = content.nodeTransforms[i].position;
            thisNodeGO.transform.localRotation = content.nodeTransforms[i].rotation;
            for (int x = 0; x < content.nodeModelIDs[i].Count; x++)
            {
                loadModelCallback(content.nodeModelIDs[i][x], thisNodeGO);
            }
        }
        yield break;
    }
예제 #11
0
        public static string GetNodeTypeName(UInt32 id, ref CommandsPAK pak) //This is performed separately to be able to remap nodes that are flowgraphs
        {
            if (id == 0)
            {
                return("");
            }
            foreach (ShortGUIDDescriptor db_entry in cathode_id_map)
            {
                if (db_entry.ID == id)
                {
                    return(db_entry.Description);
                }
            }
            CathodeFlowgraph flow = pak.GetFlowgraph(id); if (flow == null)

            {
                return(id.ToString());
            }

            return(flow.name);
        }
예제 #12
0
        public static string GetNodeTypeName(byte[] id, CommandsPAK pak) //This is performed separately to be able to remap nodes that are flowgraphs
        {
            if (id == null)
            {
                return("");
            }
            foreach (ShortGUIDDescriptor db_entry in cathode_id_map)
            {
                if (db_entry.ID.SequenceEqual(id))
                {
                    return(db_entry.Description);
                }
            }
            CathodeFlowgraph flow = pak.GetFlowgraph(id); if (flow == null)

            {
                return(BitConverter.ToString(id));
            }

            return(flow.name);
        }
예제 #13
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                return;
            }
            for (int i = 0; i < CurrentInstance.commandsPAK.Flowgraphs.Count; i++)
            {
                if (CurrentInstance.commandsPAK.Flowgraphs[i].name == textBox1.Text)
                {
                    MessageBox.Show("Failed to create flowgraph.\nA flowgraph with this name already exists.", "Flowgraph already exists.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            CathodeFlowgraph newFlowgraph = new CathodeFlowgraph();

            newFlowgraph.name   = textBox1.Text;
            newFlowgraph.nodeID = Utilities.GenerateGUID(DateTime.Now.ToString("G"));
            CurrentInstance.commandsPAK.Flowgraphs.Add(newFlowgraph);
            this.Close();
        }
예제 #14
0
        public CathodeEditorGUI_AddPin(CathodeEntity entity, CathodeFlowgraph flowgraph)
        {
            _entity = entity;
            InitializeComponent();

            _entityList = flowgraph.GetEntities();
            _entityList = _entityList.OrderBy(o => EditorUtils.GenerateNodeName(o, flowgraph).Substring(13)).ToList <CathodeEntity>();

            pin_in_node.BeginUpdate();
            for (int i = 0; i < _entityList.Count; i++)
            {
                string this_node_string = EditorUtils.GenerateNodeName(_entityList[i], flowgraph);
                pin_in_node.Items.Add(this_node_string);
            }
            pin_in_node.EndUpdate();

            pin_out_node.Text    = EditorUtils.GenerateNodeName(_entity, flowgraph);
            pin_out_node.Enabled = false;

            RefreshPinInParams();
            RefreshPinOutParams();
        }
예제 #15
0
    private IEnumerator RecursiveLoad(CathodeFlowgraph flowgraph, GameObject parentTransform, System.Action <int, GameObject> loadModelCallback)
    {
        for (int i = 0; i < flowgraph.nodes.Count; i++)
        {
            CathodeNodeEntity node     = flowgraph.nodes[i];
            CathodeFlowgraph  nextCall = commandsPAK.GetFlowgraph(node.nodeType);
            if (nextCall == null)
            {
                continue;
            }
            PosAndRot  trans           = GetTransform(ref node);
            GameObject nextFlowgraphGO = new GameObject(nextCall.name);
            nextFlowgraphGO.transform.parent        = parentTransform.transform;
            nextFlowgraphGO.transform.localPosition = trans.position;
            nextFlowgraphGO.transform.localRotation = trans.rotation;
            StartCoroutine(RecursiveLoad(nextCall, nextFlowgraphGO, loadModelCallback));
        }

        StartCoroutine(LoadModelReferenceNodes(flowgraph, parentTransform, loadModelCallback));
        StartCoroutine(LoadPlayerTriggerBoxNodes(flowgraph, parentTransform, loadModelCallback));

        yield break;
    }
예제 #16
0
        /* Resolve a node hierarchy */
        public static CathodeEntity ResolveHierarchy(List <cGUID> hierarchy, out CathodeFlowgraph containedFlowgraph)
        {
            CathodeFlowgraph currentFlowgraphToSearch = CurrentInstance.selectedFlowgraph;
            CathodeEntity    entity = null;

            for (int i = 0; i < hierarchy.Count; i++)
            {
                if (hierarchy[i] == new cGUID("00-00-00-00"))
                {
                    break;
                }
                entity = currentFlowgraphToSearch.GetEntityByID(hierarchy[i]);
                if (entity != null && entity.variant == EntityVariant.FUNCTION)
                {
                    CathodeFlowgraph flowRef = CurrentInstance.commandsPAK.GetFlowgraph(((FunctionEntity)entity).function);
                    if (flowRef != null)
                    {
                        currentFlowgraphToSearch = flowRef;
                    }
                }
            }
            containedFlowgraph = currentFlowgraphToSearch;
            return(entity);
        }
예제 #17
0
        public void PopulateUI(CathodeResource cResource, cGUID paramID, CathodeFlowgraph selected_flowgraph)
        {
            GUID_VARIABLE_DUMMY.Text = NodeDBEx.GetParameterName(paramID) + " (" + paramID.ToString() + ")";
            resRef = cResource;

            if (cResource.resourceID.val != null)
            {
                textBox2.Text = BitConverter.ToString(new byte[] { cResource.resourceID.val[0] });
                textBox3.Text = BitConverter.ToString(new byte[] { cResource.resourceID.val[1] });
                textBox5.Text = BitConverter.ToString(new byte[] { cResource.resourceID.val[2] });
                textBox4.Text = BitConverter.ToString(new byte[] { cResource.resourceID.val[3] });
            }

            /*
             * List<RenderableElement> redsList = new List<RenderableElement>();
             * CathodeResourceReference resRef = selected_flowgraph.resources.FirstOrDefault(o => o.resourceRefID == cResource.resourceID);
             * if (resRef == null || resRef.entryType != CathodeResourceReferenceType.RENDERABLE_INSTANCE) return;
             * for (int p = 0; p < resRef.entryCountREDS; p++) redsList.Add(redsBIN.GetRenderableElement(resRef.entryIndexREDS + p));
             * if (resRef.entryCountREDS != redsList.Count || redsList.Count == 0) return; //TODO: handle this nicer
             * CathodeEditorGUI_EditResource res_editor = new CathodeEditorGUI_EditResource(modelPAK.GetCS2s(), redsList);
             * res_editor.Show();
             * res_editor.EditComplete += new FinishedEditingIndexes(res_editor_submitted);
             */
        }
예제 #18
0
 private List <CathodeNodeEntity> GetAllOfType(ref CathodeFlowgraph flowgraph, UInt32 nodeType)
 {
     return(flowgraph.nodes.FindAll(o => o.nodeType == nodeType));
 }
예제 #19
0
        /* Utility: generate a list of suggested parameters for an entity */
        public static List <string> GenerateParameterList(CathodeEntity entity, out bool didGenerateFromDB)
        {
            didGenerateFromDB = false;
            List <string> items = new List <string>();

            if (CurrentInstance.commandsPAK == null)
            {
                return(items);
            }
            switch (entity.variant)
            {
            case EntityVariant.FUNCTION:
                cGUID function = ((FunctionEntity)entity).function;
                List <CathodeEntityDatabase.ParameterDefinition> parameters = CathodeEntityDatabase.GetParametersFromEntity(function);
                if (parameters != null)
                {
                    didGenerateFromDB = true;
                    for (int i = 0; i < parameters.Count; i++)
                    {
                        items.Add(parameters[i].name);
                    }
                }
                else
                {
                    string[] options = NodeDB.GetEntityParameterList(NodeDBEx.GetParameterName(function));
                    items.Add("trigger"); items.Add("reference");     //TODO: populate all params from EntityMethodInterface?
                    if (options == null)
                    {
                        CathodeFlowgraph flow = CurrentInstance.commandsPAK.GetFlowgraph(function);
                        if (flow == null)
                        {
                            break;
                        }
                        for (int i = 0; i < flow.datatypes.Count; i++)
                        {
                            string to_add = NodeDBEx.GetParameterName(flow.datatypes[i].parameter);
                            //TODO: also return datatype here
                            if (!items.Contains(to_add))
                            {
                                items.Add(to_add);
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < options.Length; i++)
                        {
                            if (!items.Contains(options[i]))
                            {
                                items.Add(options[i]);
                            }
                        }
                    }
                }
                break;

            case EntityVariant.DATATYPE:
                items.Add(NodeDBEx.GetParameterName(((DatatypeEntity)entity).parameter));
                break;
                //TODO: support other types here
            }
            items.Sort();
            return(items);
        }
예제 #20
0
    private void LoadFlowgraphAssets()
    {
        //First, make dummy prefabs of all flowgraphs
        GameObject rootGO = new GameObject();

        AssetDatabase.StartAssetEditing();
        for (int i = 0; i < levelData.CommandsPAK.AllFlowgraphs.Count; i++)
        {
            string fullFilePath  = GetFlowgraphAssetPath(levelData.CommandsPAK.AllFlowgraphs[i]);
            string fileDirectory = GetDirectory(fullFilePath);
            if (!Directory.Exists(fileDirectory))
            {
                Directory.CreateDirectory(fileDirectory);
            }
            if (!File.Exists(fullFilePath))
            {
                PrefabUtility.SaveAsPrefabAsset(rootGO, fullFilePath);
            }
        }
        AssetDatabase.StopAssetEditing();

        //Then, populate the prefabs for all flowgraphs
        AssetDatabase.StartAssetEditing();
        for (int i = 0; i < levelData.CommandsPAK.AllFlowgraphs.Count; i++)
        {
            GameObject flowgraphGO = new GameObject(levelData.CommandsPAK.AllFlowgraphs[i].name);
            string     nodeType    = "";
            for (int x = 0; x < levelData.CommandsPAK.AllFlowgraphs[i].nodes.Count; x++)
            {
                CathodeFlowgraph flowgraphRef = levelData.CommandsPAK.GetFlowgraph(levelData.CommandsPAK.AllFlowgraphs[i].nodes[x].nodeType);
                GameObject       nodeGO       = null;
                if (flowgraphRef != null)
                {
                    //This is a reference to another flowgraph
                    GameObject flowgraphAsset = Resources.Load <GameObject>(GetFlowgraphAssetPath(flowgraphRef, true));
                    nodeGO      = PrefabUtility.InstantiatePrefab(flowgraphAsset) as GameObject;
                    nodeGO.name = flowgraphRef.name;
                }
                else
                {
                    //This is a node
                    nodeGO   = new GameObject(CathodeLib.NodeDB.GetFriendlyName(levelData.CommandsPAK.AllFlowgraphs[i].nodes[x].nodeID));
                    nodeType = CathodeLib.NodeDB.GetNodeTypeName(levelData.CommandsPAK.AllFlowgraphs[i].nodes[x].nodeType, ref levelData.CommandsPAK);
                }
                nodeGO.transform.parent = flowgraphGO.transform;
                //TODO: this can all be optimised massively
                List <uint> resourceIDs = new List <uint>();
                foreach (CathodeParameterReference paramRef in levelData.CommandsPAK.AllFlowgraphs[i].nodes[x].nodeParameterReferences)
                {
                    CathodeParameter param = levelData.CommandsPAK.GetParameter(paramRef.offset);
                    if (param == null)
                    {
                        continue;
                    }
                    switch (param.dataType)
                    {
                    case CathodeDataType.POSITION:
                        CathodeTransform transform = (CathodeTransform)param;
                        nodeGO.transform.localPosition = transform.position;
                        nodeGO.transform.localRotation = Quaternion.Euler(transform.rotation);
                        break;

                    case CathodeDataType.SHORT_GUID:
                        resourceIDs.Add(((CathodeResource)param).resourceID);
                        break;
                    }
                }
                switch (nodeType)
                {
                case "PlayerTriggerBox":
                    //nodeGO.AddComponent<BoxCollider>().bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
                    break;

                case "PositionMarker":
                    //debug render marker
                    break;

                case "Sound":
                    //nodeGO.AddComponent<AudioSource>().clip = null;
                    break;

                case "PlayEnvironmentAnimation":
                    break;

                case "ParticleEmitterReference":
                    break;

                case "ModelReference":
                    for (int y = 0; y < resourceIDs.Count; y++)
                    {
                        List <CathodeResourceReference> resourceReference = levelData.CommandsPAK.AllFlowgraphs[i].GetResourceReferencesByID(resourceIDs[y]);
                        for (int z = 0; z < resourceReference.Count; z++)
                        {
                            if (resourceReference[z].entryType != CathodeResourceReferenceType.RENDERABLE_INSTANCE)
                            {
                                continue;                                                                                         //Ignoring collision maps, etc, for now
                            }
                            //TODO: This is kinda hacked for now while we're not saving with submeshes
                            for (int p = 0; p < resourceReference[z].entryCountREDS; p++)
                            {
                                int        thisIndex        = levelData.RenderableREDS.Entries[resourceReference[z].entryIndexREDS].ModelIndex + p;
                                string     meshResourcePath = GetMeshAssetPath(thisIndex, true) + "_" + p;
                                GameObject newSubmesh       = new GameObject(meshResourcePath);
                                newSubmesh.transform.parent        = nodeGO.transform;
                                newSubmesh.transform.localScale    = new Vector3(1, 1, 1) * levelData.ModelsBIN.Models[thisIndex].ScaleFactor;
                                newSubmesh.transform.localPosition = Vector3.zero;
                                newSubmesh.transform.localRotation = Quaternion.identity;
                                newSubmesh.AddComponent <MeshFilter>().sharedMesh       = Resources.Load <Mesh>(GetMeshAssetPath(thisIndex, true) + "_" + p);
                                newSubmesh.AddComponent <MeshRenderer>().sharedMaterial = Resources.Load <Material>("DUMMY");   //TODO: replace
                            }
                        }
                    }
                    break;
                }
            }
            PrefabUtility.SaveAsPrefabAsset(flowgraphGO, GetFlowgraphAssetPath(levelData.CommandsPAK.AllFlowgraphs[i]));
            Destroy(flowgraphGO);
        }
        AssetDatabase.StopAssetEditing();
        Destroy(rootGO);
    }
        private void createEntity(object sender, EventArgs e)
        {
            cGUID thisID = Utilities.GenerateGUID(DateTime.Now.ToString("G"));

            if (createDatatypeEntity.Checked)
            {
                //Make the DatatypeEntity
                DatatypeEntity newEntity = new DatatypeEntity(thisID);
                newEntity.type      = (CathodeDataType)entityVariant.SelectedIndex;
                newEntity.parameter = Utilities.GenerateGUID(textBox1.Text);

                //Make the parameter to give this DatatypeEntity a value (the only time you WOULDN'T want this is if the val is coming from a linked entity)
                CathodeParameter thisParam = null;
                switch (newEntity.type)
                {
                case CathodeDataType.POSITION:
                    thisParam = new CathodeTransform();
                    break;

                case CathodeDataType.FLOAT:
                    thisParam = new CathodeFloat();
                    break;

                case CathodeDataType.FILEPATH:
                case CathodeDataType.STRING:
                    thisParam = new CathodeString();
                    break;

                case CathodeDataType.SPLINE_DATA:
                    thisParam = new CathodeSpline();
                    break;

                case CathodeDataType.ENUM:
                    thisParam = new CathodeEnum();
                    ((CathodeEnum)thisParam).enumID = new cGUID("4C-B9-82-48");     //ALERTNESS_STATE is the first alphabetically
                    break;

                case CathodeDataType.SHORT_GUID:
                    thisParam = new CathodeResource();
                    ((CathodeResource)thisParam).resourceID = new cGUID("00-00-00-00");
                    break;

                case CathodeDataType.BOOL:
                    thisParam = new CathodeBool();
                    break;

                case CathodeDataType.DIRECTION:
                    thisParam = new CathodeVector3();
                    break;

                case CathodeDataType.INTEGER:
                    thisParam = new CathodeInteger();
                    break;
                }
                newEntity.parameters.Add(new CathodeLoadedParameter(newEntity.parameter, thisParam));

                //Add to flowgraph & save name
                flow.datatypes.Add(newEntity);
                if (NodeDB.GetCathodeName(newEntity.parameter) == newEntity.parameter.ToString())
                {
                    NodeDBEx.AddNewParameterName(newEntity.parameter, textBox1.Text);
                }
                NewEntity = newEntity;
            }
            else if (createFunctionEntity.Checked)
            {
                //Create FunctionEntity
                FunctionEntity newEntity = new FunctionEntity(thisID);
                switch (entityVariant.Text)
                {
                //TODO: find a nicer way of auto selecting this (E.G. can we reflect to class names?)
                case "CAGEAnimation":
                    newEntity = new CAGEAnimation(thisID);
                    break;

                case "TriggerSequence":
                    newEntity = new TriggerSequence(thisID);
                    break;
                }
                newEntity.function = CathodeEntityDatabase.GetEntityAtIndex(entityVariant.SelectedIndex).guid;
                //TODO: auto populate params here

                //Add to flowgraph & save name
                flow.functions.Add(newEntity);
                NodeDBEx.AddNewNodeName(thisID, textBox1.Text);
                NewEntity = newEntity;
            }
            else if (createFlowgraphEntity.Checked)
            {
                //Create FunctionEntity
                FunctionEntity   newEntity         = new FunctionEntity(thisID);
                CathodeFlowgraph selectedFlowgraph = availableFlows.FirstOrDefault(o => o.name == entityVariant.Text);
                if (selectedFlowgraph == null)
                {
                    MessageBox.Show("Failed to look up flowgraph!\nPlease report this issue on GitHub.\n\n" + entityVariant.Text, "Could not find flowgraph!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                newEntity.function = selectedFlowgraph.nodeID;

                //Add to flowgraph & save name
                flow.functions.Add(newEntity);
                NodeDBEx.AddNewNodeName(thisID, textBox1.Text);
                NewEntity = newEntity;
            }

            this.Close();
        }