private static void PlaceOutsideObjects(GenerationRandom genRan, Blacksmith smith, BuildingVoxels vox, Vec2i outMin, Vec2i outMax)
    {
        List <WorldObjectData> toPlace = new List <WorldObjectData>(new WorldObjectData[] { new Anvil(), new Anvil() });
        bool isFinished = false;

        while (!isFinished)
        {
            WorldObjectData toPlaceCur = toPlace[0];
            toPlace.RemoveAt(0);
            Vector3 pos = genRan.RandomVector3(outMin.x, outMax.x, 0, 0, outMin.z, outMax.z);
            toPlaceCur.SetPosition(pos);
            while (!BuildingGenerator.AddObject(smith, vox, toPlaceCur))
            {
                pos = genRan.RandomVector3(outMin.x, outMax.x, 0, 0, outMin.z, outMax.z);
                toPlaceCur.SetPosition(pos);
            }
            if (toPlace.Count == 0)
            {
                isFinished = true;
            }
        }
    }
Exemple #2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="genRan">The RNG used for this building</param>
    /// <param name="obj">The object to place in the building</param>
    /// <param name="height">The height above the ground the object should sit</param>
    /// <param name="vox">The voxel data of this building. Only required if 'requireWallBacking' is true</param>
    /// <param name="build">The building to place the object in</param>
    /// <param name="distFromWall">The distance from a wall the object should be placed</param>
    /// <param name="wallIndex">Defines the wall we should attempt to place this object on. The 'i'th wall defines the wall
    /// connecting build.BoundingWall[i] -> build.BoundingWall[i+1]. If left as default value (-1), an index will be randomly generated</param>
    /// <param name="requireWallBacking">If true, then we will search for a point on the wall that is backed against a wall.
    /// Used to stop certain objects being placed in front of windows</param>
    /// <param name="forcePlace">If true, then we do not check for intersection with other objects in the building</param>
    /// <param name="attemptsCount">The number of attempts made to place the object on this wall</param>
    /// <returns>True if object is placed sucesfully, false otherwise</returns>
    public static bool PlaceObjectAgainstWall(GenerationRandom genRan, WorldObjectData obj, float height,
                                              BuildingVoxels vox, Building build, float distFromWall = 0, bool requireWallBacking = false, int distToEntr = 2,
                                              bool forcePlace = false, int attemptsCount = 5)
    {
        if (build.InsideWallPoints == null)
        {
            build.InsideWallPoints = FindInsideWallBoundryPoints(vox, build);
        }

        //Check attempts count
        attemptsCount--;
        if (attemptsCount == 0)
        {
            return(false);
        }

        float wallDisp = genRan.Random();
        //Define the position as the start pos + lambda*dir
        //Select a random position from all wall points
        Vec2i pos = genRan.RandomFromArray(build.InsideWallPoints);

        //If too close to entrance, try another placement
        if (build.Entrance != null && pos.QuickDistance(build.Entrance) < distToEntr * distToEntr)
        {
            return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
        }
        //If the object is too close to any of the corners, try again
        foreach (Vec2i v in build.BoundingWall)
        {
            if (v.QuickDistance(pos) < 2)
            {
                return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
            }
        }

        Vec2i faceDirection = GetWallPointDirection(build, pos);

        //If we require a backing wall, we check the position
        if (requireWallBacking)
        {
            Vec2i wPos = pos - faceDirection;
            for (int y = 0; y < 4; y++)
            {
                VoxelNode vn = vox.GetVoxelNode(wPos.x, y, wPos.z);
                //If there is no node (nothing set) then this position is not valid
                if (!vn.IsNode)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
                if (vn.Voxel == Voxel.glass || vn.Voxel == Voxel.none)
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }
        Vector3 finPos   = pos.AsVector3() + faceDirection.AsVector3() * distFromWall + Vector3.up * height;
        float   rotation = Vec2i.Angle(Vec2i.Forward, faceDirection);

        obj.SetPosition(finPos).SetRotation(rotation);
        if (!forcePlace)
        {
            foreach (WorldObjectData obj_ in build.GetBuildingExternalObjects())
            {
                if (obj.Intersects(obj_))
                {
                    return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount));
                }
            }
        }


        //obj.SetPosition(finPos);
        build.AddInternalObject(obj);
        return(true);
    }
Exemple #3
0
    public void SetChunkData(ChunkData chunk, ChunkData[] neighbors, bool forceLoad = false)
    {
        Debug.BeginDeepProfile("set_data");
        //Debug.BeginProfile("set_data");
        Chunk = chunk;
        transform.position = new Vector3(Chunk.X * World.ChunkSize, 0, Chunk.Z * World.ChunkSize);
        LoadedWorldObjects = new WorldObject[World.ChunkSize, World.ChunkSize];

        Debug.BeginDeepProfile("chunk_create_mesh");
        int            waterDepth = -5;
        List <Vector3> verticies  = new List <Vector3>();
        List <int>     triangles  = new List <int>();
        List <Color>   colours    = new List <Color>();
        List <Vector3> normals    = new List <Vector3>();
        int            tri        = 0;
        bool           hasWater   = false;

        ///Iterate every point in chunk, define terrain mesh based on tiles.
        #region mesh_gen
        for (int z = 0; z < World.ChunkSize; z++)
        {
            for (int x = 0; x < World.ChunkSize; x++)
            {
                normals.Add(Vector3.up);
                normals.Add(Vector3.up);
                normals.Add(Vector3.up);
                normals.Add(Vector3.up);
                Tile  t = Chunk.GetTile(x, z);
                Color c = t == null?Tile.GRASS.GetColor() : t.GetColor();

                int y = 0;
                //Check if this tile is water, if so then height=-1
                if (t == Tile.WATER)
                {
                    hasWater = true;
                    y        = waterDepth;
                }


                verticies.Add(new Vector3(x, y, z));
                colours.Add(c);
                //If we are within non-extremes of chunk
                if (x < World.ChunkSize - 1 && z < World.ChunkSize - 1)
                {
                    verticies.Add(new Vector3(x, chunk.GetTile(x, z + 1) == Tile.WATER? waterDepth : 0, z + 1));
                    colours.Add(chunk.GetTile(x, z + 1).GetColor());

                    verticies.Add(new Vector3(x + 1, chunk.GetTile(x + 1, z + 1) == Tile.WATER ? waterDepth : 0, z + 1));
                    colours.Add(chunk.GetTile(x + 1, z + 1).GetColor());

                    verticies.Add(new Vector3(x + 1, chunk.GetTile(x + 1, z) == Tile.WATER ? waterDepth : 0, z));
                    colours.Add(chunk.GetTile(x + 1, z).GetColor());
                }
                else
                {
                    //We are at an extreme
                    //Check x extreme, if we are not in x extreme then this must be Z extreme
                    if (x < World.ChunkSize - 1)
                    {
                        //Z EXTREME

                        Tile t1 = neighbors[0] != null ? neighbors[0].GetTile(x, 0) : null;
                        Tile t2 = neighbors[0] != null ? neighbors[0].GetTile(x + 1, 0) : null;
                        Tile t3 = chunk.GetTile(x + 1, z);
                        if (t1 == null)
                        {
                            verticies.Add(new Vector3(x, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t1 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x, 0, z + 1));
                            }

                            colours.Add(t1.GetColor());
                        }

                        if (t2 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t2 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z + 1));
                            }

                            colours.Add(t2.GetColor());
                        }
                        if (t3 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t3 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z));
                            }

                            colours.Add(t3.GetColor());
                        }
                    }
                    else if (z < World.ChunkSize - 1)
                    {
                        //X EXTREME
                        Tile t1 = chunk.GetTile(x, z + 1);
                        Tile t2 = neighbors[2] != null ? neighbors[2].GetTile(0, z + 1) : null;
                        Tile t3 = neighbors[2] != null ? neighbors[2].GetTile(0, z) : null;
                        if (t1 == null)
                        {
                            verticies.Add(new Vector3(x, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t1 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x, 0, z + 1));
                            }

                            colours.Add(t1.GetColor());
                            //colours.Add(Color.red);
                        }

                        if (t2 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t2 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z + 1));
                            }
                            //colours.Add(Color.magenta);
                            colours.Add(t2.GetColor());
                            //colours.Add(Color.yellow);
                        }
                        if (t3 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t3 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z));
                            }

                            colours.Add(t3.GetColor());
                        }
                    }
                    else
                    {
                        //BOTH EXTREME
                        Tile t1 = neighbors[0] != null ? neighbors[0].GetTile(x, 0) : null;
                        Tile t2 = neighbors[1] != null ? neighbors[1].GetTile(0, 0) : null;
                        Tile t3 = neighbors[2] != null ? neighbors[2].GetTile(0, z) : null;
                        if (t1 == null)
                        {
                            verticies.Add(new Vector3(x, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t1 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x, 0, z + 1));
                            }

                            colours.Add(t1.GetColor());
                        }

                        if (t2 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z + 1));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t2 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z + 1));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z + 1));
                            }

                            colours.Add(t2.GetColor());
                        }
                        if (t3 == null)
                        {
                            verticies.Add(new Vector3(x + 1, y, z));
                            colours.Add(c);
                        }
                        else
                        {
                            if (t3 == Tile.WATER)
                            {
                                verticies.Add(new Vector3(x + 1, waterDepth, z));
                            }
                            else
                            {
                                verticies.Add(new Vector3(x + 1, 0, z));
                            }

                            colours.Add(t3.GetColor());
                        }
                    }
                }


                triangles.Add(tri);
                triangles.Add(tri + 1);
                triangles.Add(tri + 2);
                triangles.Add(tri);
                triangles.Add(tri + 2);
                triangles.Add(tri + 3);
                tri += 4;
            }
        }

        if (!hasWater)
        {
            foreach (Vector3 v in verticies)
            {
                if (v.y != 0)
                {
                    hasWater = true;
                    break;
                }
            }
        }
        Debug.EndDeepProfile("chunk_create_mesh");
        Debug.BeginDeepProfile("chunk_set_mesh");
        MeshFilter meshFilt = GetComponent <MeshFilter>();

        meshFilt.mesh           = new Mesh();
        meshFilt.mesh.vertices  = verticies.ToArray();
        meshFilt.mesh.triangles = triangles.ToArray();
        meshFilt.mesh.colors    = colours.ToArray();
        meshFilt.mesh.normals   = normals.ToArray();
        GetComponent <MeshRenderer>().shadowCastingMode   = UnityEngine.Rendering.ShadowCastingMode.Off;
        gameObject.GetComponent <MeshRenderer>().material = ResourceManager.GetMaterial("Chunk");
        #endregion

        Vector3[] colVerts = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 0, World.ChunkSize),
                                             new Vector3(World.ChunkSize, 0, World.ChunkSize), new Vector3(World.ChunkSize, 0, 0) };
        int[] colTris = new int[] { 0, 1, 2, 0, 2, 3 };
        Mesh  colMesh = GetComponent <MeshCollider>().sharedMesh = new Mesh();

        if (hasWater)
        {
            colMesh.vertices  = GetComponent <MeshFilter>().mesh.vertices;
            colMesh.triangles = GetComponent <MeshFilter>().mesh.triangles;
        }
        else
        {
            colMesh.vertices  = colVerts;
            colMesh.triangles = colTris;
        }
        this.name = this.name + chunk.DEBUG;
        Debug.EndDeepProfile("chunk_set_mesh");

        Vec2i chunkWorldPos = new Vec2i(chunk.X, chunk.Z) * World.ChunkSize;
        if (Chunk.Objects == null)
        {
            Debug.EndDeepProfile("set_data");
            return;
        }

        Debug.BeginDeepProfile("chunk_set_obj");
        for (int x = 0; x < World.ChunkSize; x++)
        {
            for (int z = 0; z < World.ChunkSize; z++)
            {
                WorldObjectData wObj = Chunk.GetObject(x, z);
                if (wObj != null)
                {
                    wObj.SetPosition(new Vec2i(chunk.X * World.ChunkSize + x, chunk.Z * World.ChunkSize + z));
                    //Debug.BeginDeepProfile("CreateWorldObj");
                    //objs.Add(wObj);
                    WorldObject loaded = wObj.CreateWorldObject(transform);
                    LoadedWorldObjects[x, z] = loaded;
                }
            }
        }
        Debug.EndDeepProfile("chunk_set_obj");
        Debug.EndDeepProfile("set_data");

        //Debug.EndProfile();
    }