Browse Source

Added building positioning rules system

James Peret 2 years ago
parent
commit
95996a07b6

+ 8 - 4
Runtime/BuildingBlueprintController.cs

@@ -33,7 +33,7 @@ namespace KairoEngine.VoxelBuildingSystem
         private void LateUpdate() {
             if(currentBlueprint == null) return;
             var template = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate];
-            Vector3Int targetPosition = buildingSystem.GetMouseVoxelPosition();
+            Vector3Int targetPosition = buildingSystem.GetMouseBuildingPosition();
             Vector3Int dir = buildingSystem.rotationList[buildingSystem.currentRotationIndex];
             Quaternion rotation = Quaternion.Euler(dir.x, dir.y, dir.z);
             currentBlueprint.transform.position = Vector3.Lerp(currentBlueprint.transform.position, targetPosition, Time.deltaTime * 15f);
@@ -46,6 +46,8 @@ namespace KairoEngine.VoxelBuildingSystem
         }
 
         private void RefreshVisual() {
+            Quaternion currentRotation = currentBlueprint.transform.rotation;
+            Vector3 currentPosition = currentBlueprint.transform.position;
             if (currentBlueprint != null) {
                 Destroy(currentBlueprint.gameObject);
                 currentBlueprint = null;
@@ -53,7 +55,7 @@ namespace KairoEngine.VoxelBuildingSystem
             BuildingTemplate buildingTemplate = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate];
             if (buildingTemplate != null) {
                 Vector3 targetPosition = buildingSystem.GetMouseWorldSnappedPosition();
-                currentBlueprint = Instantiate(buildingTemplate.visual, targetPosition, Quaternion.identity);
+                currentBlueprint = Instantiate(buildingTemplate.visual, currentPosition, currentRotation);
                 currentBlueprint.parent = transform;
                 // currentBlueprint.localPosition = Vector3.zero;
                 // currentBlueprint.localEulerAngles = Vector3.zero;
@@ -63,17 +65,19 @@ namespace KairoEngine.VoxelBuildingSystem
         private bool canBuild;
         private Vector3Int lastPosition;
         private int lastTemplateIndex;
+        private int lastRotationIndex;
         private void CanBuild()
         {
-            Vector3Int pos = buildingSystem.GetMouseVoxelPosition();
+            Vector3Int pos = buildingSystem.GetMouseBuildingPosition();
             int templateIndex = buildingSystem.currentBuildingTemplate;
             int rotationIndex = buildingSystem.currentRotationIndex;
-            if(lastPosition != pos || lastTemplateIndex != templateIndex)
+            if(lastPosition != pos || lastTemplateIndex != templateIndex || lastRotationIndex != rotationIndex)
             {
                 //Debug.Log("Position changed, updating blueprint materials");
                 canBuild = buildingSystem.CanPlaceBuilding(pos, templateIndex, rotationIndex);
                 lastPosition = pos;
                 lastTemplateIndex = templateIndex;
+                lastRotationIndex = rotationIndex;
                 ChangeMaterials();
             }
         }

+ 6 - 1
Runtime/BuildingTemplate.cs

@@ -18,8 +18,13 @@ namespace KairoEngine.VoxelBuildingSystem
         [BoxGroup("Properties")] public Sprite icon;
         [BoxGroup("Properties"), TextArea(2, 8), HideLabel, PropertySpace(4, 4)] public string description;
 
+        public List<Stockpile> cost = new List<Stockpile>();
         public List<VoxelConnectorData> connectors = new List<VoxelConnectorData>();
+        
 
-        public List<Stockpile> cost = new List<Stockpile>();
+        [BoxGroup("Rules")] public ConditionType rulesetCondition;
+        [BoxGroup("Rules")] public List<VoxelBuildingRuleset> rulesets = new List<VoxelBuildingRuleset>();
+
+        
     }
 }

+ 54 - 0
Runtime/VoxelBuildingRule.cs

@@ -0,0 +1,54 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Sirenix.OdinInspector;
+using KairoEngine.Chunks;
+
+namespace KairoEngine.VoxelBuildingSystem
+{
+    public enum RuleType
+    {
+        EmptyVoxels
+    }
+
+    [System.Serializable]
+    public class VoxelBuildingRule
+    {
+        private string title 
+        {
+            get 
+            {
+                switch (rule)
+                {
+                    case RuleType.EmptyVoxels: return $"Empty voxels";
+                    default: return "?";
+                }
+            }
+        }
+
+        [SerializeField, FoldoutGroup("@title")] private RuleType rule;
+        public bool Evaluate(VoxelBuildingSystem buildingSystem, int templateIndex, Vector3Int position, int rotationIndex)
+        {
+            switch (rule)
+            {
+                case RuleType.EmptyVoxels: return EvaluateEmptyVoxels(buildingSystem, templateIndex, position, rotationIndex);
+                default: return false;
+            }
+        }
+
+        public bool EvaluateEmptyVoxels(VoxelBuildingSystem buildingSystem, int templateIndex, Vector3Int position, int rotationIndex)
+        {
+            List<Vector3Int> voxelPositions = buildingSystem.GetBuildingVoxelList(position, templateIndex, rotationIndex);
+            for (int i = 0; i < voxelPositions.Count; i++)
+            {
+                VoxelBuildData block = buildingSystem.chunkSystem.GetBlock(voxelPositions[i]);
+                if(block.buildingIndex != -1) 
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+}

+ 11 - 0
Runtime/VoxelBuildingRule.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1e1260137b2b7be40ae83e66f4757812
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 47 - 0
Runtime/VoxelBuildingRuleset.cs

@@ -0,0 +1,47 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Sirenix.OdinInspector;
+using KairoEngine.Chunks;
+
+namespace KairoEngine.VoxelBuildingSystem
+{
+    [System.Serializable]
+    public class VoxelBuildingRuleset
+    {
+        public ConditionType condition;
+        public List<VoxelBuildingRule> rules = new List<VoxelBuildingRule>();
+
+        public bool Evaluate(VoxelBuildingSystem buildingSystem, int templateIndex, Vector3Int position, int rotationIndex)
+        {
+            List<bool> results = new List<bool>();
+            for (int i = 0; i < rules.Count; i++)
+            {
+                results.Add(rules[i].Evaluate(buildingSystem, templateIndex, position, rotationIndex));
+            }
+            if(condition == ConditionType.AND)
+            {
+                foreach (var value in results)
+                {
+                    if(value == false) return false;
+                }
+                return true;
+            }
+            else
+            {
+                foreach (var value in results)
+                {
+                    if(value == true) return true;
+                }
+                return false;
+            }
+        }
+        
+    }
+
+    public enum ConditionType
+    {
+        AND,
+        OR
+    }
+}

+ 11 - 0
Runtime/VoxelBuildingRuleset.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dae9d6bc20e615d4dab52648a03e2f07
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 17
Runtime/VoxelBuildingSystem.cs

@@ -87,9 +87,9 @@ namespace KairoEngine.VoxelBuildingSystem
             Vector3Int buildingPos = GetMouseBuildingPosition();
             Vector3Int voxelPos = GetMouseVoxelPosition();
             Vector3Int buildingRotation = rotationList[currentRotationIndex];
-            if(!CanPlaceBuilding(voxelPos, currentBuildingTemplate, currentRotationIndex, true)) return;
+            if(!CanPlaceBuilding(buildingPos, currentBuildingTemplate, currentRotationIndex, true)) return;
             Quaternion rotation = Quaternion.Euler(buildingRotation.x, buildingRotation.y, buildingRotation.z);
-            Transform newBuilding = Instantiate(buildingTemplates[currentBuildingTemplate].prefab, voxelPos, rotation, this.transform);
+            Transform newBuilding = Instantiate(buildingTemplates[currentBuildingTemplate].prefab, buildingPos, rotation, this.transform);
             BuildingBehaviour buildingBehaviour = newBuilding.GetComponent<BuildingBehaviour>();
             if(buildingBehaviour == null)
             {
@@ -97,10 +97,10 @@ namespace KairoEngine.VoxelBuildingSystem
                 Destroy(newBuilding);
                 return;
             }
-            buildingBehaviour.origin = voxelPos;
-            buildings.Add(voxelPos, buildingBehaviour);
+            buildingBehaviour.origin = buildingPos;
+            buildings.Add(buildingPos, buildingBehaviour);
             buildingList.Add(buildingBehaviour);
-            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, currentBuildingTemplate, currentRotationIndex);
+            List<Vector3Int> voxelPositions = GetBuildingVoxelList(buildingPos, currentBuildingTemplate, currentRotationIndex);
             for (int i = 0; i < voxelPositions.Count; i++)
             {
                 VoxelBuildData block = chunkSystem.GetBlock(voxelPositions[i]);
@@ -127,17 +127,7 @@ namespace KairoEngine.VoxelBuildingSystem
 
         public bool CanPlaceBuilding(Vector3Int voxelPos, int buildingTemplateIndex, int buildingRotationIndex = 0, bool debug = false)
         {
-            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, buildingTemplateIndex, buildingRotationIndex);
-            for (int i = 0; i < voxelPositions.Count; i++)
-            {
-                VoxelBuildData block = chunkSystem.GetBlock(voxelPositions[i]);
-                if(block.buildingIndex != -1) 
-                {
-                    if(debug) Debug.Log("Cannot place building, place is occupied.");
-                    return false;
-                }
-            }
-            return true;
+            return EvaluateRuleset(voxelPos, buildingRotationIndex, buildingTemplateIndex);
         }
 
         public Vector3Int FindVoxelPosition(Vector3 pos)
@@ -152,7 +142,7 @@ namespace KairoEngine.VoxelBuildingSystem
         {
             Vector3Int voxelPos = FindVoxelPosition(pointerPosition);
             Vector3Int rotationOffset = GetRotationOffset(currentRotationIndex, buildingTemplates[currentBuildingTemplate].size);
-            return voxelPos + rotationOffset;
+            return voxelPos - rotationOffset;
         }
 
         public List<Vector3Int> GetBuildingVoxelList(Vector3Int offset, int buildingTemplateId, int buildingRotationIndex = 0) 
@@ -308,6 +298,35 @@ namespace KairoEngine.VoxelBuildingSystem
         
         #endregion
 
+        #region Rules
+
+        public bool EvaluateRuleset(Vector3Int position, int rotationIndex, int templateIndex)
+        {
+            List<bool> results = new List<bool>();
+            BuildingTemplate template = buildingTemplates[currentBuildingTemplate];
+            for (int i = 0; i < template.rulesets.Count; i++)
+            {
+                results.Add(template.rulesets[i].Evaluate(this, templateIndex, position, rotationIndex));
+            }
+            if(template.rulesetCondition == ConditionType.AND)
+            {
+                foreach (var value in results)
+                {
+                    if(value == false) return false;
+                }
+                return true;
+            }
+            else
+            {
+                foreach (var value in results)
+                {
+                    if(value == true) return true;
+                }
+                return false;
+            }
+        }
+
+        #endregion
     }
 
     public enum VoxelBuildingTool