Beispiel #1
0
    public RoomNode CreateRoomNode(string _roomName, bool _isTerminal = true)
    {
        RoomNode l_roomNode = new RoomNode
        {
            title      = _roomName,
            roomID     = Guid.NewGuid().ToString(),
            roomType   = _roomName,
            isTerminal = _isTerminal
        };

        //set node position and size
        l_roomNode.SetPosition(new Rect(20, 20, 200, 300));

        //boton para marcar si es terminal o no
        Toggle l_isTerminalRoom = new Toggle();

        l_isTerminalRoom.text = "isTerminal";
        l_isTerminalRoom.RegisterValueChangedCallback(evt => l_roomNode.isTerminal = evt.newValue);
        l_isTerminalRoom.value = l_roomNode.isTerminal;
        l_isTerminalRoom.SetValueWithoutNotify(l_isTerminalRoom.value);
        l_roomNode.titleContainer.Add(l_isTerminalRoom);
        l_roomNode.RefreshExpandedState();


        //creamos un textField donde poner el tipo de habitacion
        TextField l_roomTypeTextField = new TextField(string.Empty);

        //registramos un callback que hara lo siguiente cuando se llame;
        l_roomTypeTextField.RegisterValueChangedCallback(evt =>
        {
            l_roomNode.roomType = evt.newValue; //cambiamos el tipo de hab. al nuevo valor
            l_roomNode.title    = evt.newValue; //actualizamos el titulo del nodo con el nuevo valor
        });
        //para no triggear el callback de arriba, utilizamos el without notify y actualizamos los textos
        l_roomTypeTextField.SetValueWithoutNotify(l_roomNode.title); //ponemos el nombre generado
        l_roomNode.mainContainer.Add(l_roomTypeTextField);           //añadimos el nombre al titulo del nodo


        Button l_addInputPortButton = new Button();

        l_addInputPortButton.text = "Add Input";
        l_addInputPortButton.clickable.clicked += () => GenerateInputPortsOnNode(l_roomNode);
        l_roomNode.titleContainer.Add(l_addInputPortButton);

        //botton para añadir puertos de salida
        Button l_addOutPortButton = new Button();

        l_addOutPortButton.text = "Add Output";
        l_addOutPortButton.clickable.clicked += () => GenerateOutputPortsOnNode(l_roomNode);
        l_roomNode.titleContainer.Add(l_addOutPortButton);

        //if (l_roomNode.IsSelected(l_roomNode)) { m_selectedRoomNode = l_roomNode;  Debug.Log("selected room " +); }


        return(l_roomNode);
    }
    private void ConnectLoadedNodes()
    {
        for (int i = 0; i < m_roomsList.Count; i++)
        {
            List <RoomNodeConnectionsData> l_connectionDataCache = m_graphToLoadCache.m_roomConnectionsDataList.Where(x => x.baseNodeId == m_roomsList[i].roomID).ToList();
            for (int j = 0; j < l_connectionDataCache.Count; j++)
            {
                string   targetNodeId   = l_connectionDataCache[j].targetNodeId;
                RoomNode targetRoom     = m_roomsList.First(x => x.roomID == targetNodeId);
                string   targetPortName = l_connectionDataCache[j].targetPortName;

                Port targetPort = m_targetGraph.ports.ToList().First(x => (x.node as RoomNode) == targetRoom && x.portName == targetPortName);

                LinkRoomPorts(m_roomsList[i].outputContainer[j].Q <Port>(), targetPort);

                targetRoom.SetPosition(new Rect(m_graphToLoadCache.m_roomNodeDataList.First(x => x.nodeID == targetRoom.roomID).position, m_targetGraph.defaultNodeSize));

                //targetRoom.transform.position = m_graphToLoadCache.roomNodeData.First(x => x.nodeID == targetRoom.roomID).position;
            }
        }
    }
    private void GenereteNeighbourNodes(RoomNode _baseRoom)
    {
        int l_numberOfConnections;

        //si es la 'start' room puedo crear 4 conexiones, sino solo puedo crear 3 (1 viene con el input previo)
        if (_baseRoom.roomType == "Start")
        {
            l_numberOfConnections = Random.Range(1, 5);
        }
        else
        {
            l_numberOfConnections = Random.Range(1, 4);
        }

        //cojo todos los strings posibles -> no usamos los que contengan stairs
        List <string> l_posibleBasePortNames = m_UtilitiesInstance.m_myConnectionsDictionary.Keys.ToList().Where(x => !x.Contains("stairs")).ToList();

        //busco en el diccionary el tipo de input que tiene la _baseRoom
        string l_conectedInputName = m_roomAndItsInputsDictionary.ToList().Find(x => x.Key == _baseRoom).Value;

        //dependiendo del input que tengo, debo limitar las opciones de mis outputs
        if (l_conectedInputName != null)
        {
            if (l_conectedInputName.Contains("up"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("up"));
            }
            else if (l_conectedInputName.Contains("down"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("down"));
            }
            else if (l_conectedInputName.Contains("left"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("left"));
            }
            else if (l_conectedInputName.Contains("right"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("right"));
            }
        }

        for (int i = 0; i < l_numberOfConnections; i++)
        {
            //seleccionar un tipo de habitacion random
            int    l_typesOfRoomsCount    = m_UtilitiesInstance.m_typesOfRoomsList.Count();
            int    l_randomSelectionValue = Random.Range(0, l_typesOfRoomsCount);
            string l_selectedRoomType     = m_UtilitiesInstance.m_typesOfRoomsList[l_randomSelectionValue];

            //seleccionar un nombre aleatorio de la lista l_posibleBasePortNames para el puerto
            int    l_numberOfDifferentConnections = l_posibleBasePortNames.Count();
            int    l_randomSelectionPortName      = Random.Range(0, l_numberOfDifferentConnections);
            string l_selectedNameOfBasePort       = l_posibleBasePortNames.ElementAt(l_randomSelectionPortName);
            string l_nameOfTargetPortByReference  = m_UtilitiesInstance.ReturnConnectionNameByReference(l_selectedNameOfBasePort);

            //spawnear la habitacion y añadirla al graph (+dictionary +list +counter)
            RoomNode l_newRoomToSpawn = m_graphView.CreateRoomNode(l_selectedRoomType, true);
            m_graphView.AddElement(l_newRoomToSpawn);
            m_roomAndItsInputsDictionary.Add(l_newRoomToSpawn, l_nameOfTargetPortByReference);
            m_currentlyInstantiatedRoomList.Add(l_newRoomToSpawn);
            m_numberOfRoomsInstantiated++;


            //DONT REPEAT NAMES OF PREVIOUS PORTS
            if (l_selectedNameOfBasePort.Contains("up"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("up"));
            }
            else if (l_selectedNameOfBasePort.Contains("down"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("down"));
            }
            else if (l_selectedNameOfBasePort.Contains("left"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("left"));
            }
            else if (l_selectedNameOfBasePort.Contains("right"))
            {
                l_posibleBasePortNames.RemoveAll(x => x.Contains("right"));
            }

            //generate and connect ports
            Port l_basePort   = m_graphView.GenerateOutputPortsOnNode(_baseRoom, l_selectedNameOfBasePort);
            Port l_targetPort = m_graphView.GenerateInputPortsOnNode(l_newRoomToSpawn, l_nameOfTargetPortByReference);
            LinkRoomPorts(l_basePort, l_targetPort);

            //assign new position to new node
            Vector3 l_newPosition  = Vector3.zero;
            Vector3 l_prevPosition = _baseRoom.transform.position;
            if (l_basePort.portName.Contains("up"))
            {
                l_newPosition.x = l_prevPosition.x;
                l_newPosition.y = l_prevPosition.y - 200;
                l_newPosition.z = l_prevPosition.z;
            }
            if (l_basePort.portName.Contains("down"))
            {
                l_newPosition.x = l_prevPosition.x;
                l_newPosition.y = l_prevPosition.y + 200;
                l_newPosition.z = l_prevPosition.z;
            }
            if (l_basePort.portName.Contains("left"))
            {
                l_newPosition.x = l_prevPosition.x - 400;
                l_newPosition.y = l_prevPosition.y;
                l_newPosition.z = l_prevPosition.z;
            }
            if (l_basePort.portName.Contains("right"))
            {
                l_newPosition.x = l_prevPosition.x + 400;
                l_newPosition.y = l_prevPosition.y;
                l_newPosition.z = l_prevPosition.z;
            }

            //AL USAR LOS DOS METODOS A LA VEZ, se guarda la posicion correctamente,
            //pero al generarse los nodos se desplazan de las posicion asignada-> ARREGLAR

            //posicion del visual object -> si uso esta sola, no se guardan correctamente al usar SaveGraph()
            l_newRoomToSpawn.transform.position = l_newPosition;
            //posicion del nodo como "rect" -> si uso esta sola, el nuevo nodo siempre parte de la pos del nodo 'Start'
            l_newRoomToSpawn.SetPosition(new Rect(l_newPosition, m_graphView.defaultNodeSize));
        }
    }
    private void CreateExpandedNodes(RoomInfoContainer _graphToLoadCache, RoomNode roomToExpand)
    {
        List <RoomNode> l_newInstantiatedRoomsList = new List <RoomNode>();

        foreach (RoomNodeData rData in _graphToLoadCache.m_roomNodeDataList)                    //para cada nodo en el nuevo grafico (la regla que acabo de cargar);
        {
            RoomNode l_tempRoom = m_graphView.CreateRoomNode(rData.nodeType, rData.isTerminal); //instancio el nodo
            l_newInstantiatedRoomsList.Add(l_tempRoom);                                         //lo añado a la lista de "nuevas salas"
            l_tempRoom.roomID = rData.nodeID;                                                   //le asigno su ID
            m_graphView.AddElement(l_tempRoom);                                                 //añado el elemento al grafico

            //creo los puertos de entrada y salida que le tocan al nodo
            List <RoomNodeConnectionsData> l_tempOutRoomPorts = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.baseNodeId == rData.nodeID).ToList();
            l_tempOutRoomPorts.ForEach(x => m_graphView.GenerateOutputPortsOnNode(l_tempRoom, x.basePortName));

            List <RoomNodeConnectionsData> l_tempInputRoomPorts = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.targetNodeId == rData.nodeID).ToList();
            l_tempInputRoomPorts.ForEach(x => m_graphView.GenerateInputPortsOnNode(l_tempRoom, x.targetPortName));
        }
        for (int i = 0; i < l_newInstantiatedRoomsList.Count; i++)// para cada nodo que acabo de instanciar
        {
            //busco las conexiones que tiene
            List <RoomNodeConnectionsData> l_connectionDataCache = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.baseNodeId == l_newInstantiatedRoomsList[i].roomID).ToList();

            for (int j = 0; j < l_connectionDataCache.Count; j++)
            {
                string   l_targetNodeId = l_connectionDataCache[j].targetNodeId;                                                                            //guardo el id del nodo target
                RoomNode l_targetRoom   = l_newInstantiatedRoomsList.First(x => x.roomID == l_targetNodeId);                                                //busco la sala que conicida con ese ID

                string l_targetPortName = l_connectionDataCache[j].targetPortName;                                                                          //guardo el nombre del puerto target

                Port l_targetPortToConnect = m_graphView.ports.ToList().First(x => (x.node as RoomNode) == l_targetRoom && x.portName == l_targetPortName); //busco el puerto al que me tengo que conectar

                //si es un nodo 'begin', marco este nodo como el beginNodeInstantiated (en el begin node empieza la regla) -> sirve como referencia para saber donde empezar a conectar el puerto q quiero expandir
                if (l_newInstantiatedRoomsList[i].roomType == "begin")
                {
                    m_beginNodeInstantiated = l_newInstantiatedRoomsList[i];
                }

                //conecto el puerto del nodo [i] con el targetPort -> en este primer linkado asigno el tempEdge a una variable m_currentBeginNodeEdge
                //que luego me servira para encontrar el nodo conectado al nodo 'begin'
                LinkRoomPorts(l_newInstantiatedRoomsList[i].outputContainer[j].Q <Port>(), l_targetPortToConnect);

                //seteo su position basadome en la posicion del nodo expandido
                l_targetRoom.SetPosition(new Rect(_graphToLoadCache.m_roomNodeDataList.First(x => x.nodeID == l_targetRoom.roomID).position +
                                                  roomToExpand.GetPosition().position, m_graphView.defaultNodeSize));
            } //end for
        }     //end of for loop

        //busco el puerto de entrada al que esta conectado la habitacion que quiero expandir
        Port l_basePort = m_graphView.edges.ToList().Find(x => (x.input.node as RoomNode) == roomToExpand).output;

        l_basePort.portColor = new Color(0, 0, 200);//blue

        //el puerto target será el que hemos marcado previamente al conectar los nodos de la regla que acabamos de cargar
        //el currentBeginNodeEdge es la conexion del nodo 'begin' -> cojemos el input, que es el puerto q pertenece al nodo 'begin'
        Port l_targetPort = m_currentBeginNodeEdge.input;

        l_targetPort.portColor = new Color(200, 0, 0);                                                     //red
        l_targetPort.portName  = m_UtilitiesInstance.ReturnConnectionNameByReference(l_basePort.portName); //asignar el nuevo nombre del puerto dependiendo del puerto base conectado

        //elimino el nodo 'begin' -> solo sirve como referencia para saber donde conectar el nodo que queremos expandir
        m_graphView.RemoveElement(m_beginNodeInstantiated);

        //conecto los puertos
        LinkRoomPorts(l_basePort, l_targetPort);

        List <RoomNode> l_currentNodesOnGraph = m_graphView.nodes.ToList().Cast <RoomNode>().ToList();

        //asignar nuevas id a cada nodo
        for (int i = 0; i < l_currentNodesOnGraph.Count; i++)
        {
            for (int j = 0; j < l_newInstantiatedRoomsList.Count(); j++)
            {
                if (l_currentNodesOnGraph[i] == l_newInstantiatedRoomsList[j])
                {
                    List <Edge> l_currentOutputRoomEdges = m_graphView.edges.ToList().Where(x => (x.output.node as RoomNode) == l_currentNodesOnGraph[i]).ToList();
                    List <Edge> l_currentInputRoomEdges  = m_graphView.edges.ToList().Where(x => (x.input.node as RoomNode) == l_currentNodesOnGraph[i]).ToList();

                    string l_newRoomID = l_currentNodesOnGraph[i].roomID = System.Guid.NewGuid().ToString();

                    foreach (Edge e in l_currentOutputRoomEdges)
                    {
                        e.output.name = l_newRoomID;
                    }
                    foreach (Edge e in l_currentInputRoomEdges)
                    {
                        e.input.name = l_newRoomID;
                    }
                }
            }
        } //end of for loop
    }     //end expand nodes function