/**********************************************************************************/ // функция устанавливает разрушаемый объект окружения в карту позиций // объекты зарегестрированные таким образом не являются для кого либо "классическим" // противником, однако могут попасть под "лихую руку" и быть уничтоженными // /**********************************************************************************/ public void RegistEnvironment(GeneratedEnvironmentCtr ctr) { int registrationId = m_nextEnvironmentKey; m_EnvironmentIdToController[registrationId] = ctr; Point objPosition = ctr.GetGlobalPosition() - new Point(ctr.SIZE / 2, ctr.SIZE / 2); for (int xPos = objPosition.x; xPos < objPosition.x + ctr.SIZE; xPos++) { for (int yPos = objPosition.y; yPos < objPosition.y + ctr.SIZE; yPos++) { int positionKey = GetPositionKey(xPos, yPos); m_EnvironmentToMap[positionKey] = registrationId; } } m_nextEnvironmentKey++; }
/**********************************************************************************/ // функция производит поиск зданий в заданном раудиуса // /**********************************************************************************/ public List <GeneratedEnvironmentCtr> SearchEnvironmentInRadius(Point position, int radius, bool closest = true) { List <GeneratedEnvironmentCtr> envObject = new List <GeneratedEnvironmentCtr>(); List <int> objKeys = new List <int>(); // начинаем поиск объектов от самого ближайшего for (int searchingRadius = 0; searchingRadius <= radius; searchingRadius++) { List <Point> pointsToCheck = m_pointsToSearch[searchingRadius]; foreach (Point point in pointsToCheck) { Point pointToCheck = point + position; // проверяем точку на валидность if (pointToCheck.x < 0 || pointToCheck.x >= m_xMapSize || pointToCheck.y < 0 || pointToCheck.y > m_yMapSize) { continue; // если точка за границей карты - уходим на сл. итерацию } int positionKey = GetPositionKey(pointToCheck.x, pointToCheck.y); if (m_EnvironmentToMap.ContainsKey(positionKey)) { int envKey = m_EnvironmentToMap[positionKey]; if (!objKeys.Contains(envKey)) { objKeys.Add(envKey); GeneratedEnvironmentCtr ctr = m_EnvironmentIdToController[envKey]; envObject.Add(ctr); } } } // если мы ищем ближайшие объекты, в случае нахождения таковых, сразу же возвращаем список найденых // в противном случае продолжаем поиск до максимального радиуса if (closest && envObject.Count > 0) { return(envObject); } } return(envObject); }
/**********************************************************************************/ // функция генерирует наполнитель для блока // вызывается после генерации зданий и дорог, когда ограничители по пространству уже определены // /**********************************************************************************/ void GenerateBlockEnviroment(GameObject block, BlockDescriptor descriptor, BlockSettings settings, int SizeOfBlocks) { int numberOfGeneratedObject = settings.NumOfEnvElements; List <GameObject> applicableObjects = new List <GameObject>(); foreach (GeneratedEnvironmentCtr.ENV_TYPE objType in settings.EnvTypes) { // формирование списка применимых для данного блока элементов foreach (GameObject generatedEnvObj in GeneratedEnvCollection) { // получаем контроллер и проверяем его тип GeneratedEnvironmentCtr ctr = generatedEnvObj.GetComponent <GeneratedEnvironmentCtr>(); if (ctr == null) { Debug.LogError("Wrong GeneratedEnvironmentCtr! is Null!"); return; } if (ctr.TYPE == objType) { applicableObjects.Add(generatedEnvObj); } } } if (applicableObjects.Count == 0) { Debug.LogWarning("We have no enviroment items for: " + settings.EnvTypes.ToString() + "; types"); return; } // выбираем рандомные элементы из получившегося набора и используем их для заполнения блока // обновляем карту пространства for (int itemN = 0; itemN < numberOfGeneratedObject; itemN++) { GameObject envItemToInstance = applicableObjects[Random.Range(0, applicableObjects.Count)]; bool generatingSuccess = false; bool weHaveFreeSpace = true; while (!generatingSuccess && weHaveFreeSpace) { // состовляем коллекцию свободных точек List <Point> freeSpacePoints = new List <Point>(); for (int x = 0; x < SizeOfBlocks; x++) { for (int y = 0; y < SizeOfBlocks; y++) { if (descriptor.FreeSpaceMap[x, y] == true) { freeSpacePoints.Add(new Point(x, y)); } } } // проверяем наличие свободного пространства if (freeSpacePoints.Count == 0) { weHaveFreeSpace = false; continue; } // выбираем случайную точку из свободных и устанавливаем туда элемент окружения Point randomFreePosition = freeSpacePoints[Random.Range(0, freeSpacePoints.Count)]; int xPos = randomFreePosition.x; int yPos = randomFreePosition.y; // правильные координаты будут выставлены несколькими шагами дальше через localPosition GameObject instance = Instantiate(envItemToInstance, new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity) as GameObject; GeneratedEnvironmentCtr gec = instance.GetComponent <GeneratedEnvironmentCtr>(); // устанавливаем в родителя ( TODO: без учёта размера генерируемого элемента) instance.transform.SetParent(block.transform); instance.transform.localPosition = new Vector3(((float)(xPos) + ((float)gec.SIZE) / 2) * SizeOfCell, ((float)(yPos) + ((float)gec.SIZE) / 2) * SizeOfCell, 0.0f); // сохраняем локальные координаты gec.POSITION = new Point(xPos, yPos); // сохраняем ссылку на все сгенерированные элементы окружения descriptor.Enviroment.Add(instance); // обновляем карту свободных клеток в блоке descriptor.UpdateFreeSpaceMap(SizeOfBlocks); generatingSuccess = true; } } }
/**********************************************************************************/ // обрабатываем параметры блока и заполняем карту свободных ячеек // /**********************************************************************************/ public void UpdateFreeSpaceMap(int SizeOfBlock) { m_freeSpaceCounter = SizeOfBlock * SizeOfBlock; int sizeOfObjectMapX = SizeOfBlock * xSize; int sizeOfObjectMapY = SizeOfBlock * ySize; if (FreeSpaceMap == null) { FreeSpaceMap = new bool[sizeOfObjectMapX, sizeOfObjectMapY]; // считаем, что мы имеем всё поле свободным for (int x = 0; x < sizeOfObjectMapX; x++) { for (int y = 0; y < sizeOfObjectMapY; y++) { FreeSpaceMap[x, y] = true; } } } if (FreeWaysMap == null) { FreeWaysMap = new bool[sizeOfObjectMapX, sizeOfObjectMapY]; // считаем, что мы имеем всё поле свободным for (int x = 0; x < sizeOfObjectMapX; x++) { for (int y = 0; y < sizeOfObjectMapY; y++) { FreeWaysMap[x, y] = true; } } } // проверяем соединения блоков if (RoadConnections == null) { Debug.LogError("RoadConnections not initialized!"); return; } // средняя нижняя точка if (RoadConnections[(int)Base.DIREC.DOWN] != ROAD_CONNECTION_STATUS.BLOCKED) { FreeSpaceMap[sizeOfObjectMapX / 2, 0] = false; m_freeSpaceCounter--; } // средняя верхняя точка if (RoadConnections[(int)Base.DIREC.UP] != ROAD_CONNECTION_STATUS.BLOCKED) { FreeSpaceMap[sizeOfObjectMapX / 2, sizeOfObjectMapY - 1] = false; m_freeSpaceCounter--; } // средняя левая точка if (RoadConnections[(int)Base.DIREC.LEFT] != ROAD_CONNECTION_STATUS.BLOCKED) { FreeSpaceMap[0, sizeOfObjectMapY / 2] = false; m_freeSpaceCounter--; } // средняя правая точка if (RoadConnections[(int)Base.DIREC.RIGHT] != ROAD_CONNECTION_STATUS.BLOCKED) { FreeSpaceMap[sizeOfObjectMapX - 1, sizeOfObjectMapY / 2] = false; m_freeSpaceCounter--; } // производим учёт зданий foreach (GameObject building in Buildings) { BuildingController bc = building.GetComponent <BuildingController>(); if (bc == null) { Debug.LogError("BuildingController is null!"); return; } Point buildingPosion = bc.GetLocalPosition(); buildingPosion.x -= bc.XBuildingSize / 2; buildingPosion.y -= bc.YBuildingSize / 2; for (int xFreeMap = buildingPosion.x; xFreeMap < buildingPosion.x + bc.XBuildingSize; xFreeMap++) { for (int yFreeMap = buildingPosion.y; yFreeMap < buildingPosion.y + bc.YBuildingSize; yFreeMap++) { FreeSpaceMap[xFreeMap, yFreeMap] = false; FreeWaysMap[xFreeMap, yFreeMap] = false; m_freeSpaceCounter--; } } Point roadPoint = new Point(buildingPosion) + bc.RoadPoint; FreeSpaceMap[roadPoint.x, roadPoint.y] = false; m_freeSpaceCounter--; } // производим учёт сгенерированного окружения foreach (GameObject envObj in Enviroment) { GeneratedEnvironmentCtr gec = envObj.GetComponent <GeneratedEnvironmentCtr>(); if (gec == null) { Debug.LogError("BuildingController is null!"); return; } Point gePosion = gec.POSITION; gePosion.x -= gec.SIZE / 2; gePosion.y -= gec.SIZE / 2; for (int xFreeMap = gePosion.x; xFreeMap < gePosion.x + gec.SIZE; xFreeMap++) { for (int yFreeMap = gePosion.y; yFreeMap < gePosion.y + gec.SIZE; yFreeMap++) { FreeSpaceMap[xFreeMap, yFreeMap] = false; FreeWaysMap[xFreeMap, yFreeMap] = gec.FREE_WALKING; m_freeSpaceCounter--; } } } }