Beispiel #1
0
    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);
    }
Beispiel #2
0
    /// <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);
    }