public bool IsAreaFree(int x, int z, int width, int height, Tile ignoreTile = null) { if (x < 0 || z < 0) { return(false); } if (GameGenerator != null) { Vec2i baseChunk = BaseChunk + new Vec2i(Mathf.FloorToInt((float)x / World.ChunkSize), Mathf.FloorToInt((float)z / World.ChunkSize)); Vec2i cBase = World.GetChunkPosition(this.BaseTile + new Vec2i(x, z)) - new Vec2i(2, 2); int chunkWidth = Mathf.FloorToInt((float)width / World.ChunkSize) + 1; int chunkHeight = Mathf.FloorToInt((float)height / World.ChunkSize) + 1; for (int cx = 0; cx < chunkWidth; cx++) { for (int cz = 0; cz < chunkHeight; cz++) { int cbx = baseChunk.x + cx; int cbz = baseChunk.z + cz; if (cbx < 0 || cbx > World.WorldSize - 1 || cbz < 0 || cbz > World.WorldSize - 1) { return(false); } ChunkBase cb = GameGenerator.TerrainGenerator.ChunkBases[cbx, cbz]; if (cb.RiverNode != null) { cb.RiverNode.AddBridge(new RiverBridge()); return(false); } if (cb.RiverNode != null || cb.Lake != null || !cb.IsLand) { return(false); } } } } Recti rect = new Recti(x, z, width, height); foreach (Recti r in BuildingPlots) { if (rect.Intersects(r)) { return(false); } } for (int x_ = x; x_ < x + width; x_++) { for (int z_ = z; z_ < z + height; z_++) { if (z_ >= TileSize - 1 || x_ >= TileSize - 1) { return(false); } int cx = WorldToChunk(x_); int cz = WorldToChunk(z_); int baseIgnore = Tile.NULL.ID; if (ChunkBases != null && ChunkBases[cx, cz] != null) { baseIgnore = Tile.GetFromBiome(ChunkBases[cx, cz].Biome).ID; } if (ignoreTile != null) { if (GetTile(x_, z_) != 0 && GetTile(x_, z_) != ignoreTile.ID && GetTile(x_, z_) != baseIgnore) { return(false); } } else if (GetTile(x_, z_) != 0 && GetTile(x_, z_) != baseIgnore) { return(false); } } } return(true); }
/// <summary> /// Adds the building to the settlement /// </summary> /// <param name="b"></param> /// <param name="vox"></param> /// <param name="pos"></param> /// <returns></returns> public Recti AddBuilding(Building b, BuildingVoxels vox, Vec2i pos) { if (!IsAreaFree(pos.x, pos.z, b.Width, b.Height)) { return(null); } int nodeX = Mathf.FloorToInt(((float)pos.x) / NodeSize); int nodeZ = Mathf.FloorToInt(((float)pos.z) / NodeSize); int nodeWidth = Mathf.CeilToInt(((float)b.Width) / NodeSize); int nodeHeight = Mathf.CeilToInt(((float)b.Height) / NodeSize); for (int x = nodeX; x < nodeX + nodeWidth; x++) { for (int z = nodeZ; z < nodeZ + nodeHeight; z++) { BuildingMap[x, z] = true; } } Recti bo = new Recti(pos.x - 1, pos.z - 1, b.Width + 2, b.Height + 2); foreach (Recti bound in BuildingPlots) { if (bo.Intersects(bound)) { return(null); } } int height = (int)Mathf.FloorToInt(FlattenArea(pos.x - 1, pos.z - 1, b.Width + 2, b.Height + 2)); BuildingPlots.Add(bo); //Debug.Log("Adding building " + b); //SetTiles(pos.x, pos.z, b.Width, b.Height, b.BuildingTiles); for (int x = 0; x < b.Width; x++) { for (int z = 0; z < b.Height; z++) { SetTile(x + pos.x, z + pos.z, b.BuildingTiles[x, z]); //SetHeight(x + pos.x, z + pos.z, maxHeight); for (int y = 0; y < vox.Height; y++) { SetVoxelNode(x + pos.x, height + y, z + pos.z, vox.GetVoxelNode(x, y, z)); } } } foreach (WorldObjectData obj in b.GetBuildingExternalObjects()) { //We must set the object to have coordinates based on the settlement, //such that the object is added to the correct chunk. obj.SetPosition(obj.Position + pos.AsVector3()); //We (should) already have checked for object validity when creating the building AddObject(obj, true); } Vec2i wPos = pos + BaseTile; Vec2i cPos = World.GetChunkPosition(wPos); //Debug.Log("Calculating tiles!!!"); b.SetPositions(BaseTile, pos); //if (b.BuildingSubworld != null) // AddObject(b.ExternalEntranceObject as WorldObjectData, true); // World.Instance.AddSubworld(b.BuildingSubworld); b.CalculateSpawnableTiles(vox); Buildings.Add(b); //PathNodes.Add(b.Entrance); return(bo); }