Example #1
0
        private static bool NeedsAll(BeyondComponent bc, BeyondGroup bg, List <string> templatesList, List <Vector3Int> offsetsList, List <cellSide> cellSides, Vector3Int?optionalGroupPos = null)
        {
            if (bg == null)
            {
                return(false);
            }
            Vector3Int groupPos = (optionalGroupPos != null) ? (Vector3Int)optionalGroupPos : bc.groupPosition;

            foreach (string templateName in templatesList)
            {
                foreach (Vector3Int offset in offsetsList)
                {
                    bool foundOne = false;
                    foreach (cellSide side in cellSides)
                    {
                        if (IsTemplatePresentHere(bg, groupPos + offset, templateName, side))
                        {
                            foundOne = true;
                        }
                    }
                    if (!foundOne)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Example #2
0
        void StartDrag()
        {
            ForwardOffsetBeforeDragging = UIController.Instance.forwardOffset;
            if (ConstraintController.CanPlace(currentBC))
            {
                string templateName = currentBC.template.name;
                string name         = templateName + "_" + (nbObjectsPlaced++);

                // Place the first Ghost = still green, still not collidin'
                TemplateController.PlaceObject(currentBC, name, BC_State.Ghost);

                draggedBC.Add(currentBC);
                draggingGroup     = currentBC.beyondGroup;
                lastGroupPosition = currentBC.groupPosition;

                currentBC = null;
                CreateNewPlaceableObject(templateName);
                // TODO : another hardcoded position. Not good. Yet, I must move the currentBC to where I started dragging or else I'm going to drag to some unknown place.
                currentBC.transform.position = draggedBC[0].transform.position;
                currentBC.transform.rotation = draggedBC[0].transform.rotation;

                // Instantiate a big bunch of placeable object based on what we are currently dragging
                for (int i = 0; i < MaxDraggedObjectCount; i++)
                {
                    BeyondComponent bc = TemplateController.CreateObject(templateName);
                    //TODO Better names, please
                    name = templateName + "_Ghost" + i;
                    bc.SetBCinGroup(draggingGroup, lastGroupPosition);
                    TemplateController.PlaceObject(bc, name, BC_State.Ghost);
                    bc.gameObject.SetActive(false);
                    draggedBC.Add(bc);
                }
            }
        }
Example #3
0
        /*
         * Sets the group of this BC, its position in the gorup, and places the object where it must be
         */
        /*
         * public void setObjectGroup (BeyondGroup g , Vector3Int p , cellSide cs , bool firstObject=false)
         * { // TODO should make that more robust : what if g is null ?
         *  unsetObjectGroup();
         *  if (g!=null)
         *  {
         *      beyondGroup = g ;
         *      groupPosition = p ;
         *      side = cs ;
         *      // The first object should not be offset or rotated by the group, since it sets the group position and rotation
         *      if (!firstObject)
         *      {
         *          // Rotate the pivot offset by the group's rotation
         *          Vector3 rotatedPivotOffset = template.pivotOffset ;
         *          rotatedPivotOffset = g.rotation * rotatedPivotOffset ;
         *          // Then  by the sideRotation
         *          rotatedPivotOffset = sideRotation(cs) * rotatedPivotOffset ;
         *
         *          // Move the object to its template offset position
         *          transform.position += rotatedPivotOffset;
         *
         *          // Rotate the object by the group's rotation + its cellSide rotation
         *          transform.rotation = g.rotation * sideRotation(cs) ;
         *      }
         *      g.addBeyondComponent(this);
         *  }
         * }
         */

        public void SetBCinGroup(BeyondGroup g, Vector3Int p, bool firstObject = false)
        { // TODO should make that more robust : what if g is null ?
            unsetObjectGroup();
            if (g != null)
            {
                beyondGroup   = g;
                groupPosition = p;

                // If this template can only be on a specific side, use it, otherwise determine the side based on the rotation of the BC
                side = (template.fixedSide == null) ? getSideByRotation(this, g, p) : (cellSide)template.fixedSide;

                //TODO : Maybe I need one last check based on side : is there really no object here on the same postion and rotation

                // The first object should not be offset or rotated by the group, since it sets the group position and rotation
                if (!firstObject)
                {
                    // Rotate the cell's position to apply the group's rotation
                    Vector3 rotatedCellPosition = Utility.RotateAroundPoint(p, Vector3.zero, g.rotation);
                    // Rotate the pivot's position to apply the group's rotation and the side's rotation
                    Vector3 rotatedPivotOffset = Utility.RotateAroundPoint(template.pivotOffset, Vector3.zero, sideRotation(side) * g.rotation);
                    Vector3 ObjectPosition     = g.position + rotatedCellPosition + rotatedPivotOffset;

                    transform.position = ObjectPosition;
                    // Rotate the object by the group's rotation + its cellSide rotation
                    transform.rotation = g.rotation * sideRotation(side);
                }
                g.addBeyondComponent(this);
            }
        }
Example #4
0
        private List <BeyondGroup> findCloseGroups(BeyondComponent bc, out BeyondGroup closestGroup)
        {
            List <BeyondGroup> result = new List <BeyondGroup>();

            // Find the groups that are close to this BeyondComponent
            Collider[] collidersInGroup = Physics.OverlapBox(bc.transform.position, bc.template.castBox + new Vector3(1f, 1f, 1f) * groupSnapTolerance, bc.transform.rotation, ConstraintController.getBuildingsMask());
            closestGroup = null;
            float minDistance = 0;

            foreach (Collider c in collidersInGroup)
            {
                BeyondComponent collided_bc = c.transform.GetComponent <BeyondComponent>();
                if (collided_bc != null && collided_bc.beyondGroup != null)
                {
                    result.Add(collided_bc.beyondGroup);
                    float distance = Vector3.Distance(bc.transform.position, collided_bc.transform.position);
                    if (closestGroup == null || distance < minDistance)
                    {
                        minDistance  = distance;
                        closestGroup = collided_bc.beyondGroup;
                    }
                }
            }
            UIController.Instance.SetClosestGroup(closestGroup);

            return(result);
        }
Example #5
0
 public static bool IsTemplatePresentHere(BeyondGroup group, Vector3Int here, string t_name)
 {
     if (group == null)
     {
         return(false);
     }
     // TODO : With the restriction on Ghosts, I can't snap dragged objects. Is there a way around this ?
     return(group.BeyondComponentsAt(here).Exists(bc => bc.template.name == t_name && bc.state != BC_State.Ghost));
 }
Example #6
0
 private static bool AndConstraints(BeyondComponent bc, BeyondGroup bg, List <Constraints> lc, Vector3Int?optionalGroupPos = null)
 {
     foreach (Constraints c in lc)
     {
         if (!CheckConstraints(bc, c, bg, optionalGroupPos))
         {
             return(false);
         }
     }
     return(true);
 }
Example #7
0
 private static bool FirstInGroup(BeyondComponent bc, BeyondGroup bg)
 {
     if (bg == null)
     {
         return(true);          // By definition, if there's no group, the bc fulfills this constraint
     }
     if (bg.componentList.Count == 1)
     {
         return(true);
     }
     return(false);
 }
Example #8
0
        public void StopDragging()
        {
            List <GameObject> objectsPlaced = new List <GameObject>();
            GameObject        FirstObject   = Instantiate(GameObject_DragFrom);
            BeyondComponent   BC_DragFrom   = GameObject_DragFrom.GetComponent <BeyondComponent>();

            FirstObject.GetComponent <BeyondComponent>().CopyValues(BC_DragFrom);
            SetBlueprintFromGhost(FirstObject);
            objectsPlaced.Add(FirstObject);
            Destroy(GameObject_DragFrom);

            for (int i = 0; i < draggedObjects.Count; i++) // Note: a for loop is better than a foreach that can miss some objects
            {
                // TO DO : We need to check a bit more than that: can't have a bunch of objects split in several groups because they failed constraint. All draggedObject should form 1 block
                // And, as stated in the AvoidCollision Constraint, if adding to an existing group we should check the object is in a valid group position:
                // As above: no isolated objects, but also no 2 same objects in the same cell, all objects have at least one Snaptarget, etc
                if (draggedObjects[i].activeSelf && Constraint.CheckRootConstraint(draggedObjects[i]))
                {
                    GameObject      ThisObject    = Instantiate(draggedObjects[i]);
                    BeyondComponent BC_ThisObject = draggedObjects[i].GetComponent <BeyondComponent>();
                    ThisObject.GetComponent <BeyondComponent>().CopyValues(BC_ThisObject);
                    SetBlueprintFromGhost(ThisObject);
                    objectsPlaced.Add(ThisObject);
                }
                Destroy(draggedObjects[i]);
            }
            draggedObjects.Clear();
            DestroyActiveBlueprint();

            // When snapping, the Active blueprint is already in a group, which we should use, otherwise create a new one
            BeyondGroup bg = null;

            if (SnappedToObject != null)
            {
                bg = SnappedToObject.GetComponent <BeyondComponent>().Group;
                //Debug.Log("I should add all these to the group of the object I was snapped to: "+bg.Name);
                SnappedToObject = null;
            }

            // Create BeyondGroup, add all objects to it
            foreach (GameObject go in objectsPlaced)
            {
                if (bg == null)
                {
                    bg = CreateNewBeyondGroup(go);
                }
                bg.AddObject(go);
                // Only set the layer at the end, so objects don't collide into each other and fail the constraint check
                go.layer = LayerMask.NameToLayer("Buildings");
            }
        }
Example #9
0
 public SavedComponent(BeyondComponent bc)
 {
     template      = bc.template.name;
     state         = bc.state;
     group         = bc.beyondGroup;
     side          = bc.side;
     groupPosition = bc.groupPosition;
     cells         = bc.cells;
     position      = bc.transform.position;
     rotation      = bc.transform.rotation;
     name          = bc.transform.gameObject.name;
     layer         = bc.transform.gameObject.layer;
     isTrigger     = bc.transform.gameObject.GetComponent <BoxCollider>().isTrigger;
     enabled       = bc.transform.gameObject.GetComponent <BoxCollider>().enabled;
 }
Example #10
0
        public void CreateNewBeyondGroup(BeyondComponent bc, string name = null)
        {
            if (name == null)
            { // Auto give name
                name = String.Format("Group {0:0000}", place.beyondGroups.Count);
            }
            // bc.transform.position - bc.template.pivotOffset : THIS IS ESSENTIAL - This allows us to properly set the pivot of the group
            BeyondGroup group = new BeyondGroup(name, bc.transform.position - bc.template.pivotOffset, bc.transform.rotation);

            if (bc != null)
            {
                group.addBeyondComponent(bc);
                // Vector3Int.zero because the first object in a group is at position [0,0,0]
                bc.SetBCinGroup(group, Vector3Int.zero, true);
            }
            place.beyondGroups.Add(group);
        }
Example #11
0
        private void PlaceOnClic()
        {
            if (Input.GetMouseButtonUp(0))
            {
                //TODO : dragging stuff - make it better
                for (int i = 0; i < draggedBC.Count; i++)
                {
                    if (draggedBC[i].gameObject.activeSelf && ConstraintController.CanPlace(draggedBC[i]))
                    {
                        string name = currentBC.template.name + "_" + (nbObjectsPlaced++);
                        TemplateController.PlaceObject(draggedBC[i], name, BC_State.Blueprint);
                    }
                    else
                    {
                        Destroy(draggedBC[i].gameObject);
                    }
                }
                Destroy(currentBC.gameObject);
                draggingGroup = null;
                draggedBC.Clear();
                UIController.Instance.SetForwardOffset(ForwardOffsetBeforeDragging); // reset ForwardOffset to what it was before dragging - less annoying

                /*
                 * This works for 1 clic :
                 *
                 * if (ConstraintController.CanPlace(currentPlaceableObject))
                 * {
                 *  string name = currentBC.template.name + "_" + (nbObjectsPlaced++) ;
                 *  TemplateController.PlaceObject(ref currentPlaceableObject , name , BC_State.Blueprint) ;
                 * }
                 * else
                 * {
                 *  //Debug.Log("Destroyed currentPlaceableObject "+ currentPlaceableObject .GetInstanceID()+ " as I couldn't place it");
                 *  Destroy(currentPlaceableObject);
                 * }
                 */
            }
        }
Example #12
0
        private static bool NeedsOne(BeyondComponent bc, BeyondGroup bg, List <string> templatesList, List <Vector3Int> offsetsList, List <cellSide> cellSides, Vector3Int?optionalGroupPos = null)
        {
            if (bg == null)
            {
                return(false);
            }
            Vector3Int groupPos = (optionalGroupPos != null) ? (Vector3Int)optionalGroupPos : bc.groupPosition;

            foreach (string templateName in templatesList)
            {
                foreach (Vector3Int offset in offsetsList)
                {
                    foreach (cellSide side in cellSides)
                    {
                        if (IsTemplatePresentHere(bg, groupPos + offset, templateName, side))
                        {
                            return(true);
                        }
                    }
                }
            }
            Debug.Log("Check constraints NEEDSONE returned FALSE");
            return(false);
        }
Example #13
0
        public static cellSide getSideByRotation(BeyondComponent bc, BeyondGroup group, Vector3Int pos)
        {
            float d = Vector3.Distance(bc.transform.position - bc.template.pivotOffset, group.position + (Vector3)pos);

            Debug.Log("getSideByRotation. Distance from pivot=" + d);
            Quaternion r = bc.transform.rotation;
            //TODO : Back & Front / Left & Right can both be returned based on how close we are from one edge or the other.
            // So this function must do better than this and work on a transform, not just a Quaternion
            float angle = Quaternion.Angle(Quaternion.identity, r);

            if (angle > 45f && angle <= 135f)
            {
                return(cellSide.Right);
            }
            if (angle > 135f && angle <= 225f)
            {
                return(cellSide.Front);
            }
            if (angle > 225f && angle <= 315f)
            {
                return(cellSide.Left);
            }
            return(cellSide.Back);
        }
Example #14
0
        //TO DO : refactor that with love & care
        public BeyondGroup CreateNewBeyondGroup(GameObject go, string name = null)
        {
            // Auto give name
            if (name == null)
            {
                name = String.Format("Group {0:0000}", GameManager.instance.Place.BeyondGroups.Count);
            }

            BeyondComponent bc = go.GetComponent <BeyondComponent>();

            if (bc != null)
            {
                // bc.transform.position - bc.template.pivotOffset : THIS IS ESSENTIAL - This allows us to properly set the pivot of the group
                BeyondGroup group = new BeyondGroup(name, bc.transform.position - bc.Template.CellCentre, bc.transform.rotation);
                group.AddObject(go);
                GameManager.instance.Place.BeyondGroups.Add(group);
                return(group);
            }
            else
            {
                Debug.LogError("CreateNewBeyondGroup attempted to create an emtpy group");
            }
            return(null);
        }
Example #15
0
 public void SetGroupPosition(BeyondGroup bg, Vector3Int pos)
 {
     Group         = bg;
     GroupPosition = pos;
 }
Example #16
0
        /*
         * ============================================================
         * CONSTRAINTS CHECKING
         * ============================================================
         */

        // Check this BC's constraints (optionally in a group)
        public static bool CheckConstraints(BeyondComponent bc, Constraints c = null, BeyondGroup bg = null, Vector3Int?optionalGroupPos = null)
        {
            Constraints constraints = (c == null ? bc.template.constraints : c);

            //Debug.Log(String.Format("Checking constraint on {0} of group {1}: {2}" , bc.name , (bg==null ? "null" : bg.name) , Constraints.ShowConstraints(constraints)));
            //int i=0;
            switch (constraints.operation)
            {
            case "OR":
                //if (i++>1000) {Debug.Log("OR just exploded"); return false;}
                return(OrConstraints(bc, bg, constraints.constraintsList, optionalGroupPos));

            case "AND":
                //if (i++>1000) {Debug.Log("AND just exploded"); return false;}
                return(AndConstraints(bc, bg, constraints.constraintsList, optionalGroupPos));

            case "TOPCLEAR":
                //if (i++>1000) {Debug.Log("TOPCLEAR just exploded"); return false;}
                return(TopClear(bc, constraints.mask));

            case "ALLCLEAR":
                //if (i++>1000) {Debug.Log("ALLCLEAR just exploded"); return false;}
                return(AllClear(bc, constraints.mask));

            case "BASEIN":
                //if (i++>1000) {Debug.Log("BASEIN just exploded"); return false;}
                return(BaseInTerrain(bc));

            case "NEEDSONE":
                //if (i++>1000) {Debug.Log("NEEDSONE just exploded"); return false;}
                return(NeedsOne(bc, bg, constraints.templateNamesList, constraints.offsetsList, constraints.cellSides, optionalGroupPos));

            case "NEEDSALL":
                //if (i++>1000) {Debug.Log("BEEDSALL just exploded"); return false;}
                return(NeedsAll(bc, bg, constraints.templateNamesList, constraints.offsetsList, constraints.cellSides, optionalGroupPos));

            case "FIRSTINGROUP":
                //if (i++>1000) {Debug.Log("FIRSTINGROUP just exploded"); return false;}
                return(FirstInGroup(bc, bg));

            default:
                //if (i++>1000) {Debug.Log("CHeckConstraints just exploded"); return false;}
                return(false);
            }
        }
Example #17
0
        public static bool CanSnapTo(BeyondComponent bc, BeyondGroup group, Vector3Int here)
        {
            Debug.Log("CanSnapTo called on " + bc.name + " for group " + (group == null ? "null" : group.name) + " at " + here);
            if (group == null)
            {
                return(false);
            }

            if (bc.template.name == "Foundation")
            {
                // must not have the same object (Foundation) here
                if (IsTemplatePresentHere(group, here, "Foundation"))
                {
                    return(false);
                }
                // Must have a neighbouring Foundation in X or Z, same Y
                if (IsTemplatePresentHere(group, new Vector3Int(here.x - 1, here.y, here.z), "Foundation"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x + 1, here.y, here.z), "Foundation"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x, here.y, here.z - 1), "Foundation"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x, here.y, here.z + 1), "Foundation"))
                {
                    return(true);
                }
                Debug.Log("No neighbouring foundation  in group " + group.name);
                return(false);
            }
            if (bc.template.name == "Wall")
            {
                if (IsTemplatePresentHere(group, here, bc.template.name, BeyondComponent.getSideByRotation(bc, group, here)))
                {
                    Debug.Log("CanSnapTo FALSE = Can't have wall in the same position and side");
                    return(false); // Can't have wall in the same position and side
                }

                // There must be a foundation to place a Wall
                if (IsTemplatePresentHere(group, here, "Foundation"))
                {
                    Debug.Log("CanSnapTo TRUE = Found foundation");
                    return(true);
                }
                Debug.Log("CanSnapTo FALSE = No foundation");
                return(false);
            }
            if (bc.template.name == "Wallhole")
            {
                if (IsTemplatePresentHere(group, here, bc.template.name, BeyondComponent.getSideByRotation(bc, group, here)))
                {
                    return(false);                                                                                                            // Can't have wallhole in the same position and side
                }
                // There must be a foundation to place a Wall
                if (IsTemplatePresentHere(group, here, "Foundation"))
                {
                    return(true);
                }
                return(false);
            }
            if (bc.template.name == "Floor")
            {
                // must not have the same object (Floor) here
                if (IsTemplatePresentHere(group, here, "Floor"))
                {
                    return(false);
                }

                // There must be a Wall 3 cells below
                if (IsTemplatePresentHere(group, new Vector3Int(here.x, here.y - 3, here.z), "Wall"))
                {
                    return(true);
                }
                // Or a floor next to here
                if (IsTemplatePresentHere(group, new Vector3Int(here.x - 1, here.y, here.z), "Floor"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x + 1, here.y, here.z), "Floor"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x, here.y, here.z - 1), "Floor"))
                {
                    return(true);
                }
                if (IsTemplatePresentHere(group, new Vector3Int(here.x, here.y, here.z + 1), "Floor"))
                {
                    return(true);
                }
                return(false);
            }
            return(false);
        }
Example #18
0
 public void SetClosestGroup(BeyondGroup g)
 {
     closestGroup = g;
 }
Example #19
0
 public void Awake()
 {
     draggedBC     = new List <BeyondComponent>();
     draggingGroup = null;
 }