public static RegionGameLogic CreateRegion(GameObject parent, string regionGameLogicGuid, string objectiveGuid, string name, string regionDefId, float radius = 0)
        {
            GameObject regionGo     = CreateRegionGameObject(parent, name);
            float      regionRadius = (radius > 0) ? radius : DEFAULT_REGION_RADIUS;

            MeshCollider collider = regionGo.AddComponent <MeshCollider>();
            MeshFilter   mf       = regionGo.AddComponent <MeshFilter>();
            Mesh         mesh     = MeshTools.CreateHexigon(regionRadius);

            collider.sharedMesh = mesh;
            mf.mesh             = mesh;

            regionGo.AddComponent <TerrainDataChangeDetection>();
            regionGo.AddComponent <SnapToTerrain>();
            regionGo.AddComponent <MeshRenderer>();

            RegionGameLogic regionGameLogic = regionGo.AddComponent <RegionGameLogic>();

            regionGameLogic.encounterObjectGuid = regionGameLogicGuid;
            regionGameLogic.radius      = regionRadius;
            regionGameLogic.regionDefId = regionDefId;
            regionGameLogic.alwaysShowRegionWhenActive = true;

            CreateRegionPointGameObject(regionGo, $"RegionPoint1", new Vector3(0, 0, regionRadius));                     // North
            CreateRegionPointGameObject(regionGo, $"RegionPoint2", new Vector3(regionRadius, 0, regionRadius / 2f));     // North-East
            CreateRegionPointGameObject(regionGo, $"RegionPoint3", new Vector3(regionRadius, 0, -(regionRadius / 2f)));  // South-East
            CreateRegionPointGameObject(regionGo, $"RegionPoint4", new Vector3(0, 0, -regionRadius));                    // South
            CreateRegionPointGameObject(regionGo, $"RegionPoint5", new Vector3(-regionRadius, 0, -(regionRadius / 2f))); // South-West
            CreateRegionPointGameObject(regionGo, $"RegionPoint6", new Vector3(-regionRadius, 0, regionRadius / 2f));    // North-West

            return(regionGameLogic);
        }
Beispiel #2
0
        private void RegenerateRegion(GameObject regionGo)
        {
            CombatGameState combatState     = UnityGameInstance.BattleTechGame.Combat;
            RegionGameLogic regionGameLogic = regionGo.GetComponent <RegionGameLogic>();
            List <Vector3>  meshPoints      = new List <Vector3>();

            // Get all region points and fix the y height
            foreach (Transform t in regionGo.transform)
            {
                if (t.gameObject.name.StartsWith("RegionPoint"))
                {
                    Vector3 position            = t.position;
                    float   height              = combatState.MapMetaData.GetLerpedHeightAt(position);
                    Vector3 fixedHeightPosition = new Vector3(position.x, height, position.z);
                    t.position = fixedHeightPosition;
                    meshPoints.Add(t.localPosition);
                }
            }

            // Create new mesh from points and set to collider and mesh filter
            MeshCollider collider = regionGo.GetComponent <MeshCollider>();
            MeshFilter   mf       = regionGo.GetComponent <MeshFilter>();
            Mesh         mesh     = MeshTools.CreateHexigon(REGION_RADIUS, meshPoints);

            collider.sharedMesh = mesh;
            mf.mesh             = mesh;

            List <MapEncounterLayerDataCell> cells = SceneUtils.GetMapEncounterLayerDataCellsWithinCollider(regionGo);

            for (int i = 0; i < cells.Count; i++)
            {
                MapEncounterLayerDataCell cell = cells[i];
                cell.AddRegion(regionGameLogic);
            }
        }
        public override void Trigger(MessageCenterMessage inMessage, string triggeringName)
        {
            Main.LogDebug("[PositionRegion] Positioning Region...");
            GameObject      regionGo    = GameObject.Find(RegionName);
            CombatGameState combatState = UnityGameInstance.BattleTechGame.Combat;
            Team            playerTeam  = combatState.LocalPlayerTeam;

            Vector3       centerOfTeamMass = GetCenterOfTeamMass(playerTeam, true);
            Vector3       possiblePosition = Vector3.zero;
            AbstractActor actor            = combatState.AllActors.First((AbstractActor x) => x.TeamId == playerTeam.GUID);

            while (possiblePosition == Vector3.zero || !PathFinderManager.Instance.IsSpawnValid(regionGo, possiblePosition, actor.GameRep.transform.position, UnitType.Mech, $"PositionRegionResult.{RegionName}"))
            {
                Main.LogDebug($"[PositionRegion] {(possiblePosition == Vector3.zero ? "Finding possible position..." : "Trying again to find a possible position...")}");
                possiblePosition = SceneUtils.GetRandomPositionFromTarget(centerOfTeamMass, Main.Settings.DynamicWithdraw.MinDistanceForZone, Main.Settings.DynamicWithdraw.MaxDistanceForZone);
            }
            regionGo.transform.position = possiblePosition;

            // Debug
            // GameObjextExtensions.CreateDebugPoint("DEBUGCenterofTeamMassGizmo", centerOfTeamMass, Color.red);
            // GameObjextExtensions.CreateDebugPoint("DEBUGDynamicWithdrawCenter", regionGo.transform.position, Color.blue);

            RegionGameLogic regionGameLogic = regionGo.GetComponent <RegionGameLogic>();

            regionGameLogic.Regenerate();
        }
Beispiel #4
0
        public static RegionGameLogic CreateWithdrawRegion(GameObject parent, string regionGameLogicGuid, string objectiveGuid, string name = null)
        {
            GameObject withdrawRegionGo = CreateWithdrawRegionGameObject(parent, name);

            MeshCollider collider = withdrawRegionGo.AddComponent <MeshCollider>();
            MeshFilter   mf       = withdrawRegionGo.AddComponent <MeshFilter>();
            Mesh         mesh     = MeshTools.CreateHexigon(REGION_RADIUS);

            collider.sharedMesh = mesh;
            mf.mesh             = mesh;

            withdrawRegionGo.AddComponent <TerrainDataChangeDetection>();
            withdrawRegionGo.AddComponent <SnapToTerrain>();
            withdrawRegionGo.AddComponent <MeshRenderer>();

            RegionGameLogic regionGameLogic = withdrawRegionGo.AddComponent <RegionGameLogic>();

            regionGameLogic.encounterObjectGuid = regionGameLogicGuid;
            regionGameLogic.radius      = REGION_RADIUS;
            regionGameLogic.regionDefId = "regionDef_EvacZone";
            regionGameLogic.alwaysShowRegionWhenActive = true;

            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint1", new Vector3(0, 0, REGION_RADIUS));                      // North
            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint2", new Vector3(REGION_RADIUS, 0, REGION_RADIUS / 2f));     // North-East
            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint3", new Vector3(REGION_RADIUS, 0, -(REGION_RADIUS / 2f)));  // South-East
            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint4", new Vector3(0, 0, -REGION_RADIUS));                     // South
            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint5", new Vector3(-REGION_RADIUS, 0, -(REGION_RADIUS / 2f))); // South-West
            CreateRegionPointGameObject(withdrawRegionGo, $"RegionPoint6", new Vector3(-REGION_RADIUS, 0, REGION_RADIUS / 2f));    // North-West

            return(regionGameLogic);
        }
Beispiel #5
0
 static void Postfix(RegionGameLogic __instance)
 {
     if (GizmoManager.GetInstance().IsGizmoModeActive&& GizmoManager.GetInstance().IsGizmoRegionModeActive)
     {
         MeshRenderer component = __instance.GetComponent <MeshRenderer>();
         if (component != null)
         {
             component.enabled = true;
         }
     }
 }
    public static void RemoveRegion(this MapEncounterLayerDataCell layerDataCell, RegionGameLogic regionGameLogic)
    {
        if (layerDataCell.regionGuidList == null)
        {
            return;
        }

        if (layerDataCell.regionGuidList.Contains(regionGameLogic.encounterObjectGuid))
        {
            layerDataCell.regionGuidList.Remove(regionGameLogic.encounterObjectGuid);
        }
    }
Beispiel #7
0
    public static void Regenerate(this RegionGameLogic regionGameLogic)
    {
        GameObject      regionGo    = regionGameLogic.gameObject;
        CombatGameState combatState = UnityGameInstance.BattleTechGame.Combat;
        List <Vector3>  meshPoints  = new List <Vector3>();

        // Remove old region location from layer data cells
        List <MapEncounterLayerDataCell> beforeCells = SceneUtils.GetMapEncounterLayerDataCellsWithinCollider(regionGo);

        for (int i = 0; i < beforeCells.Count; i++)
        {
            MapEncounterLayerDataCell cell = beforeCells[i];
            cell.RemoveRegion(regionGameLogic);
        }

        // Get all region points and fix the y height
        foreach (Transform t in regionGo.transform)
        {
            if (t.gameObject.name.StartsWith("RegionPoint"))
            {
                Vector3 position            = t.position;
                float   height              = combatState.MapMetaData.GetLerpedHeightAt(position);
                Vector3 fixedHeightPosition = new Vector3(position.x, height, position.z);
                t.position = fixedHeightPosition;
                meshPoints.Add(t.localPosition);
            }
        }

        // Create new mesh from points and set to collider and mesh filter
        MeshCollider collider = regionGo.GetComponent <MeshCollider>();
        MeshFilter   mf       = regionGo.GetComponent <MeshFilter>();
        Mesh         mesh     = MeshTools.CreateHexigon(regionGameLogic.radius, meshPoints);

        collider.sharedMesh = mesh;
        mf.mesh             = mesh;

        List <MapEncounterLayerDataCell> afterCells = SceneUtils.GetMapEncounterLayerDataCellsWithinCollider(regionGo);

        for (int i = 0; i < afterCells.Count; i++)
        {
            MapEncounterLayerDataCell cell = afterCells[i];
            cell.AddRegion(regionGameLogic);
        }
    }
Beispiel #8
0
        private void TagUnitsInRegion()
        {
            Main.LogDebug($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Tagging '{NumberOfUnits}' '{Type}' in region '{RegionGuid}'");
            RegionGameLogic regionGameLogic = UnityGameInstance.BattleTechGame.Combat.ItemRegistry.GetItemByGUID <RegionGameLogic>(RegionGuid);

            if (regionGameLogic == null)
            {
                Main.Logger.LogError($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Region Not Found for Guid '{RegionGuid}'");
                return;
            }

            if (Type == "Building")
            {
                List <BuildingRepresentation> buildingsInMap = GameObjextExtensions.GetBuildingsInMap();
                Main.LogDebug($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Collected '{buildingsInMap.Count}' buildings to check.");

                if (NumberOfUnits > 0)
                {
                    buildingsInMap.Shuffle();
                }

                foreach (BuildingRepresentation building in buildingsInMap)
                {
                    bool isBuildingInRegion = RegionUtil.PointInRegion(UnityGameInstance.BattleTechGame.Combat, building.transform.position, RegionGuid);
                    if (isBuildingInRegion)
                    {
                        Main.LogDebug($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Found building '{building.gameObject.name}' in region!");
                        building.ParentBuilding.EncounterTags.UnionWith(Tags);

                        SetTeam(building.ParentBuilding);
                        SetIsTargetObjective(building.ParentBuilding);

                        if (HasReachedUnitLimit())
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                Main.LogDebug($"[SetUnitsInRegionToBeTaggedObjectiveTargetsResult] Tagging '{Type}' Not Yet Supported. Use 'TagUnitsInRegion'");
            }
        }
Beispiel #9
0
        public void BuildNormal()
        {
            string regionGuid    = objective["Guid"].ToString();
            string objectiveGuid = objective["ObjectiveGuid"].ToString();
            float  radius        = objective.ContainsKey("Radius") ? (float)objective["Radius"] : (float)0;

            RegionGameLogic regionLogic = RegionFactory.CreateRegion(this.parent, regionGuid, objectiveGuid, this.name, regionDefId, radius);
            GameObject      regionGo    = regionLogic.gameObject;

            if (position != null)
            {
                SetPosition(regionGo, position);
            }
            if (rotation != null)
            {
                SetRotation(regionGo, rotation);
            }

            regionLogic.Regenerate();
        }
Beispiel #10
0
    public static List <MapEncounterLayerDataCell> GetMapEncounterLayerDataCellsWithinCollider(GameObject regionGo)
    {
        MeshCollider    collider               = regionGo.GetComponent <MeshCollider>();
        RegionGameLogic regionGameLogic        = regionGo.GetComponent <RegionGameLogic>();
        List <MapEncounterLayerDataCell> cells = new List <MapEncounterLayerDataCell>();
        Vector3 colliderExtents = collider.bounds.extents;
        Vector3 colliderCenter  = collider.bounds.center;

        EncounterLayerData encounterLayerData = MissionControl.MissionControl.Instance.EncounterLayerData;
        int cellX = encounterLayerData.GetXIndex(colliderCenter.x);
        int cellZ = encounterLayerData.GetZIndex(colliderCenter.z);

        // Add center
        MapEncounterLayerDataCell layerDataCell = GetOrCreateEncounterLayerDataCell(cellX, cellZ);

        cells.Add(layerDataCell);

        float bottom = colliderCenter.x - colliderExtents.x;
        float top    = colliderCenter.x + colliderExtents.x;
        float left   = colliderCenter.z - colliderExtents.z;
        float right  = colliderCenter.z + colliderExtents.z;

        for (float i = bottom; i < top; i += 0.5f)
        {
            for (float j = left; j < right; j += 0.5f)
            {
                cellX = encounterLayerData.GetXIndex(i);
                cellZ = encounterLayerData.GetZIndex(j);

                layerDataCell = GetOrCreateEncounterLayerDataCell(cellX, cellZ);

                if (layerDataCell != null)
                {
                    cells.Add(layerDataCell);
                }
            }
        }

        return(cells);
    }
Beispiel #11
0
    override protected BehaviorTreeResults Tick()
    {
        string regionGUID = RegionUtil.GetStayInsideRegionGUID(unit);

        if (regionGUID == null)
        {
            return(new BehaviorTreeResults(BehaviorNodeState.Failure));
        }

        if (unit.IsInRegion(regionGUID))
        {
            return(new BehaviorTreeResults(BehaviorNodeState.Success));
        }

        ITaggedItem item = unit.Combat.ItemRegistry.GetItemByGUID(regionGUID);

        if (item == null)
        {
            Debug.Log("no item with GUID: " + regionGUID);
            return(new BehaviorTreeResults(BehaviorNodeState.Failure));
        }
        RegionGameLogic region = item as RegionGameLogic;

        if (region == null)
        {
            Debug.Log("item is not region: " + regionGUID);
            return(new BehaviorTreeResults(BehaviorNodeState.Failure));
        }

        // TODO: find a point inside the region, for now using the average of all vertices.
        int numPoints = region.regionPointList.Length;

        Vector3 destination = new Vector3();

        for (int pointIndex = 0; pointIndex < numPoints; ++pointIndex)
        {
            destination += region.regionPointList[pointIndex].Position;
        }
        if (numPoints == 0)
        {
            Debug.Log("no points in region: " + regionGUID);
            return(new BehaviorTreeResults(BehaviorNodeState.Failure));
        }

        destination = RoutingUtil.Decrowd(destination * 1.0f / numPoints, unit);
        destination = RegionUtil.MaybeClipMovementDestinationToStayInsideRegion(unit, destination);

        var cell = unit.Combat.MapMetaData.GetCellAt(destination);

        destination.y = cell.cachedHeight;

        if ((destination - unit.CurrentPosition).magnitude < 1)
        {
            // already close (should probably have been caught, above)
            return(new BehaviorTreeResults(BehaviorNodeState.Success));
        }

        bool shouldSprint = unit.CanSprint;

        //float sprintRange = Mathf.Max(unit.MaxSprintDistance, unit.MaxWalkDistance);
        float moveRange = unit.MaxWalkDistance;

        if ((destination - unit.CurrentPosition).magnitude < moveRange)
        {
            shouldSprint = false;
        }

        if (shouldSprint)
        {
            unit.Pathing.SetSprinting();
        }
        else
        {
            unit.Pathing.SetWalking();
        }

        unit.Pathing.UpdateAIPath(destination, destination, shouldSprint ? MoveType.Sprinting : MoveType.Walking);
        Vector3 destinationThisTurn = unit.Pathing.ResultDestination;

        float        movementBudget = unit.Pathing.MaxCost;
        PathNodeGrid grid           = unit.Pathing.CurrentGrid;
        Vector3      successorPoint = destination;

        var longRangeToShorRangeDistanceThreshold = unit.BehaviorTree.GetBehaviorVariableValue(BehaviorVariableName.Float_LongRangeToShortRangeDistanceThreshold).FloatVal;

        if (grid.GetValidPathNodeAt(destinationThisTurn, movementBudget) == null || (destinationThisTurn - destination).magnitude > longRangeToShorRangeDistanceThreshold)
        {
            List <AbstractActor> lanceUnits = AIUtil.GetLanceUnits(unit.Combat, unit.LanceId);
            List <Vector3>       path       = DynamicLongRangePathfinder.GetDynamicPathToDestination(destination, movementBudget, unit, shouldSprint, lanceUnits, grid, 0);
            if (path == null || path.Count == 0)
            {
                return(new BehaviorTreeResults(BehaviorNodeState.Failure));
            }

            destinationThisTurn = path[path.Count - 1];

            Vector2 flatDestination = new Vector2(destination.x, destination.z);

            float   currentClosestPointInRegionDistance = float.MaxValue;
            Vector3?closestPoint = null;

            for (int i = 0; i < path.Count; ++i)
            {
                Vector3 pointOnPath = path[i];

                if (RegionUtil.PointInRegion(unit.Combat, pointOnPath, regionGUID))
                {
                    var distance = (flatDestination - new Vector2(pointOnPath.x, pointOnPath.z)).sqrMagnitude;

                    if (distance < currentClosestPointInRegionDistance)
                    {
                        currentClosestPointInRegionDistance = distance;
                        closestPoint = pointOnPath;
                    }
                }
            }

            if (closestPoint != null)
            {
                destinationThisTurn = closestPoint.Value;
            }
        }

        Vector3 cur = unit.CurrentPosition;

        AIUtil.LogAI(string.Format("issuing order from [{0} {1} {2}] to [{3} {4} {5}] looking at [{6} {7} {8}]",
                                   cur.x, cur.y, cur.z,
                                   destinationThisTurn.x, destinationThisTurn.y, destinationThisTurn.z,
                                   successorPoint.x, successorPoint.y, successorPoint.z
                                   ));

        BehaviorTreeResults results      = new BehaviorTreeResults(BehaviorNodeState.Success);
        MovementOrderInfo   mvtOrderInfo = new MovementOrderInfo(destinationThisTurn, successorPoint);

        mvtOrderInfo.IsSprinting = shouldSprint;
        results.orderInfo        = mvtOrderInfo;
        results.debugOrderString = string.Format("{0}: dest:{1} sprint:{2}", this.name, destination, mvtOrderInfo.IsSprinting);
        return(results);
    }
        public void GenerateEncounterLayerBuildingData()
        {
            Main.Logger.LogDebug($"[EncounterDataManager.GenerateEncounterLayerBuildingData] Generating building data");
            Terrain terrain            = Terrain.activeTerrain;
            float   terrainZSize       = terrain.terrainData.size.z;
            float   terrainXSize       = terrain.terrainData.size.x;
            Vector3 terrainPosition    = terrain.transform.position;
            float   halfMapCellSize    = (float)MapMetaDataExporter.cellSize / 2f;
            int     halfMapCellSizeInt = MapMetaDataExporter.cellSize / 2;
            EncounterLayerParent encounterLayerParent = MissionControl.Instance.EncounterLayerParent;
            EncounterLayerData   encounterLayerData   = MissionControl.Instance.EncounterLayerData;
            MapMetaDataExporter  mapMetaExporter      = encounterLayerParent.GetComponent <MapMetaDataExporter>();
            MapMetaData          mapMetaData          = UnityGameInstance.BattleTechGame.Combat.MapMetaData;
            Vector3 raycastOrigin = new Vector3(0f, 1000f, 0f);

            // Lookups
            Dictionary <string, int>    regionRaycastHits         = new Dictionary <string, int>();
            List <RegionGameLogic>      regionGameObjectList      = new List <RegionGameLogic>();
            List <ObstructionGameLogic> obstructionGameObjectList = new List <ObstructionGameLogic>();

            // Marks only the ObstructionGameLogic objects for ray tracing for performance reasons
            AccessTools.Method(typeof(MapMetaDataExporter), "MarkCellsForRaycasting").Invoke(mapMetaExporter, new object[] { mapMetaData.mapTerrainDataCells, (int)terrain.transform.position.x, (int)terrain.transform.position.z });

            // TODO: Maybe wipe region building lists. Not sure if I really need/want this yet
            RegionGameLogic[] componentsInChildren = encounterLayerData.GetComponentsInChildren <RegionGameLogic>();
            for (int i = 0; i < componentsInChildren.Length; i++)
            {
                componentsInChildren[i].InitRegionForRayCasting();
            }

            // Iterate over the Z cell range
            for (float i = halfMapCellSize; i < terrainZSize; i += (float)MapMetaDataExporter.cellSize)
            {
                int zCellIndex = (int)i / MapMetaDataExporter.cellSize;

                // Iterate over the X cell range
                for (float j = halfMapCellSize; j < terrainXSize; j += (float)MapMetaDataExporter.cellSize)
                {
                    int xCellIndex = (int)j / MapMetaDataExporter.cellSize;

                    MapEncounterLayerDataCell mapEncounterLayerDataCell = new MapEncounterLayerDataCell();
                    if (mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].doRayCast)
                    {
                        int hitIndex = 0;
                        regionRaycastHits.Clear();
                        regionGameObjectList.Clear();
                        obstructionGameObjectList.Clear();

                        for (int k = -halfMapCellSizeInt; k < halfMapCellSizeInt; k++)
                        {
                            raycastOrigin.z = i + (float)k + terrainPosition.z;

                            for (int l = -halfMapCellSizeInt; l < halfMapCellSizeInt; l++)
                            {
                                raycastOrigin.x = j + (float)l + terrainPosition.x;

                                RaycastHit[] raycastHits          = Physics.RaycastAll(raycastOrigin, Vector3.down);
                                List <ObstructionGameLogic> list3 = new List <ObstructionGameLogic>();

                                // Go through all the raycasts at Z,X of the terrain by cell size (middle of cell)
                                // Then find any regions hit, record the number of hits/cells the region has
                                for (int m = 0; m < raycastHits.Length; m++)
                                {
                                    RegionGameLogic regionGameLogic = raycastHits[m].transform.GetComponent <RegionGameLogic>();
                                    if (regionGameLogic != null)
                                    {
                                        if (!regionRaycastHits.ContainsKey(regionGameLogic.encounterObjectGuid))
                                        {
                                            regionRaycastHits[regionGameLogic.encounterObjectGuid] = 1;
                                        }
                                        else
                                        {
                                            string encounterObjectGuid = regionGameLogic.encounterObjectGuid;
                                            regionRaycastHits[encounterObjectGuid]++;
                                        }

                                        // Cache the region in the lookup
                                        if (!regionGameObjectList.Contains(regionGameLogic))
                                        {
                                            regionGameObjectList.Add(regionGameLogic);
                                        }
                                    }

                                    ObstructionGameLogic obstructionGameLogicInParent = raycastHits[m].transform.GetComponentInParent <ObstructionGameLogic>();
                                    if (obstructionGameLogicInParent != null && raycastHits[m].point.y > mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].terrainHeight)
                                    {
                                        if (obstructionGameLogicInParent.IsBuildingHitAddWorthy)
                                        {
                                            if (!obstructionGameObjectList.Contains(obstructionGameLogicInParent))
                                            {
                                                obstructionGameObjectList.Add(obstructionGameLogicInParent);
                                            }
                                        }

                                        Vector3            normal             = raycastHits[m].normal;
                                        BuildingRaycastHit buildingRaycastHit = new BuildingRaycastHit {
                                            buildingSteepness = 90f - 57.29578f * Mathf.Atan2(normal.y, Mathf.Sqrt(normal.x * normal.x + normal.z * normal.z)),
                                            buildingHeight    = raycastHits[m].point.y,
                                            buildingGuid      = obstructionGameLogicInParent.encounterObjectGuid,
                                            hitIndex          = hitIndex
                                        };
                                        mapEncounterLayerDataCell.AddBuildingHit(buildingRaycastHit);
                                    }
                                }
                                hitIndex++;
                            }
                        }

                        // For all the regions detected, if it exists in 10 or more cells - add the region to the map encounter layer data (this is vanilla... why?!)
                        // And all all obstruction games logics to the region
                        foreach (RegionGameLogic regionGameLogic in regionGameObjectList)
                        {
                            if (regionRaycastHits[regionGameLogic.encounterObjectGuid] >= 10)
                            {
                                mapEncounterLayerDataCell.AddRegion(regionGameLogic);
                                foreach (ObstructionGameLogic obstructionGameLogic in obstructionGameObjectList)
                                {
                                    regionGameLogic.AddBuildingGuidToRegion(obstructionGameLogic.encounterObjectGuid);
                                }
                            }
                        }
                        mapEncounterLayerDataCell.AverageTheBuildingHits();
                        mapEncounterLayerDataCell.SortBuildingListByHeight();
                    }

                    encounterLayerData.mapEncounterLayerDataCells[zCellIndex, xCellIndex] = mapEncounterLayerDataCell;
                    encounterLayerData.mapEncounterLayerDataCells[zCellIndex, xCellIndex].relatedTerrainCell = mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex];
                    mapMetaData.mapTerrainDataCells[zCellIndex, xCellIndex].MapEncounterLayerDataCell        = mapEncounterLayerDataCell;
                }
            }
        }