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);
    }
예제 #2
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);
                }
            }
        }
    }
예제 #3
0
    public void SetAuxilaryConnections(HexMetrics.Direction relativeDirection, int newConnectionTypes)
    {
        ConnectionDescription connDesc = _connectedParts[(int)relativeDirection];

        if (connDesc.connectedPart == null)
        {
            connDesc.auxConnectionTypes = 0;
            return;
        }

        HexMetrics.Direction  oppositeDirection = ConnectedsOpposite(relativeDirection);
        ConnectionDescription otherConnDesc     = connDesc.connectedPart._connectedParts[(int)oppositeDirection];

        bool weldableHere  = Weldable(relativeDirection);
        bool weldabelThere = connDesc.connectedPart.Weldable(oppositeDirection);

        if (weldableHere && weldabelThere)
        {
            connDesc.auxConnectionTypes      = newConnectionTypes;
            otherConnDesc.auxConnectionTypes = newConnectionTypes;
        }
        else
        {
            connDesc.auxConnectionTypes      = 0;
            otherConnDesc.auxConnectionTypes = 0;
        }
    }
예제 #4
0
    public static IntVector2 GetGridOffset(HexMetrics.Direction direction)
    {
        switch (direction)
        {
        case HexMetrics.Direction.Up:            return(new IntVector2(0, 1));

        case HexMetrics.Direction.RightUp:       return(new IntVector2(1, 0));

        case HexMetrics.Direction.RightDown: return(new IntVector2(1, -1));

        case HexMetrics.Direction.Down:          return(new IntVector2(0, -1));

        case HexMetrics.Direction.LeftDown:      return(new IntVector2(-1, 0));

        case HexMetrics.Direction.LeftUp:        return(new IntVector2(-1, 1));
        }

        return(null);
//		return new Dictionary<HexMetrics.Direction, System.Func<IntVector2>>()
//		{
//			{HexMetrics.Direction.Up,       () => new IntVector2( 0, 1)},
//			{HexMetrics.Direction.RightUp,  () => new IntVector2( 1, 0)},
//			{HexMetrics.Direction.RightDown,() => new IntVector2( 1,-1)},
//			{HexMetrics.Direction.Down,     () => new IntVector2( 0,-1)},
//			{HexMetrics.Direction.LeftDown,	() => new IntVector2(-1, 0)},
//			{HexMetrics.Direction.LeftUp,	() => new IntVector2(-1, 1)}
//
//		}
    }
예제 #5
0
 public GrabberState(HexMetrics.Direction dir, int ext, bool clampOpen)
 {
     direction      = dir;
     extention      = ext;
     this.clampOpen = clampOpen;
     rotation       = 0;
 }
예제 #6
0
 public int GetAuxilaryConnectionTypes(HexMetrics.Direction relativeDirection)
 {
     if (GetConnectedPart(relativeDirection) == null)
     {
         return(0);
     }
     return(_connectedParts[(int)relativeDirection].auxConnectionTypes);
 }
예제 #7
0
 public PhysicalConnectionType GetPhysicalConnectionType(HexMetrics.Direction relativeDirection)
 {
     if (GetConnectedPart(relativeDirection) == null)
     {
         return(PhysicalConnectionType.None);
     }
     return(_connectedParts[(int)relativeDirection].connectionType);
 }
예제 #8
0
    private void SetWeldSprite(HexMetrics.Direction relativeDirection, bool show)
    {
        GameObject weldSprite = _weldSpriteObjects[(int)relativeDirection];

        if (weldSprite != null)
        {
            weldSprite.transform.localScale = Vector3.one * (show ? 1 : 0);
        }
    }
예제 #9
0
    public HexMetrics.Direction ConnectedPartsOppositeDirection(HexMetrics.Direction relativeDirection)
    {
        GrabbablePart connectedPart = GetConnectedPart(relativeDirection);

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

        return(OtherPartsOppositeDirection(relativeDirection, connectedPart));
    }
예제 #10
0
 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);
         }
     }
 }
예제 #11
0
 public Vector2 GetDirection(HexMetrics.Direction direction)
 {
     return(new Dictionary <HexMetrics.Direction, System.Func <Vector2> >()
     {
         { HexMetrics.Direction.Up, () => Up },
         { HexMetrics.Direction.RightUp, () => RightUp },
         { HexMetrics.Direction.RightDown, () => RightDown },
         { HexMetrics.Direction.Down, () => - Up },
         { HexMetrics.Direction.LeftDown, () => - RightUp },
         { HexMetrics.Direction.LeftUp, () => - RightDown }
     }[direction]());
 }
    public void OnSceneGUI()
    {
        if (part == null)
        {
            return;
        }
//		Debug.DrawLine(part.transform.position, );
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iDir = (HexMetrics.Direction)i;
            Handles.DrawSolidDisc(part.transform.position + (Vector3)GameSettings.instance.hexCellPrefab.GetDirection(iDir), Vector3.forward, 1);
        }
    }
예제 #13
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);
            }
        }
    }
예제 #14
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);
    }
예제 #15
0
    public HashSet <Construction> SetSimulationOrientation(HexMetrics.Direction orientation)
    {
        for (int i = 0; i < 6; i++)
        {
            if (_connectedParts[i] == null)
            {
                _connectedParts[i] = new ConnectionDescription();
            }
        }

//			adjacent.ForEach((obj) => obj.parent = null);
        int directionChange = ((int)orientation - (int)SimulationOrientation + 6) % 6;

        transform.rotation = Quaternion.Euler(0, 0, (int)orientation * -60);

        ConnectionDescription []  newParts            = new ConnectionDescription [6];
        PhysicalConnectionType [] physicalConnections = new PhysicalConnectionType [6];
        int [] auxilaryConnections = new int [6];

//			adjacent.ForEach((obj) => obj.parent = transform);

        for (int i = 0; i < 6; i++)
        {
            int newDirection = (i + directionChange) % 6;
            newParts[i] = _connectedParts[newDirection];

            physicalConnections[i] = _connectedParts[newDirection].connectionType;
            auxilaryConnections[i] = _connectedParts[newDirection].auxConnectionTypes;
        }
        for (int i = 0; i < 6; i++)
        {
            int newDirection = (i + directionChange) % 6;
            _connectedParts[i] = newParts[i];

            if (_connectedParts[i].connectedPart == null)
            {
                physicalConnections[i] = PhysicalConnectionType.None;
                auxilaryConnections[i] = 0;
            }
//			Debug.Log ("Replacing Connection ("+(HexMetrics.Direction)newDirection+") "+ _connectedParts[i].connectionType +" -> ("+(HexMetrics.Direction)i+") " + physicalConnections[i]);
            SetPhysicalConnection((HexMetrics.Direction)i, physicalConnections[i], SplitOptions.DoNotSplit);
            SetAuxilaryConnections((HexMetrics.Direction)i, auxilaryConnections[i]);
        }

        if (ParentConstruction != null)
        {
            return(ParentConstruction.CheckForSplitsOrJoins());
        }
        return(new HashSet <Construction>());
    }
예제 #16
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);
    }
예제 #17
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,
             });
         }
     }
 }
예제 #18
0
//	public void Decode(string code, Dictionary<int, GrabbablePart> idParts)
//	{
//		ConstructionElement constructionElement = new ConstructionElement();
//		constructionElement.id          =                       CharSerializer.ToNumber(code[0]);
//		constructionElement.partType    =             (PartType)CharSerializer.ToNumber(code[1]);
//		SimulationOrientation = (HexMetrics.Direction)CharSerializer.ToNumber(code[2]);
//		for (int i = 0 ; i < 6 ; i++)
//		{
//			constructionElement.connectedParts[i]         =                                       CharSerializer.ToNumber(code[3+(i*3)+0]);
//			constructionElement.physicalConnectionType[i] = (GrabbablePart.PhysicalConnectionType)CharSerializer.ToNumber(code[3+(i*3)+1]);
//			constructionElement.auxilaryConnectionType[i] =                                       CharSerializer.ToNumber(code[3+(i*3)+2]);
//		}
//
//		return constructionElement;
//		return null;
//	}



    #endregion

    void Awake()
    {
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction absoluteIDir = (HexMetrics.Direction)i;

            if (Weldable(i))
            {
                _weldSpriteObjects[i] = Instantiate(GameSettings.instance.weldPrefab) as GameObject;                //ObjectPoolManager.GetObject(GameSettings.instance.weldPrefab);
                _weldSpriteObjects[i].transform.parent        = transform;
                _weldSpriteObjects[i].transform.localPosition = Vector3.zero;
                _weldSpriteObjects[i].transform.localRotation = Quaternion.Euler(0, 0, -60 * i);
                _weldSpriteObjects[i].transform.localScale    = Vector3.zero;
            }
        }
    }
예제 #19
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);
    }
    private int GetSuggestedRotation(GrabbablePart part)
    {
        List <Construction.PartSide> partSides = new List <Construction.PartSide>();

        targetConstructions.ForEach((con) => partSides.AddRange(con.IsConnectable(part)));

        ClearInnerArrows();

        foreach (Construction.PartSide partSide in partSides)
        {
            Color   drawColor = new Color [] { Color.green, Color.yellow, Color.blue, Color.red }[Mathf.Abs(partSide.offsetFromSide)];
            Vector3 offset    = GameSettings.instance.hexCellPrefab.GetDirection(partSide.part.Absolute(partSide.relativeDirection));
            Debug.DrawLine(partSide.part.transform.position, partSide.part.transform.position + offset, drawColor);

            if (partSide.offsetFromSide == 0)
            {
                HexMetrics.Direction absoluteDir = partSide.part.Absolute(partSide.relativeDirection);
                _innerArrows[(int)absoluteDir].transform.localScale = Vector3.one;
                _innerArrows[(int)absoluteDir].transform.position   = partSide.part.transform.position;

                _oppositeInnerArrows[(int)absoluteDir].transform.localScale = Vector3.one;
                _oppositeInnerArrows[(int)absoluteDir].transform.position   = part.transform.position;
            }
//			Debug.Log ("is connectable "+partSide.part.name +" in "+partSide.relativeDirection+" ("+partSide.offsetFromSide+")");
        }


//		partSides.Sort((x, y) => Mathf.Abs(part.SimulationRotationDifference(x.relativeDirection)) - Mathf.Abs(part.SimulationRotationDifference(y.relativeDirection)));
        partSides.Sort((x, y) => Mathf.Abs(x.offsetFromSide) - Mathf.Abs(y.offsetFromSide));

//		Debug.Log (string.Join (",", partSides.ConvertAll((input) => ""+input.offsetFromSide).ToArray()));

        if (partSides.Count > 0)
        {
            Construction.PartSide partSide = partSides[0];
//			Debug.Log ("rotating towards "+partSides[0].part.name+" ("+partSides[0].offsetFromSide+")");
            return(partSide.offsetFromSide);
        }

        return(0);
    }
예제 #21
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);
        }
    }
예제 #22
0
    public IEnumerable <IEncodable> EncodeWithContext(Dictionary <GrabbablePart, int> partIDs)
    {
//		Debug.Log("GrabbablePart::EncodeWithContext "+name);

        int id = partIDs[this];

        yield return((EncodableInt)id);

        yield return((EncodableInt)(int)partType);

        yield return((EncodableInt)(int)SimulationOrientation);

//		string code = ""+CharSerializer.ToCode()+CharSerializer.ToCode((int)partType)+CharSerializer.ToCode((int)SimulationOrientation);
        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction iDir     = (HexMetrics.Direction)i;
            GrabbablePart        connPart = GetConnectedPart(iDir);
            int connPartID       = connPart == null ? 0 : partIDs[connPart];
            int physicalConnType = (int)GetPhysicalConnectionType(iDir);
            int auxilaryConnType = (int)GetAuxilaryConnectionTypes(iDir);
            if (physicalConnType == (int)PhysicalConnectionType.None)             // i.e. None
            {
                connPartID       = 0;
                auxilaryConnType = 0;
            }

            yield return((EncodableInt)connPartID);

            yield return((EncodableInt)(int)physicalConnType);

            yield return((EncodableInt)(int)auxilaryConnType);
//			code += ""+
//					CharSerializer.ToCode(connPartID)+
//					CharSerializer.ToCode((int)physicalConnType)+
//					CharSerializer.ToCode((int)auxilaryConnType);
        }

//		return code;
    }
예제 #23
0
    private bool HasSimilarConnectionsTo(GrabbablePart part1, GrabbablePart part2, int part2DirectionOffset)
    {
        for (int i = 0; i < 6; i++)
        {
            int p2i = (i + part2DirectionOffset) % 6;
            HexMetrics.Direction p1Dir = (HexMetrics.Direction)i;
            HexMetrics.Direction p2Dir = (HexMetrics.Direction)p2i;

            GrabbablePart p1ConnectedPart = part1.GetConnectedPart(p1Dir);
            GrabbablePart p2ConnectedPart = part2.GetConnectedPart(p2Dir);
            if (p1ConnectedPart == null && p2ConnectedPart == null)
            {
                continue;
            }

            if (p1ConnectedPart != null && p2ConnectedPart != null)
            {
                if (p1ConnectedPart.partType != p2ConnectedPart.partType)
                {
                    return(false);
                }
                if (part1.GetPhysicalConnectionType(p1Dir) != part2.GetPhysicalConnectionType(p2Dir))
                {
                    return(false);
                }
                if (part1.GetAuxilaryConnectionTypes(p1Dir) != part2.GetAuxilaryConnectionTypes(p2Dir))
                {
                    return(false);
                }
            }
            else             // one is null other is connected
            {
                return(false);
            }
        }

        return(true);
    }
예제 #24
0
    public bool WillSimulationOrientationRotatateSplitConstruction(int offset)
    {
        bool hasNoConnections = true;

        for (int i = 0; i < 6; i++)
        {
            HexMetrics.Direction relativeI    = (HexMetrics.Direction)i;
            HexMetrics.Direction newRelativeI = (HexMetrics.Direction)((i + offset + 6) % 6);

            // if the new direction will connect to a part, then the construction will not split
            if (GetConnectedPart(relativeI) != null)
            {
                Debug.Log(GetConnectedPart(relativeI).name + ":" + Weldable(newRelativeI));
                // it is connected in this direction
                if (Weldable(newRelativeI))
                {
                    return(false);
                }
                hasNoConnections = false;
            }
        }

        return(!hasNoConnections);
    }
예제 #25
0
    public bool Weldable(HexMetrics.Direction dir)
    {
        switch (dir)
        {
        case HexMetrics.Direction.Up:
            return(weldsUp);

        case HexMetrics.Direction.RightUp:
            return(weldsRightUp);

        case HexMetrics.Direction.LeftUp:
            return(weldsLeftUp);

        case HexMetrics.Direction.Down:
            return(weldsDown);

        case HexMetrics.Direction.RightDown:
            return(weldsRightDown);

        case HexMetrics.Direction.LeftDown:
            return(weldsLeftDown);
        }
        return(false);
    }
예제 #26
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);
    }
예제 #27
0
    public IEnumerable <PartSide> IsConnectable(GrabbablePart otherPart)
    {
        Vector3 otherPartLocation = otherPart.PartSphereCollider.transform.position;
        float   radSq             = otherPart.PartSphereCollider.radius * otherPart.PartSphereCollider.radius;

        foreach (GrabbablePart part in Parts)
        {
            Vector3 partLocation = part.transform.position;
            if (Vector3.SqrMagnitude(otherPartLocation - partLocation) < radSq)
            {
                yield break;
            }
        }
//		List<PartSide> partSides = new List<PartSide>();
        foreach (GrabbablePart part in Parts)
        {
            for (int i = 0; i < 6; i++)
            {
                HexMetrics.Direction iDir         = (HexMetrics.Direction)i;
                HexMetrics.Direction iDirRelative = part.Relative(iDir);
                if (part.GetConnectedPart(iDirRelative) == null)
                {
                    Vector3 partLocation          = part.transform.position;
                    Vector3 potentialPartLocation = partLocation + (Vector3)GameSettings.instance.hexCellPrefab.GetDirection(iDir);

                    if (Vector3.SqrMagnitude(otherPartLocation - potentialPartLocation) < radSq)
                    {
                        HashSet <HexMetrics.Direction> weldableRotations = new HashSet <HexMetrics.Direction>(part.IsWeldableWithRotationFactor(iDirRelative, otherPart));
//						Debug.Log(string.Join(", ", new List<HexMetrics.Direction>(weldableRotations).ConvertAll<string>((input) => ""+input).ToArray()));
//						Color debugColor = Color.red;

                        if (weldableRotations.Count > 0)
                        {
                            PartSide partSide = new PartSide();
                            foreach (HexMetrics.Direction weldableDir in new HexMetrics.Direction[] {
                                HexMetrics.Direction.Down,
                                HexMetrics.Direction.LeftDown,
                                HexMetrics.Direction.RightDown,
                                HexMetrics.Direction.LeftUp,
                                HexMetrics.Direction.RightUp,
                                HexMetrics.Direction.Up
                            })
                            {
                                if (weldableRotations.Contains(weldableDir))
                                {
                                    partSide.offsetFromSide = GrabbablePart.RotationDifference(weldableDir);
                                }
                            }
                            partSide.part = part;
                            partSide.relativeDirection = iDirRelative;

                            yield return(partSide);
                        }
//							debugColor = Color.green;
//						}


//						Debug.Log("Found at "+part.name+" in "+iDir);
//						Debug.DrawLine(part.transform.position, potentialPartLocation, debugColor);
                    }
                }
            }
        }
    }
예제 #28
0
 public static int RotationDifference(HexMetrics.Direction a)
 {
     return(RotationDifference(a, HexMetrics.Direction.Up));
 }
예제 #29
0
 public static int RotationDifference(HexMetrics.Direction a, HexMetrics.Direction b)
 {
     HexMetrics.Direction diff = (HexMetrics.Direction)((int)a - (int)b);
     return((((int)diff + 3) % 6) - 3);
 }
    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);
    }