Ejemplo n.º 1
0
    public bool Decode(Encoding encodedElements)
    {
//		List<string> encodedElements = new List<string>(CharSerializer.AllStrings(encoding));

//		Encoding encodedElements = new Encoding(encodings);

//		string fullEncoding = string.Join (" | ", encodedElements.ToArray());

        Debug.Log("Decoding Construction: \n" + encodedElements.DebugString());
        if (encodedElements.Count == -1 || encodedElements.Count == 0 || (encodedElements.Count == 1 && encodedElements.IsInt(0)))
        {
            return(true);
        }

//		if (encodedElements.Count == 1 && encodedElements.IsInt(0))
//		{
//			PartType partType = (PartType)encodedElements.Int(0);
//			return CreateSimpleConstruction(partType);
//		}


        Dictionary <int, GrabbablePart>      idParts       = new Dictionary <int, GrabbablePart>();
        Dictionary <GrabbablePart, Encoding> partEncodings = new Dictionary <GrabbablePart, Encoding>();
//
//		List<GrabbablePart> elements = new List<GrabbablePart>();
//		List<string> encodedElements = new List<string>(encoded.Split(','));


//
        int centerId = -1;

        for (int i = 0; i < encodedElements.Count; i++)
        {
            Encoding partEncoding = encodedElements.SubEncoding(i);
            int      id           = partEncoding.Int(0);
//			Debug.Log ("Encoding "+encodedElements[i][0]+" ("+id+")");
            if (centerId == -1)
            {
                centerId = id;
            }
            PartType partType = (PartType)partEncoding.Int(1);


            idParts[id] = ObjectPoolManager.GetObject(GameSettings.instance.GetPartPrefab(partType));
            partEncodings[idParts[id]] = partEncoding;

//			Debug.Log ("Creating part "+id);
        }

        foreach (int id in idParts.Keys)
        {
            idParts[id].SetSimulationOrientation(partEncodings[idParts[id]].Int(2));
        }

//		Construction construction = ObjectPoolManager.GetObject(GameSettings.instance.constructionPrefab);
//		construction.name = "Decoded Construction";


        HashSet <GrabbablePart> exploredParts = new HashSet <GrabbablePart>();

        System.Func <GrabbablePart, bool> addToConstructionRecursively = null;

        addToConstructionRecursively = (newPart) =>
        {
            exploredParts.Add(newPart);
            this.AddToConstruction(newPart);

            Encoding code = partEncodings[newPart];
            int      id   = code.Int(0);
            PartType type = (PartType)code.Int(1);

//			Debug.Log ("Connecting part "+id+"("+type+")");

            for (int i = 0; i < 6; i++)
            {
                HexMetrics.Direction iDir = (HexMetrics.Direction)i;
                int otherId = code.Int(3 + (i * 3) + 0);
                GrabbablePart.PhysicalConnectionType physicalConnType = (GrabbablePart.PhysicalConnectionType)code.Int(3 + (i * 3) + 1);
                int auxilaryConnectionType = code.Int(3 + (i * 3) + 2);

//				Debug.Log("Connection Def: "+id+"->"+otherId+":"+iDir+":"+physicalConnType);

                if (otherId != 0 && !idParts.ContainsKey(otherId))
                {
                    Debug.LogError("idParts does not contain part with id " + otherId + "\n" + string.Join(", ", new List <int>(idParts.Keys).ConvertAll((e) => "" + e).ToArray()));
                    return(false);
                }
                GrabbablePart otherPart = otherId == 0 ? null : idParts[otherId];
                if (otherPart != null)
                {
//					Debug.Log ("Connecting part "+id+" to "+otherId+" in direction "+iDir +"("+physicalConnType+", "+auxilaryConnectionType+")");
                    newPart.ConnectPartAndPlaceAtRelativeDirection(otherPart, physicalConnType, iDir);
                    newPart.SetPhysicalConnection(iDir, physicalConnType);
                    newPart.SetAuxilaryConnections(iDir, auxilaryConnectionType);

                    if (!exploredParts.Contains(otherPart))
                    {
                        if (!addToConstructionRecursively(otherPart))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    newPart.SetPhysicalConnection(iDir, GrabbablePart.PhysicalConnectionType.None, GrabbablePart.SplitOptions.DoNotSplit);
                    newPart.SetAuxilaryConnections(iDir, 0);
                }
            }
            return(true);
        };


        if (idParts.ContainsKey(centerId))
        {
            idParts[centerId].transform.position = this.transform.position;
            if (!addToConstructionRecursively(idParts[centerId]))
            {
                foreach (GrabbablePart part in idParts.Values)
                {
                    ObjectPoolManager.DestroyObject(part);
                }
                ObjectPoolManager.DestroyObject(this);

                return(Construction.CreateSimpleConstruction(PartType.Standard6Sided));
            }
        }
        this.CenterConstruction(idParts[centerId]);

        // do this in such a way that they are placed properly
//		for (int i = 1 ; i < encodedElements.Count ; i++)
//		{
//			construction.AddToConstruction(idParts[i+1]);
//		}

        return(true);
    }
    public override void OnInspectorGUI()
    {
        part = target as GrabbablePart;
        DrawDefaultInspector();


        if (EditorApplication.isPlaying)
        {
            GUILayout.Label("Construction editor disabled while playing");
            return;
        }

//		System.Action<Construction> deleteFunction = (construct) => DestroyImmediate(construct);

        EditorGUILayout.BeginHorizontal();
        HexMetrics.Direction oldOrietation = part.SimulationOrientation;
        HexMetrics.Direction newOrietation = (HexMetrics.Direction)EditorGUILayout.EnumPopup(part.SimulationOrientation);
        if (newOrietation != oldOrietation)
        {
            part.SetSimulationOrientation(newOrietation);
        }
        if (GUILayout.Button("<-"))
        {
            part.SetSimulationOrientation(((int)(part.SimulationOrientation) - 1) % 6);
        }
        if (GUILayout.Button("->"))
        {
            part.SetSimulationOrientation(((int)(part.SimulationOrientation) + 1) % 6);
        }
        EditorGUILayout.EndHorizontal();

        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iDir          = (HexMetrics.Direction)i;
            HexMetrics.Direction iDirRelative  = part.Relative(iDir);
            GrabbablePart        connectedPart = part.GetConnectedPart(iDirRelative);

            EditorGUILayout.BeginHorizontal();


            if (GUILayout.Button("GOTO", GUILayout.Width(75)))
            {
                if (connectedPart != null)
                {
                    Selection.activeObject = connectedPart;
                }
            }

            // check for other components
            Vector3     connectedPosition = part.transform.position + (Vector3)GameSettings.instance.hexCellPrefab.GetDirection(iDir);
            Collider [] colliders         = Physics.OverlapSphere(connectedPosition, 1);

            GrabbablePart contact = null;
            foreach (Collider c in colliders)
            {
                contact = c.attachedRigidbody.GetComponent <GrabbablePart>();

                if (contact != null)
                {
                    break;
                }
            }
            if (contact != null && contact.ParentConstruction != null && contact.ParentConstruction != part.ParentConstruction)
            {
                Vector3 difference = contact.transform.position - connectedPosition;
//				Debug.Log(difference);
                if (difference != Vector3.zero)
                {
                    if (GUILayout.Button("Line Up"))
                    {
                        Debug.Log(difference);
                        Transform toMove = (contact.ParentConstruction == null ? null : contact.ParentConstruction.transform) ?? contact.transform;
                        toMove.position -= difference;
                    }
                }
                else
                {
                    if (GUILayout.Button("Connect (" + (GrabbablePart.PhysicalConnectionType) 1 + ")"))
                    {
                        part.ParentConstruction.AddToConstruction(contact);
                        part.ConnectPartAndPlaceAtRelativeDirection(contact, GrabbablePart.PhysicalConnectionType.Weld, iDirRelative);
                        part.SetPhysicalConnection(iDirRelative, GrabbablePart.PhysicalConnectionType.Weld);
                    }
                }
            }
            else if (
                contact != null && contact.ParentConstruction != null && contact.ParentConstruction == part.ParentConstruction &&
                part.GetPhysicalConnectionType(iDirRelative) == GrabbablePart.PhysicalConnectionType.None)
            {
                if (GUILayout.Button((GrabbablePart.PhysicalConnectionType) 1 + " connect " + contact.partType))
                {
                    part.ConnectPartAndPlaceAtRelativeDirection(contact, GrabbablePart.PhysicalConnectionType.Weld, iDirRelative);
                }
            }
            else
            {
                PartType oldType     = connectedPart == null ? PartType.None : connectedPart.partType;
                PartType newPartType = (PartType)EditorGUILayout.EnumPopup(oldType);

                bool changingPart = newPartType != oldType;

                // if we are changing part and we have one there already, remove it
                if (connectedPart != null && changingPart)
                {
                    GameObject toDestroy = part.RemoveConnectedPart(iDirRelative).gameObject;
                    GameObject.DestroyImmediate(toDestroy);
                }
                if (changingPart && newPartType != PartType.None)
                {
                    // create part

                    GrabbablePart partPrefab       = GameSettings.instance.GetPartPrefab(newPartType);
                    GrabbablePart newConnectedPart = PrefabUtility.InstantiatePrefab(partPrefab) as GrabbablePart;
                    part.ConnectPartAndPlaceAtRelativeDirection(newConnectedPart, GrabbablePart.PhysicalConnectionType.Weld, iDirRelative);
                    part.SetSimulationOrientation(part.SimulationOrientation);
//					part.SetPhysicalConnection(iDir, GrabbablePart.PhysicalConnectionType.Weld, instantiateFunction);
                }

                GrabbablePart.PhysicalConnectionType oldConnectionType = part.GetPhysicalConnectionType(iDirRelative);
                GrabbablePart.PhysicalConnectionType newConnectionType = (GrabbablePart.PhysicalConnectionType)EditorGUILayout.EnumPopup(oldConnectionType);
                if (oldConnectionType != newConnectionType)
                {
                    part.SetPhysicalConnection(iDirRelative, newConnectionType);
                }

                int oldAuxTypes = part.GetAuxilaryConnectionTypes(iDirRelative);
                int newAuxTypes = EditorGUILayout.MaskField(oldAuxTypes, System.Enum.GetNames(typeof(GrabbablePart.AuxilaryConnectionType)));
                if (oldAuxTypes != newAuxTypes)
                {
                    part.SetAuxilaryConnections(iDirRelative, newAuxTypes);
                }
            }
            if (GUILayout.Button("<-"))
            {
                if (contact != null)
                {
                    contact.SetSimulationOrientation(((int)(contact.SimulationOrientation) - 1) % 6);
                }
            }
            if (GUILayout.Button("->"))
            {
                if (contact != null)
                {
                    contact.SetSimulationOrientation(((int)(contact.SimulationOrientation) + 1) % 6);
                }
            }

            EditorGUILayout.EndHorizontal();
        }

        EditorUtility.SetDirty(part);
    }