private void DestroyPart(GrabbablePart toDestroy)
    {
        if (toDestroy != null)
        {
            if (targetConstructions.Contains(toDestroy.ParentConstruction))
            {
                Debug.Log("hit a part in our preview construction");

//				// remove the construction we are splitting
//				Construction toRemoveConstruction = toDestroy.ParentConstruction;
//				targetConstructions.Remove (toRemoveConstruction);
//
//				// adding the split constructions
//				targetConstructions.AddRange(toRemoveConstruction.RemoveFromConstruction(toDestroy));
//
//
//				// removing the construction we are about to destroy
//				targetConstructions.Remove(toDestroy.ParentConstruction);
//
//				// and destroying it
//				ObjectPoolManager.DestroyObject (toDestroy.ParentConstruction);
////				ObjectPoolManager.DestroyObject (toRemoveConstruction);
//				toDestroy = null;

                PerformsConstructionFunctionThatMightSplit((con) => con.RemoveFromConstruction(toDestroy));
            }
        }
    }
Exemple #2
0
//	public override void PlaceAtLocation(IntVector2 location)
//	{
//		Location = location;
//		if (location != null)
//		{
//			hexCell = GridManager.instance.GetHexCell(location);
//			if (hexCell != null)
//			{
//				transform.position = hexCell.transform.position;
//				hexCell.partOnCell = this;
//			}
//		}
//		else
//		{
//			if (hexCell != null)
//			{
//				if (hexCell.partOnCell == this)
//				{
//					hexCell.partOnCell = null;
//				}
//				hexCell = null;
//			}
//		}
//	}

//	public void CheckForFinish ()
//	{
//		hexCell = Location == null ? null : GridManager.instance.GetHexCell(Location);
//
//		if (hexCell != null && hexCell.finishCell)
//		{
//			// check if it is the right thing
//			bool isCorrectConstruction = true;
//			if (isCorrectConstruction)
//			{
//				PlaceAtLocation(null);
//
//				finished = true;
//				Destroy(this.gameObject);
//				GameManager.instance.AddCompletedConstruction();
//				return;
//			}
//			GameManager.instance.IncompleteConstruction();
//		}
//	}



    public GrabbablePart CheckForCollisions()
    {
        if (_sphereCollider == null)
        {
            return(null);
        }
        Collider [] colliders = Physics.OverlapSphere(_sphereCollider.transform.position + _sphereCollider.center, _sphereCollider.radius, 1 << gameObject.layer);

        foreach (Collider c in colliders)
        {
            if (c.attachedRigidbody.GetComponent <GrabbablePart>().IsFinished)
            {
                continue;
            }
            if (c.attachedRigidbody == _sphereCollider.attachedRigidbody)
            {
                continue;
            }

            GrabbablePart collidedPart = c.attachedRigidbody.gameObject.GetComponent <GrabbablePart>();
            if (collidedPart != null)
            {
                return(collidedPart);
            }
        }

        return(null);
    }
Exemple #3
0
    public override void OnInspectorGUI()
    {
        Construction construction = target as Construction;

        if (!construction.HasChild)
        {
            PartType newPartType = (PartType)EditorGUILayout.EnumPopup("Create initial part", PartType.None);

            if (newPartType != PartType.None)
            {

                GrabbablePart partPrefab = GameSettings.instance.GetPartPrefab(newPartType);
                GrabbablePart newPart = PrefabUtility.InstantiatePrefab(partPrefab) as GrabbablePart;
                newPart.transform.position = construction.transform.position;

                construction.AddToConstruction(newPart);
            }
        }
        else if (GUILayout.Button("Select first part"))
        {
            Selection.activeObject = construction.FirstPart;
        }
        if (GUILayout.Button("Regenerate encoded construction"))
        {
            encodedString = "";
        }
        if (encodedString == "")
        {
            encodedString = Encoding.Encode(construction);
        }
        EditorGUILayout.SelectableLabel(encodedString);
    }
    private void ConnectPartWithBestRotation(GrabbablePart part)
    {
        List <Construction.PartSide> partSides = new List <Construction.PartSide>();

        targetConstructions.ForEach((con) => partSides.AddRange(con.IsConnectable(part)));
//		partSides.Sort((x, y) => Mathf.Abs(x.offsetFromSide) - Mathf.Abs(y.offsetFromSide));

        if (partSides.Count == 0)
        {
            return;
        }

        GrabbablePart newPart = ObjectPoolManager.GetObject(GameSettings.instance.GetPartPrefab(part.partType));

        newPart.transform.position = part.transform.position;
        newPart.SetSimulationOrientation(part.SimulationOrientation);

        partSides.RemoveAll((x) => x.offsetFromSide != 0);
//		if (partSides.Count > 0)
        foreach (Construction.PartSide partSide in partSides)
        {
            partSide.part.ConnectPartAndPlaceAtRelativeDirection(
                newPart,
                GrabbablePart.PhysicalConnectionType.Weld,
                partSide.relativeDirection);
        }
    }
Exemple #5
0
    private IEnumerable <LocatedPart> GetAllConnectedPartsWithLocation(IntVector2 thisLocation, HashSet <GrabbablePart> exploredParts)
    {
        if (exploredParts.Contains(this))
        {
            yield break;
        }
        exploredParts.Add(this);

        yield return(new LocatedPart(this, thisLocation));

//		Debug.Log ("adding "+thisLocation.x+":"+thisLocation.y);

        for (int i = 0; i < 6; i++)
        {
            GrabbablePart connectedPart = _connectedParts[i].connectedPart;
            if (connectedPart != null && _connectedParts[i].connectionType != PhysicalConnectionType.None)
            {
                HexMetrics.Direction relativeDirection = (HexMetrics.Direction)i;
                HexMetrics.Direction absoluteDirection = AbsoluteDirectionFromRelative(relativeDirection);
                IntVector2           newLocation       = HexMetrics.GetGridOffset(absoluteDirection) + thisLocation;
//				Debug.Log (thisLocation.x+":"+thisLocation.y+" -> "+newLocation.x+":"+newLocation.y+" (A:"+absoluteDirection+", R:"+relativeDirection+")");
                foreach (LocatedPart loactedPart in connectedPart.GetAllConnectedPartsWithLocation(newLocation, exploredParts))
                {
                    yield return(loactedPart);
                }
            }
        }
    }
    Adjancency IsAdjacent(GrabbablePart startPart, GrabbablePart overPart, out HexMetrics.Direction relativeDirection)
    {
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iAbsDir = (HexMetrics.Direction)i;
            HexMetrics.Direction iRelDir = startPart.RelativeDirectionFromAbsolute(iAbsDir);

            if (startPart.GetConnectedPart(iRelDir) == overPart)             // already connected
            {
//				Debug.Log("Found connection "+startPart+" -> "+overPart);
                relativeDirection = iRelDir;
                return(Adjancency.Connected);
            }
            else
            {
                Vector3 offset = GameSettings.instance.hexCellPrefab.GetDirection(iAbsDir);
//				Debug.Log ((startPart.transform.position + offset) +" : "+overPart.transform.position);
                if (Vector3.SqrMagnitude((startPart.transform.position + offset) - overPart.transform.position) < 0.0001)
                {
                    Debug.Log("Found Adjacency " + startPart + " -> " + overPart);
                    relativeDirection = iRelDir;
                    return(Adjancency.Adjacent);
                }
            }
        }
        relativeDirection = (HexMetrics.Direction)(-1);
        return(Adjancency.None);
    }
Exemple #7
0
    public void OnTriggerEnter(Collider other)
    {
//		Debug.Log("OnTriggerEnter (Collider "+other+")");

        if (other.attachedRigidbody == null)
        {
            return;
        }

        GrabbablePart otherPart = other.attachedRigidbody.gameObject.GetComponent <GrabbablePart>();

//		foreach(Component c in other.gameObject.GetComponents<MonoBehaviour>())
//		{
//			Debug.Log (c);
//		}
        if (otherPart != null)
        {
            if ((ParentConstruction == null || ParentConstruction.ignoreCollisions) ||
                (otherPart.ParentConstruction == null || otherPart.ParentConstruction.ignoreCollisions))
            {
                return;
            }

            LevelManager.instance.PartCollisionOccured(this, otherPart);
        }
    }
    bool WeldParts(GrabbablePart startPart, GrabbablePart endPart, Vector3 startPoint, Vector3 endPoint)
    {
        ClearSelections();
        // TODO
//		Debug.Log("WeldParts "+startPart+" -> "+endPart+" "+startPoint+" "+endPoint);
        if (endPart == null)
        {
            return(false);
        }

        HexMetrics.Direction direction;
        Adjancency           adjacency = IsAdjacent(startPart, endPart, out direction);

        if (adjacency == Adjancency.Adjacent)
        {
            startPart.ConnectPartAndPlaceAtRelativeDirection(endPart, GrabbablePart.PhysicalConnectionType.Weld, (HexMetrics.Direction)direction);
        }
        else if (adjacency == Adjancency.Connected)
        {
//			startPart.SetPhysicalConnection(
            PerformsConstructionFunctionThatMightSplit((con) =>
                                                       startPart.SetPhysicalConnection(direction, GrabbablePart.PhysicalConnectionType.None, GrabbablePart.SplitOptions.SplitIfNecessary));
        }

        return(true);
    }
 bool DragRecenter(GrabbablePart startPart, GrabbablePart endPart, Vector3 startPoint, Vector3 endPoint)
 {
     ClearSelections();
     startPart.ParentConstruction.transform.position = startDragLocation + (endPoint - startPoint);
     FindPartClosestToCenterTarget().highlighted     = true;
     return(false);
 }
    bool DragRecenterEnd(GrabbablePart startPart, GrabbablePart endPart, Vector3 startPoint, Vector3 endPoint)
    {
        ClearSelections();
        startPart.ParentConstruction.transform.position = startDragLocation + (endPoint - startPoint);

        return(Recenter(FindPartClosestToCenterTarget()));
    }
 public void PartCollisionOccured(GrabbablePart part, GrabbablePart otherPart)
 {
     Debug.Log("SimulationFailed");
     part.highlighted      = true;
     otherPart.highlighted = true;
     gameState             = State.SimulationFailed;
 }
Exemple #12
0
    void MoveToState(float extentionValue, float directionValue, float rotationValue)
    {
        GrabbablePart heldPart = GrabberManager.instance.GetPartHeldBy(this);



        if (heldPart != null)
        {
            if (heldPart.ParentConstruction == null)
            {
                Debug.LogError("Parent is null!", heldPart);
            }
            heldPart.ParentConstruction.gameObject.transform.parent = clamp.transform;
        }

        clamp.transform.localRotation = Quaternion.Euler(0, 0, rotationValue);

//		Debug.Log(clamp.transform.localRotation.eulerAngles);

        transform.localRotation = Quaternion.Euler(0, 0, directionValue);
        for (int i = 0; i < _arms.Length; i++)
        {
            _arms[i].transform.localPosition = new Vector3(0, extentionValue * GameSettings.instance.hexCellPrefab.Height / (_arms.Length), 1);
        }

        if (heldPart != null)
        {
            heldPart.ParentConstruction.gameObject.transform.parent = null;
        }

//		clamp.transform.localRotation = Quaternion.Euler(0, 0, 0);
    }
 void HandleInputAction(System.Func <GrabbablePart, bool> action, GrabbablePart part)
 {
     if (action != null)
     {
         if (action(part))
         {
             MarkConstructionChange();
         }
     }
 }
Exemple #14
0
    public HexMetrics.Direction ConnectedPartsOppositeDirection(HexMetrics.Direction relativeDirection)
    {
        GrabbablePart connectedPart = GetConnectedPart(relativeDirection);

        if (connectedPart == null)
        {
            return((HexMetrics.Direction)(-1));
        }

        return(OtherPartsOppositeDirection(relativeDirection, connectedPart));
    }
 public bool Contains(GrabbablePart isPart)
 {
     foreach (GrabbablePart part in Parts)
     {
         if (isPart == part)
         {
             return(true);
         }
     }
     return(false);
 }
    public IEnumerable <Construction> RemoveFromConstruction(GrabbablePart partToRemove)
    {
        // disconnect part from construction
        for (int i = 0; i < 6; i++)
        {
            partToRemove.SetPhysicalConnection((HexMetrics.Direction)i, GrabbablePart.PhysicalConnectionType.None, GrabbablePart.SplitOptions.DoNotSplit);
        }


        // split if necessary
        return(CheckForSplitsOrJoins());
    }
Exemple #17
0
    public IEnumerable <GrabbablePart> GetConnectedParts()
    {
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iDir     = (HexMetrics.Direction)i;
            GrabbablePart        connPart = GetConnectedPart(iDir);

            if (connPart != null)
            {
                yield return(connPart);
            }
        }
    }
    public static Construction CreateSimpleConstruction(PartType partType)
    {
        Construction singleConstruction = ObjectPoolManager.GetObject(GameSettings.instance.constructionPrefab);

        if (partType != PartType.None)
        {
            GrabbablePart singlePart = ObjectPoolManager.GetObject(GameSettings.instance.GetPartPrefab(partType));
            singleConstruction.AddToConstruction(singlePart);
            singlePart.transform.localPosition = Vector3.zero;
        }
        singleConstruction.transform.position = Vector3.zero;
        return(singleConstruction);
    }
Exemple #19
0
    public bool ConnectPartOnGrid(GrabbablePart otherPart, PhysicalConnectionType connectionType)
    {
        if (connectionType == PhysicalConnectionType.None)
        {
//			Debug.Log("Not Connecting: "+this.idNumber+" : "+otherPart.idNumber);
            return(false);
        }

//		Debug.Log("Connecting: "+this.idNumber+" : "+otherPart.idNumber);

//		HexMetrics.Direction directionToOther;
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iDir             = (HexMetrics.Direction)i;
            IntVector2           relativeLocation = HexMetrics.GetGridOffset(iDir);

//			Debug.Log (GetGridLocationFromPosition().ToString() +" : "+otherPart.GetGridLocationFromPosition().ToString() + " + "+relativeLocation.ToString() + " = "+ (otherPart.GetGridLocationFromPosition() + relativeLocation).ToString());
            if (GetGridLocationFromPosition().IsEqualTo(otherPart.GetGridLocationFromPosition() - relativeLocation))
            {
                HexMetrics.Direction relativeDirection = Relative(iDir);
                int r = (int)relativeDirection;
//				Debug.Log ("Found Direction A: "+iDir+", R: "+relativeDirection);
                if (_connectedParts[r] != null && _connectedParts[r].connectedPart != null)
                {
                    // if this happens twice in a step, remember that it is actually happening over 2 steps.
                    // It weld at the beginning of each step, i.e. as it comes into the welder and as it leaves
//					Debug.Log("Connecting part "+otherPart.idNumber+" to a direction that is already connected (connected to "+_connectedParts[r].connectedPart.idNumber+")");
                    return(false);
                }
//				otherPart.gameObject.transform.parent = gameObject.transform;

                if (IsWeldable(relativeDirection, otherPart))
                {
                    if (ParentConstruction != null)
                    {
                        ParentConstruction.AddToConstruction(otherPart);
                    }

                    _connectedParts[r].Reset();
                    _connectedParts[r].connectedPart = otherPart;
                    HexMetrics.Direction oppositeDirection = ConnectedsOpposite(relativeDirection);
                    otherPart._connectedParts[(int)oppositeDirection].Reset();
                    otherPart._connectedParts[(int)oppositeDirection].connectedPart = this;
                    SetPhysicalConnection(relativeDirection, connectionType);
                    return(true);
                }
            }
        }

        return(false);
    }
Exemple #20
0
    public GrabbablePart RemoveConnectedPart(HexMetrics.Direction relativeDirection)
    {
        GrabbablePart ret = _connectedParts[(int)relativeDirection].connectedPart;

//		if ( transform.parent != null && ret != null && ret.transform == transform.parent )
//		{
//			transform.parent = null;
//		}
        _connectedParts[(int)relativeDirection].connectedPart      = null;
        _connectedParts[(int)relativeDirection].connectionType     = PhysicalConnectionType.None;
        _connectedParts[(int)relativeDirection].auxConnectionTypes = 0;

        return(ret);
    }
 bool RotatePartInConstruction(GrabbablePart part)
 {
     for (int i = 1; i < 6; i++)
     {
         Debug.Log("Checking direction " + (-i));
         if (!part.WillSimulationOrientationRotatateSplitConstruction(-i))
         {
             Debug.Log("Rotating direction " + (-i));
             part.RotatateSimulationOrientation(-i);
             break;
         }
     }
     return(true);
 }
    public void CenterConstruction(GrabbablePart childPart)
    {
        if (childPart.ParentConstruction != this)
        {
            return;
        }

        Vector3 diff = childPart.transform.localPosition;

        foreach (GrabbablePart part in Parts)
        {
            part.transform.localPosition -= diff;
        }
    }
    IEnumerable <IEnumerable <GrabbablePart> > FindConstructionComponentsWithout(GrabbablePart ignorePart)
    {
        HashSet <GrabbablePart> unexploredParts = new HashSet <GrabbablePart>(ignorePart.ParentConstruction.Parts);

        unexploredParts.Remove(ignorePart);

        foreach (GrabbablePart connPart in ignorePart.GetConnectedParts())
        {
            if (unexploredParts.Contains(connPart))
            {
                yield return(ExplorePart(connPart, unexploredParts));
            }
        }
    }
    public void RegisterGrab(Grabber grabber, GrabbablePart part)
    {
        if (LevelManager.instance.gameState == LevelManager.State.Simulation)
        {
            Debug.LogWarning("Grab " + grabber.name + ":" + part.name + " (" + part.ParentConstruction.name + ")");
            grabbedPart[grabber] = part;

            if (!grabbedBy.ContainsKey(part.ParentConstruction))
            {
                grabbedBy[part.ParentConstruction] = new HashSet <Grabber>();
            }
            grabbedBy[part.ParentConstruction].Add(grabber);
            DumpInfo();
        }
    }
    bool DragPart(GrabbablePart part)
    {
        UIButton dragButton = dragButtons[part.partType];

        _editorAreaInputCatcher.Retarget(dragButton);


        onDragStart = () =>
        {
            buttonToPart[dragButton].SetSimulationOrientation(part.SimulationOrientation);

            DestroyPart(part);
        };
        return(true);
    }
Exemple #26
0
 public IEnumerable <PartSide> GetConnectedPartsWithDirection()
 {
     for (int i = 0; i < 6; i++)
     {
         HexMetrics.Direction iDir     = (HexMetrics.Direction)i;
         GrabbablePart        connPart = GetConnectedPart(iDir);
         if (connPart != null)
         {
             yield return(new PartSide()
             {
                 part = connPart, relativeDirection = iDir,
             });
         }
     }
 }
    public void PerformPostStart()
    {
//		foreach (HexCell hc in new HexCell [4] {hexCell, leftBelow, centerBelow, rightBelow})
//		{
//			Debug.Log ("("+hc.location.x+":"+hc.location.y+")"+hc.partOnCell+" -> "+hc.partHeldOverCell +" | "+hc.partOverCell);
//
//			// there are 5 welding combos (t = top, b = botton, l = left, r = right):
//			// tl, tr, bl, br, tb
//
//		}

//		System.Action<Construction> deleteFunction = (obj) => Destroy(obj.gameObject);
        //InstantiatePrefabDelegate instantiateFunction = (prefab) => Instantiate(prefab) as GameObject;

        GrabbablePart topPart    = hexCell.partOverCell;
        GrabbablePart bottomPart = centerBelow.partOverCell;
        GrabbablePart leftPart   = leftBelow.partOverCell;
        GrabbablePart rightPart  = rightBelow.partOverCell;

        if (topPart != null)
        {
            if (leftPart != null)
            {
                topPart.ConnectPartOnGrid(leftPart, GrabbablePart.PhysicalConnectionType.Weld);
            }
            if (bottomPart != null)
            {
                topPart.ConnectPartOnGrid(bottomPart, GrabbablePart.PhysicalConnectionType.Weld);
            }
            if (rightPart != null)
            {
                topPart.ConnectPartOnGrid(rightPart, GrabbablePart.PhysicalConnectionType.Weld);
            }
        }
        if (bottomPart != null)
        {
            if (leftPart != null)
            {
                bottomPart.ConnectPartOnGrid(leftPart, GrabbablePart.PhysicalConnectionType.Weld);
            }
            if (rightPart != null)
            {
                bottomPart.ConnectPartOnGrid(rightPart, GrabbablePart.PhysicalConnectionType.Weld);
            }
        }

//		if (hexCell.partOverCell)
    }
 public void RegisterDrop(Grabber grabber, GrabbablePart part)
 {
     if (LevelManager.instance.gameState == LevelManager.State.Simulation)
     {
         Debug.LogWarning("Drop " + grabber.name + ":" + part.name + " (" + part.ParentConstruction.name + ")\n" +
                          "grabbedPart.Remove(" + grabber.name + ")\n" +
                          "grabbedBy[" + part.ParentConstruction.name + "].Remove(" + grabber.name + "); ");
         grabbedPart.Remove(grabber);
         grabbedBy[part.ParentConstruction].Remove(grabber);
         if (grabbedBy[part.ParentConstruction].Count == 0)
         {
             grabbedBy.Remove(part.ParentConstruction);
         }
         DumpInfo();
     }
 }
    IEnumerable <GrabbablePart> ExplorePart(GrabbablePart toExplore, HashSet <GrabbablePart> unexploredParts)
    {
        if (!unexploredParts.Contains(toExplore))
        {
            yield break;
        }
        unexploredParts.Remove(toExplore);
        yield return(toExplore);

        foreach (GrabbablePart connPart in toExplore.GetConnectedParts())
        {
            foreach (GrabbablePart explored in ExplorePart(connPart, unexploredParts))
            {
                yield return(explored);
            }
        }
    }
    public void TransferConstruction(GrabbablePart part, Construction toConstruction)
    {
        Grabber grabber = GrabberManager.instance.GetGrabberHolding(part);

        if (grabber != null)
        {
//			Debug.Log ("Grabber "+grabber.name +" is holding "+part.name);
//			Debug.Log ("TransferConstruction---");
            GrabberManager.instance.RegisterDrop(grabber, part);
        }
        part.transform.parent = toConstruction.transform;
        if (grabber != null)
        {
//			Debug.Log ("TransferConstruction---");
            GrabberManager.instance.RegisterGrab(grabber, part);
        }
    }
	public HexMetrics.Direction OtherPartsOppositeDirection(HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		return ReverseDirection( otherPart.RelativeDirectionFromAbsolute(AbsoluteDirectionFromRelative(relativeDirection)));
	}
		public void Reset ()
		{
			connectedPart = null;
			connectionType = GrabbablePart.PhysicalConnectionType.None;
			auxConnectionTypes = 0;
		}
//	public void ConnectPartAndPlaceAtAbsoluteDirection(GrabbablePart otherPart, PhysicalConnectionType connectionType, HexMetrics.Direction absoluteDirection)
//	{
//		ConnectPartAndPlaceAtRelativeDirection(otherPart, connectionType, Relative(absoluteDirection));
//	}
	
	public void ConnectPartAndPlaceAtRelativeDirection(GrabbablePart otherPart, PhysicalConnectionType connectionType, HexMetrics.Direction relativeDirection)
	{
		HexMetrics.Direction absoluteDirection = Absolute(relativeDirection);
		ConnectionDescription connDesc = _connectedParts[(int)relativeDirection];
		
		connDesc.connectedPart = otherPart; // connect the part
		
		ConnectionDescription otherConnDesc = otherPart._connectedParts[(int)ConnectedsOpposite(relativeDirection)]; // get the other parts opposite side that is connected to this
		
		otherConnDesc.connectedPart = this; // connect that side
		
		connDesc.connectedPart.transform.position = transform.position + (Vector3)GameSettings.instance.hexCellPrefab.GetDirection(absoluteDirection);
		
		SetPhysicalConnection(relativeDirection, connectionType);
		
		if (ParentConstruction != null)
		{
//			Debug.Log("Adding to construction "+ParentConstruction.name);
			ParentConstruction.AddToConstruction(otherPart);
		}
		
	}
//	public GrabbablePart heldPart 
//	{ 
//		get {return _heldPart; } 
//		private set
//		{
//			
////			if (_heldPart == null && value != null)
////			{
////				Debug.Log ("Held Part "+_heldPart+" newheldpart "+value, value);
////				Debug.Log (value.ParentConstruction, value.ParentConstruction);
////				if (value.ParentConstruction.heldAndMovingGrabber != null) // we are grabbing a part that is already grabbed!
////				{
////					Debug.Log (value.ParentConstruction.heldAndMovingGrabber, value.ParentConstruction.heldAndMovingGrabber);
////					Debug.LogWarning("Multiple grab");
////					GameManager.instance.MultipleGrabOccured(value.ParentConstruction.heldAndMovingGrabber, this);
////					return;
////				}
////			}
//			
//			if (_heldPart != null)
//			{
//				Debug.Log ("Dropping part", this);
//				Debug.Log ("Dropping part", _heldPart);
//				_heldPart.ParentConstruction.heldAndMovingGrabber = null;
//			}
//			else
//			{
//				Debug.Log ("Empty", this);
//				Debug.Log ("Empty", value);
//				if (value != null && value.ParentConstruction.heldAndMovingGrabber != null)
//				{
//					// part is already grabber
//					Debug.LogWarning("Multiple grab, part already grabbed", value);
//					GameManager.instance.MultipleGrabOccured(value.ParentConstruction.heldAndMovingGrabber, this);
//				}
//			}
//			_heldPart = value;
//			if (_heldPart != null)
//			{
//				_heldPart.ParentConstruction.heldAndMovingGrabber = this;
//				Debug.Log ("Grabbing part "+_currentInstruction, this);
//				Debug.Log ("Grabbing part", _heldPart);
//			}
//		} 
//	}
//	GrabbablePart _heldPart;
//	System.Action _doAtEndOfInstruction;
	
	
	void Grab(GrabbablePart part)
	{
		GrabberManager.instance.RegisterGrab(this, part);
	}
	void Drop(GrabbablePart part)
	{
		GrabberManager.instance.RegisterDrop(this, part);
	}
	public LocatedPart(GrabbablePart __part, IntVector2 __location)
	{
		part = __part;
		location = __location;
	}
	public bool IsWeldable (HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		return IsWeldable(relativeDirection, otherPart, (HexMetrics.Direction)0);
	}
	public bool IsWeldable (HexMetrics.Direction relativeDirection, GrabbablePart otherPart, HexMetrics.Direction rotationFactor)
	{
//		relativeDirection = (HexMetrics.Direction)(((int)relativeDirection+(int)rotationFactor+6)%6);
		
		if (otherPart == null) return false;
		
		HexMetrics.Direction oppositeDirection = OtherPartsOppositeDirection(relativeDirection, otherPart);
		oppositeDirection = (HexMetrics.Direction)(((int)oppositeDirection+(int)rotationFactor+6)%6); // what if we were to rotate the other part?
//		ConnectionDescription otherConnDesc = connDesc.connectedPart._connectedParts[(int)oppositeDirection];
		
		bool weldableHere = Weldable(relativeDirection);
		bool weldabelThere = otherPart.Weldable(oppositeDirection);
//		Debug.Log("Checking weldability: "+direction+"("+weldableHere+") <-> "+oppositeDirection+"("+weldabelThere+")");
		
		return weldableHere && weldabelThere;
	}
	public void RegisterPart (GrabbablePart newPart)
	{
		_partOverCell = newPart;
	}
	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);

	}
	public IEnumerable<HexMetrics.Direction> IsWeldableWithRotationFactor (HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		for (int i = 0 ; i < 6 ; i++)
		{
			HexMetrics.Direction iDir = (HexMetrics.Direction)i;
			if (IsWeldable(relativeDirection, otherPart, iDir))
			{
				yield return iDir;
			}
		}
	}
	public bool ConnectPartOnGrid(GrabbablePart otherPart, PhysicalConnectionType connectionType)
	{
		if (connectionType == PhysicalConnectionType.None)
		{
//			Debug.Log("Not Connecting: "+this.idNumber+" : "+otherPart.idNumber);
			return false;
		}
		
//		Debug.Log("Connecting: "+this.idNumber+" : "+otherPart.idNumber);
		
//		HexMetrics.Direction directionToOther;
		for (int i = 0 ; i < 6 ; i++)
		{
			HexMetrics.Direction iDir = (HexMetrics.Direction)i;
			IntVector2 relativeLocation = HexMetrics.GetGridOffset(iDir);
			
//			Debug.Log (GetGridLocationFromPosition().ToString() +" : "+otherPart.GetGridLocationFromPosition().ToString() + " + "+relativeLocation.ToString() + " = "+ (otherPart.GetGridLocationFromPosition() + relativeLocation).ToString());
			if (GetGridLocationFromPosition().IsEqualTo(otherPart.GetGridLocationFromPosition() - relativeLocation))
			{
				HexMetrics.Direction relativeDirection = Relative(iDir);
				int r = (int)relativeDirection;
//				Debug.Log ("Found Direction A: "+iDir+", R: "+relativeDirection);
				if (_connectedParts[r] != null && _connectedParts[r].connectedPart != null)
				{
					// if this happens twice in a step, remember that it is actually happening over 2 steps. 
					// It weld at the beginning of each step, i.e. as it comes into the welder and as it leaves
//					Debug.Log("Connecting part "+otherPart.idNumber+" to a direction that is already connected (connected to "+_connectedParts[r].connectedPart.idNumber+")");
					return false;
				}
//				otherPart.gameObject.transform.parent = gameObject.transform;
				
				if (IsWeldable (relativeDirection, otherPart))
				{
					if (ParentConstruction != null)
					{
						ParentConstruction.AddToConstruction(otherPart);
					}
				
					_connectedParts[r].Reset();
					_connectedParts[r].connectedPart = otherPart;
					HexMetrics.Direction oppositeDirection = ConnectedsOpposite(relativeDirection);
					otherPart._connectedParts[(int)oppositeDirection].Reset();
					otherPart._connectedParts[(int)oppositeDirection].connectedPart = this;
					SetPhysicalConnection(relativeDirection, connectionType);
					return true;
				}
				
				
				
			}
		}
		
		return false;
		
	}