예제 #1
0
    private Color GetColorFromChunkBase(ChunkBase cb)
    {
        Color c = Color.magenta;

        switch (cb.Biome)
        {
        case ChunkBiome.ocean:
            c = new Color(0, 0, 1);
            break;

        case ChunkBiome.grassland:
            c = new Color(0, 1, 0);
            break;

        case ChunkBiome.dessert:
            c = new Color(1, 1, 0);
            break;

        case ChunkBiome.forrest:
            c = new Color(34f / 255f, 139f / 255f, 34f / 255f);
            break;
        }

        if (cb.RiverNode != null)
        {
            c = new Color(0, 191f / 255f, 1f);
        }
        if (cb.Lake != null)
        {
            c = new Color(0, 0.2f, 1f);
        }
        return(c);
    }
예제 #2
0
        /// <summary>
        /// 解析*.3ds文件。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_3dsFilename"></param>
        /// <returns></returns>
        public MainChunk Parse(string _3dsFilename)
        {
            var base_dir = new FileInfo(_3dsFilename).DirectoryName;// +"/";
            var file     = new FileStream(_3dsFilename, FileMode.Open, FileAccess.Read);
            var reader   = new BinaryReader(file);

            reader.BaseStream.Seek(0, SeekOrigin.Begin);

            var context = new ParsingContext()
            {
                base_dir = base_dir, file = file, reader = reader,
            };

            ChunkBase chunk = reader.ReadChunk();

            if (chunk.GetType() != typeof(MainChunk))
            {
                throw new Exception("Not a proper 3DS file.");
            }

            chunk.Process(context);

            context.Dispose();

            return(chunk as MainChunk);
        }
예제 #3
0
    public Vec2i FindSpace(Kingdom kingdom, int size)
    {
        int attempts = 0;

        while (attempts < 20)
        {
            Vec2i v = null;
            if (kingdom == null)
            {
                v = GenerationRandom.RandomFromList(GameGenerator.TerrainGenerator.LandChunks);
            }
            else
            {
                v = GenerationRandom.RandomFromList(KingdomChunks[kingdom]);
            }
            bool canDo = true;
            //Check point allows settlement within bounds
            if (v.x - size < 0 || v.x + size > World.WorldSize - 1 || v.z - size < 0 || v.z + size > World.WorldSize - 1)
            {
                canDo = false;
            }
            else
            {
                for (int x = -size; x <= size; x++)
                {
                    for (int z = -size; z <= size; z++)
                    {
                        int       cx = x + v.x;
                        int       cz = z + v.z;
                        ChunkBase cb = TerrainGenerator.ChunkBases[cx, cz];
                        if (cb.Kingdom != kingdom || cb.HasSettlement || !cb.IsLand)
                        {
                            canDo = false;
                        }
                        else if (cb.RiverNode != null || cb.Lake != null)
                        {
                            canDo = false;
                        }

                        /*
                         * else if (TerrainGenerator.ChunkBases[Mathf.Clamp(x + v.x, 0, World.WorldSize - 1), Mathf.Clamp(z + v.z, 0, World.WorldSize - 1)].Kingdom != kingdom)
                         *  canDo = false;
                         * else if (TerrainGenerator.ChunkBases[Mathf.Clamp(x + v.x, 0, World.WorldSize - 1), Mathf.Clamp(z + v.z, 0, World.WorldSize - 1)].Settlement != null)
                         *  canDo = false;
                         * else if (!TerrainGenerator.ChunkBases[Mathf.Clamp(x + v.x, 0, World.WorldSize - 1), Mathf.Clamp(z + v.z, 0, World.WorldSize - 1)].IsLand)
                         *  canDo = false;
                         */
                    }
                }
            }
            if (canDo)
            {
                return(v);
            }
            attempts++;
        }

        return(null);
    }
예제 #4
0
        private async Task Incoming(HttpListenerContext context)
        {
            try
            {
                _tracingHttpServerSource.TraceEvent(TraceEventType.Verbose, TRACEEVENT_RECEIVED);
                Interlocked.Increment(ref _requestCount);

                HttpClientImpl client = new HttpClientImpl(context)
                {
                    StartTicks = _timer.ElapsedTicks
                };

                var currentActive = Interlocked.Increment(ref _activeCount);
                var maxActive     = Interlocked.Read(ref _maxActive);
                maxActive = Math.Max(currentActive, maxActive);
                Interlocked.Exchange(ref _maxActive, maxActive); // it is possible to overwrite a higher value on a different thread but it's good enough

                byte[] buffer = new byte[1024];
                int    read   = 0;

                ChunkBase root = null;

                if (Path.GetExtension(context.Request.RawUrl) == "")
                {
                    client.Context.Response.ContentType = "application/json";
                    root = new RESTChunk(this);
                }
                else if (context.Request.RawUrl.EndsWith(".page"))
                {
                    client.Context.Response.ContentType = "text/html";
                    root = new PageChunk(this, null);
                }
                else
                {
                    client.Context.Response.ContentType = "application/octet";
                    root = new FileChunk(this);
                }

                await root.Send(client, null);

                client.StopTicks = _timer.ElapsedTicks;

                Interlocked.Add(ref _tickCount, client.TimetoLastByte);
            }
            catch (Exception ex)
            {
                _tracingHttpServerSource.TraceData(TraceEventType.Error, TRACEEVENT_ERROR, ex);
            }
            finally
            {
                Interlocked.Increment(ref _requestCompleteCount);
                Interlocked.Decrement(ref _activeCount);
            }
        }
예제 #5
0
    /// <summary>
    /// Generates a simple texture representing the terrain defined by the
    /// ChunkBase array.
    /// This Texture is then stored in GameManager.Game.toDrawTexts[3]
    /// </summary>
    /// <param name="cbs">The chunk bases the generated map will be based on</param>
    private void GenerateTerrainMap(ChunkBase[,] cbs)
    {
        Texture2D terMap = new Texture2D(World.WorldSize, World.WorldSize);

        for (int x = 0; x < World.WorldSize; x++)
        {
            for (int z = 0; z < World.WorldSize; z++)
            {
                ChunkBase cb = cbs[x, z];
                Color     c  = Color.black;
                switch (cb.Biome)
                {
                case ChunkBiome.ocean:
                    c = new Color(0, 0, 1);
                    break;

                case ChunkBiome.grassland:
                    c = new Color(0, 1, 0);
                    break;

                case ChunkBiome.dessert:
                    c = new Color(1, 1, 0);
                    break;

                case ChunkBiome.forrest:
                    c = new Color(34f / 255f, 139f / 255f, 34f / 255f);
                    break;
                }

                if (cb.RiverNode != null)
                {
                    c = new Color(0, 191f / 255f, 1f);
                }
                if (cb.Lake != null)
                {
                    c = new Color(0, 0.2f, 1f);
                }
                if (cb.ChunkStructure != null)
                {
                    c = Color.magenta;
                    //Debug.Log("chunk struct at " + x + "_" + z);
                }

                terMap.SetPixel(x, z, c);
            }
        }
        terMap.Apply();
        GameManager.Game.toDrawTexts[3] = terMap;
    }
예제 #6
0
        public ChunkBase NextChunk(Vault vault)
        {
            var header = new ChunkBlockHeader();

            header.Read(vault, Reader);
            ChunkBase chunk = null;

            switch (header.ID)
            {
            case 0x53747245:
                chunk = new BinStringsChunk();
                break;

            case 0x5374724E:
                chunk = new VltStartChunk();
                break;

            case 0x456E6443:
                chunk = new EndChunk();
                break;

            case 0x56657273:
                chunk = new VltVersionChunk();
                break;

            case 0x4465704E:
                chunk = new VltDependencyChunk();
                break;

            case 0x4578704E:
                chunk = new VltExportChunk();
                break;

            case 0x5074724E:
                chunk = new VltPointersChunk();
                break;

            default:
                chunk = new GenericChunk(header.ID);
                break;
            }

            chunk.Offset = header.Offset;
            chunk.Size   = header.Size + 8;

            return(chunk);
        }
예제 #7
0
        /// <summary>
        ///     Writes a chunk to the data stream.
        /// </summary>
        /// <param name="chunk">The chunk to write.</param>
        public void WriteChunk(ChunkBase chunk)
        {
            var beginPos = Writer.BaseStream.Position;

            Writer.Write(chunk.Id);
            var sizePos = Writer.BaseStream.Position;

            Writer.Write(0);

            chunk.Write(Vault, Writer);

            var endPos = Writer.BaseStream.Position;

            Writer.BaseStream.Position = sizePos;
            Writer.Write((uint)(endPos - beginPos));
            Writer.BaseStream.Position = endPos;
        }
예제 #8
0
 public void SpawnChunkEntities(ChunkBase cb)
 {
     if (cb.ChunkStructure != null)
     {
         ChunkStructure cStruct  = cb.ChunkStructure;
         Vec2i          localPos = cb.Position - cStruct.Position;
         List <Entity>  toSpawn  = cStruct.StructureEntities[localPos.x, localPos.z];
         if (toSpawn == null)
         {
             return;
         }
         foreach (Entity e in toSpawn)
         {
             e.CombatManager.Reset();
             Manager.LoadEntity(e);
         }
     }
 }
예제 #9
0
    public Dictionary <Vec2i, ChunkData> GenerateAllSettlementChunks(SettlementBuilder setBuild, Settlement set)
    {
        Vec2i baseChunk = new Vec2i(setBuild.BaseCoord.x / World.ChunkSize, setBuild.BaseCoord.z / World.ChunkSize);
        Dictionary <Vec2i, ChunkData> setChunks = new Dictionary <Vec2i, ChunkData>();
        int setSizeChunks = setBuild.TileSize / World.ChunkSize;

        for (int x = 0; x < setSizeChunks; x++)
        {
            for (int z = 0; z < setSizeChunks; z++)
            {
                ChunkBase cb = GameGenerator.TerrainGenerator.ChunkBases[baseChunk.x + x, baseChunk.z + z];
                ChunkData cd = null;
                if (cb.RiverNode != null || cb.Lake != null)
                {
                    cd = GameGenerator.ChunkGenerator.GenerateChunk(baseChunk.x + x, baseChunk.z + z);
                }
                else
                {
                    int[,] cTiles = new int[World.ChunkSize, World.ChunkSize];
                    Dictionary <int, WorldObjectData> cObj = new Dictionary <int, WorldObjectData>();
                    for (int x_ = 0; x_ < World.ChunkSize; x_++)
                    {
                        for (int z_ = 0; z_ < World.ChunkSize; z_++)
                        {
                            Tile st = setBuild.Tiles[x * World.ChunkSize + x_, z *World.ChunkSize + z_];
                            cTiles[x_, z_] = st == null ? Tile.GRASS.ID : st.ID;
                            cObj[WorldObject.ObjectPositionHash(x_, z_)] = setBuild.SettlementObjects[x * World.ChunkSize + x_, z *World.ChunkSize + z_];
                            if (setBuild.SettlementObjects[x * World.ChunkSize + x_, z *World.ChunkSize + z_] != null)
                            {
                                setBuild.SettlementObjects[x * World.ChunkSize + x_, z *World.ChunkSize + z_].SetPosition(new Vec2i(baseChunk.x + x + x_, baseChunk.z + z + z_));
                            }
                        }
                    }
                    cd = new ChunkData(baseChunk.x + x, baseChunk.z + z, cTiles, true, cObj);
                }


                cd.SetSettlement(set);
                setChunks.Add(new Vec2i(cd.X, cd.Z), cd);
            }
        }
        set.AfterApplyToWorld();
        return(setChunks);
    }
예제 #10
0
    /// <summary>
    /// Generates the chunk based on its biome, as well as things added to it such as forrests and wooded areas
    /// </summary>
    /// <param name="x"></param>
    /// <param name="z"></param>
    /// <returns></returns>
    public ChunkData GenerateChunk(int x, int z)
    {
        ChunkBase cb = ChunkBases[x, z];
        ChunkData cd = null;

        if (cb.Lake != null)
        {
            cd = GenerateLakeChunk(x, z, cb);
        }
        else if (cb.RiverNode != null)
        {
            cd = GenerateRiverChunk(x, z, cb);
        }
        else
        {
            cd = GenerateSimpleChunk(x, z, cb);
        }
        return(cd);
    }
예제 #11
0
        private ChunkBase BuildSimpleTree(ChunkBase chunk)
        {
            var newChunk = ((ICloneable)chunk).Clone() as ChunkBase;

            newChunk.Parent   = null;
            newChunk.Children = new List <ChunkBase>();

            foreach (var item in chunk.Children)
            {
                if (item.GetType() != typeof(UndefinedChunk))
                {
                    var newItem = BuildSimpleTree(item);
                    newItem.Parent = newChunk;
                    newChunk.Children.Add(newItem);
                }
            }

            return(newChunk);
        }
예제 #12
0
        private TreeNode BuildTreeNode(ChunkBase chunk)
        {
            TreeNode node = new TreeNode(chunk.ToString());

            node.Tag         = chunk;
            node.ToolTipText = chunk.ToString();
            if (chunk.Length != chunk.BytesRead)
            {
                node.BackColor = Color.Red;
            }

            foreach (var item in chunk.Children)
            {
                var itemNode = BuildTreeNode(item);
                node.Nodes.Add(itemNode);
            }

            return(node);
        }
예제 #13
0
    public void LoadChunk(ChunkBase cb, Vec2i v)
    {
        //Debug.Log("Loading chunk with entities");
        LoadedChunks.Add(v);
        //Debug.Log("Loading entities from chunk " + v);
        if (FixedEntities.ContainsKey(v))
        {
            List <int> toLoad = FixedEntities[v];
            Debug.Log("Loading " + toLoad.Count + " entities from " + v, Debug.ENTITY);
            //Debug.Log(toLoad.Count);
            foreach (int e in toLoad)
            {
                LoadEntity(GetEntityFromID(e));
            }

            FixedEntities[v].Clear();
        }
        if (cb != null)
        {
            EntitySpawner.SpawnChunkEntities(cb);
        }
    }
 ///Contains function to check if positions are valid
 #region misc
 /// <summary>
 /// Takes a position and size, checks against terrain values to see if
 /// the position is free to place the desired structure on
 /// </summary>
 /// <param name="position"></param>
 /// <returns></returns>
 private bool IsPositionValid(Vec2i position, int clear = 5)
 {
     for (int x = -clear; x <= clear; x++)
     {
         for (int z = -clear; z <= clear; z++)
         {
             int cx = position.x + x;
             int cz = position.z + z;
             //Debug.Log(cx + "_" + cz);
             if (cx < 0 || cz < 0 || cx >= World.WorldSize - 1 || cz >= World.WorldSize - 1)
             {
                 return(false);
             }
             ChunkBase cb = GameGenerator.TerrainGenerator.ChunkBases[cx, cz];
             if (cb.HasSettlement || cb.RiverNode != null || cb.Lake != null || cb.ChunkStructure != null)
             {
                 //Debug.Log(cb.HasSettlement + "_" + cb.RiverNode + "_" + cb.Lake + "_" + cb.ChunkStructure);
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #15
0
    /// <summary>
    /// Generates a chunk that has no special land features
    /// </summary>
    /// <param name="x"></param>
    /// <param name="z"></param>
    /// <param name="cb"></param>
    /// <returns></returns>
    private ChunkData GenerateSimpleChunk(int x, int z, ChunkBase cb)
    {
        if (!cb.IsLand)
        {
            return(new ChunkData(x, z, (int[, ])OCEAN.Clone(), cb.IsLand));
        }
        if (cb.Biome == ChunkBiome.dessert)
        {
            return(new ChunkData(x, z, (int[, ])EMPTY_DESERT.Clone(), cb.IsLand));
        }
        int[,] tiles = (int[, ])EMPTY_PLAINS.Clone();

        GenerationRandom genRan = new GenerationRandom(Seed + x << 16 + z);

        //if(genRan.Random() > 0.1f)
        //    return new ChunkData(x, z, tiles, cb.IsLand);

        Dictionary <int, WorldObjectData> obs = new Dictionary <int, WorldObjectData>(256);

        for (int i = 0; i < World.ChunkSize; i++)
        {
            for (int j = 0; j < World.ChunkSize; j++)
            {
                if (genRan.Random() < 0.01f)
                {
                    obs.Add(WorldObject.ObjectPositionHash(i, j), new Tree(new Vec2i(x * World.ChunkSize + i, z * World.ChunkSize + j)));
                }
                else if (genRan.Random() < 0.3f)
                {
                    //obs.Add(WorldObject.ObjectPositionHash(i, j), new Tree(new Vec2i(x * World.ChunkSize + i, z * World.ChunkSize + j)));
                }
            }
        }
        ChunkData cd = new ChunkData(x, z, tiles, cb.IsLand, obs);

        return(cd);
    }
예제 #16
0
    private void Start()
    {
        ///Chunk test
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        //original chunk
        ProjectileObjectSyncChunk message = new ProjectileObjectSyncChunk();

        message.chunkType       = (int)ChunkType.ProjectileObjectSync;
        message.connID          = 1;
        message.objID           = 12;
        message.position        = new Vector3(1, 1, 1);
        message.veclocity       = new Vector3(2, 2, 2);
        message.force           = new Vector3(3, 3, 3);
        message.isKinematic     = false;
        message.magicalExtraOne = 233;

        //protobuf message
        Chunks.ProjectileObjectSyncChunk projectile = new Chunks.ProjectileObjectSyncChunk();
        projectile.Position        = GetVector3Message(message.position);
        projectile.Velocity        = GetVector3Message(message.veclocity);
        projectile.Force           = GetVector3Message(message.force);
        projectile.IsKinematic     = message.isKinematic;
        projectile.MagicalExtraOne = message.magicalExtraOne;

        //wrapper. (solving the inheritance issue). need a better solution for this.
        ChunkBase chunkBase = new ChunkBase();

        chunkBase.Chunktype = message.chunkType;
        chunkBase.ConnID    = message.connID;
        chunkBase.ObjID     = message.objID;
        //wrap the content
        chunkBase.Content = projectile.ToByteString();

        //Serialize
        byte[] bytes = chunkBase.ToByteArray();

        //Deserialize
        Chunks.ChunkBase parsedChunk = Chunks.ChunkBase.Parser.ParseFrom(bytes);
        if (parsedChunk.Chunktype == (int)ChunkType.ProjectileObjectSync)
        {
            //deserialize to child
            Chunks.ProjectileObjectSyncChunk parsedProjectile = Chunks.ProjectileObjectSyncChunk.Parser.ParseFrom(parsedChunk.Content);
            Debug.Log(GetVector3(parsedProjectile.Position));
            Debug.Log(GetVector3(parsedProjectile.Velocity));
            Debug.Log(GetVector3(parsedProjectile.Force));
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        ///List Test
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        //ListTest list = new ListTest();
        //for(int i=0; i<10; i++)
        //{
        //    list.List.Add(GetVector3Message(new Vector3(i,i,i)));
        //}

        //byte[] bytes = list.ToByteArray();

        //ListTest newList = ListTest.Parser.ParseFrom(bytes);
        //foreach(Vector3Message v in newList.List)
        //{
        //    Debug.Log(GetVector3(v));
        //}
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }
예제 #17
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.BaseCoord + 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);
                    }
                }
            }
        }

        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);
                }
                if (ignoreTile != null)
                {
                    if (Tiles[x_, z_] != null && Tiles[x_, z_] != ignoreTile)
                    {
                        return(false);
                    }
                }
                else if (Tiles[x_, z_] != null)
                {
                    return(false);
                }
            }
        }

        return(true);
    }
예제 #18
0
    private void CreateWorld2()
    {
        World             world = new World();
        SettlementBase    b     = new SettlementBase(new Vec2i(8, 8), 8, SettlementType.CAPITAL);
        SettlementBuilder build = new SettlementBuilder(null, b);

        build.GenerateSettlement();

        /*foreach(SettlementPathNode p in build.nodes)
         * {
         *  TestNodes.Add(p);
         * }*/
        Tile[,] tiles           = build.Tiles;
        WorldObjectData[,] objs = build.SettlementObjects;
        int tileSize = build.TileSize;
        int cSize    = tileSize / World.ChunkSize;

        ChunkData[,] cData = new ChunkData[cSize, cSize];
        ChunkBase[,] cBase = new ChunkBase[cSize, cSize];
        for (int x = 0; x < cSize; x++)
        {
            for (int z = 0; z < cSize; z++)
            {
                cBase[x, z]             = new ChunkBase(new Vec2i(x, z), true);
                int[,] cTiles           = new int[World.ChunkSize, World.ChunkSize];
                WorldObjectData[,] cObj = new WorldObjectData[World.ChunkSize, World.ChunkSize];
                Dictionary <int, WorldObjectData> wObjData = new Dictionary <int, WorldObjectData>();
                for (int x_ = 0; x_ < World.ChunkSize; x_++)
                {
                    for (int z_ = 0; z_ < World.ChunkSize; z_++)
                    {
                        if (tiles[x * World.ChunkSize + x_, z *World.ChunkSize + z_] != null)
                        {
                            cTiles[x_, z_] = tiles[x * World.ChunkSize + x_, z *World.ChunkSize + z_].ID;
                        }
                        else
                        {
                            cTiles[x_, z_] = Tile.GRASS.ID;
                        }

                        if (objs[x * World.ChunkSize + x_, z *World.ChunkSize + z_] != null)
                        {
                            wObjData.Add(WorldObject.ObjectPositionHash(x_, z_), objs[x * World.ChunkSize + x_, z * World.ChunkSize + z_]);
                        }
                        // cObj[x_, z_] = objs[x * World.ChunkSize + x_, z * World.ChunkSize + z_];
                    }
                }
                cData[x, z] = new ChunkData(x, z, cTiles, true, wObjData);
            }
        }


        ChunkRegion r = new ChunkRegion(0, 0, cData);

        WorldManager.LoadedRegions[0, 0] = r;



        Kingdom k = new Kingdom("test", new Vec2i(0, 0));

        k.SetKingdomID(world.AddKingdom(k));
        Settlement set = new Settlement(k, "test_set", build);

        set.SetSettlementID(world.AddSettlement(set));

        WorldManager.SetWorld(world);

        KingdomNPCGenerator npcGen = new KingdomNPCGenerator(new GameGenerator(0), k, EntityManager);

        Debug.Log("BASE:" + set.BaseCoord);
        Debug.Log(cSize);
        npcGen.GenerateSettlementNPC(set);

        world.SetChunkBases(cBase);



        for (int x = 0; x < cSize - 1; x++)
        {
            for (int z = 0; z < cSize - 1; z++)
            {
                //LoadChunk(cData[x, z]);
                WorldManager.CRManager.LoadChunk(new Vec2i(x, z));
                EntityManager.LoadChunk(null, new Vec2i(x, z));
            }
        }

        /*
         * DungeonGenerator dugeonGenerator = new DungeonGenerator();
         * dungeon = dugeonGenerator.GenerateDungeon();
         * ChunkRegion r = new ChunkRegion(0, 0, dungeon.SubworldChunks);
         * world.LoadedRegions.Add(new Vec2i(0, 0), r);
         * WorldManager.SetWorld(world);*/
        //world.Set
    }
예제 #19
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);
    }
예제 #20
0
    public void GenerateChunkBases()
    {
        ChunkBases = new ChunkBase[World.WorldSize, World.WorldSize];
        LandChunks = new List <Vec2i>();

        Vec2i mid   = new Vec2i(World.WorldSize / 2, World.WorldSize / 2);
        float r_sqr = (World.WorldSize / 3) * (World.WorldSize / 3);

        WorldRad = (World.WorldSize / 2.1f) * (World.WorldSize / 2.1f);

        Texture2D t    = new Texture2D(World.WorldSize, World.WorldSize);
        Texture2D hum  = new Texture2D(World.WorldSize, World.WorldSize);
        Texture2D temp = new Texture2D(World.WorldSize, World.WorldSize);



        float[,] humdity = new float[World.WorldSize, World.WorldSize];
        Vec2i offset = GenRan.RandomVec2i(World.WorldSize / 8, World.WorldSize / 4);

        Vec2i humMid    = mid + offset;
        float humRadSqr = GenRan.Random(World.WorldSize / 4, World.WorldSize / 2);

        humRadSqr *= humRadSqr;


        Vec2i tempMid    = mid - offset;
        float tempRadSqr = GenRan.Random(World.WorldSize / 4, World.WorldSize / 2);

        tempRadSqr          *= tempRadSqr;
        float[,] temperature = new float[World.WorldSize, World.WorldSize];

        for (int x = 0; x < World.WorldSize; x++)
        {
            for (int z = 0; z < World.WorldSize; z++)
            {
                float c = WorldHeightChunk(x, z);



                humdity[x, z]  = 0.4f + 0.6f * Mathf.PerlinNoise(4000 + x * 0.02f, 4000 + z * 0.02f);
                humdity[x, z] /= (((x - humMid.x) * (x - humMid.x) + (z - humMid.z) * (z - humMid.z)) / humRadSqr);
                humdity[x, z]  = Mathf.Clamp(humdity[x, z], 0, 1);

                //temperature[x, z] = Mathf.PerlinNoise(700 + x * 0.02f, 700 + z * 0.02f);
                temperature[x, z]  = 0.4f + 0.6f * Mathf.PerlinNoise(700 + x * 0.02f, 700 + z * 0.02f);
                temperature[x, z] /= (((x - tempMid.x) * (x - tempMid.x) + (z - tempMid.z) * (z - tempMid.z)) / tempRadSqr);
                temperature[x, z]  = Mathf.Clamp(temperature[x, z], 0, 1);
                hum.SetPixel(x, z, new Color(humdity[x, z], humdity[x, z], humdity[x, z]));
                temp.SetPixel(x, z, new Color(temperature[x, z], temperature[x, z], temperature[x, z]));

                //c /= (((x - mid.x) * (x - mid.x) + (z - mid.z) * (z - mid.z)) / r_sqr);

                t.SetPixel(x, z, new Color(c / World.ChunkHeight, c / World.ChunkHeight, c / World.ChunkHeight));
                Vec2i v = new Vec2i(x, z);

                //if ((x - mid.x) * (x - mid.x) + (z - mid.z) * (z - mid.z) < r_sqr)
                if (c > 40 && !(x == 0 || z == 0 || x == World.WorldSize - 1 || z == World.WorldSize - 1))
                { //If point within this radius of middle
                    ChunkBases[x, z] = new ChunkBase(v, Mathf.FloorToInt(c), true);
                    LandChunks.Add(v);

                    if (c > 100)
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.mountain);
                    }
                    else if (temperature[x, z] > 0.7f && humdity[x, z] < 0.4f)
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.dessert);
                    }
                    else if (humdity[x, z] > 0.4f && temperature[x, z] > 0.5f)
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.forrest);
                    }
                    else
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.grassland);
                    }

                    /*
                     * if(temperature[x, z] > 0.7f && humdity[x,z] < 0.4f)
                     * {
                     *  ChunkBases[x, z].SetBiome(ChunkBiome.dessert);
                     * }else if(temperature[x, z] < 0.7f && humdity[x, z] > 0.6f)
                     * if (temperature[x, z] < 0.25f)
                     * {
                     *  ChunkBases[x, z].SetBiome(ChunkBiome.forrest);
                     * }
                     * else
                     * {
                     *      ChunkBases[x, z].SetBiome(ChunkBiome.grassland);
                     * }*/
                }
                else
                {
                    ChunkBases[x, z] = new ChunkBase(v, 1, false);
                }
            }
        }
        t.Apply();
        hum.Apply();
        temp.Apply();

        /*
         * GameManager.Game.toDrawTexts[0] = t;
         * GameManager.Game.toDrawTexts[1] = hum;
         * GameManager.Game.toDrawTexts[2] = temp;*/
    }
예제 #21
0
    public void GenerateMesh()
    {
        // Default 4096, else use the lase size + 1024
        int newSize = vertexBuffer.used == 0 ? 4096 : vertexBuffer.used + 1024;

        vertexBuffer.Reset(newSize);

        // Negative X side
        cXN = chunkPosX > 0 ? m.chunks[chunkPosX - 1, chunkPosY, chunkPosZ] : null;

        // Positive X side
        cXP = chunkPosX < Constants.ChunkXAmount - 1 ? m.chunks[chunkPosX + 1, chunkPosY, chunkPosZ] : null;

        // Negative Y side
        cYN = chunkPosY > 0 ? m.chunks[chunkPosX, chunkPosY - 1, chunkPosZ] : null;

        // Positive Y side
        cYP = chunkPosY < Constants.ChunkYAmount - 1 ? m.chunks[chunkPosX, chunkPosY + 1, chunkPosZ] : null;

        // Negative Z neighbour
        cZN = chunkPosZ > 0 ? m.chunks[chunkPosX, chunkPosY, chunkPosZ - 1] : null;

        // Positive Z side
        cZP = chunkPosZ < Constants.ChunkZAmount - 1 ? m.chunks[chunkPosX, chunkPosY, chunkPosZ + 1] : null;

        // Precalculate the map-relative Y position of the chunk in the map
        int chunkY = chunkPosY * CHUNK_SIZE;

        // Allocate variables on the stack
        int  access, heightMapAccess, iCS, kCS2, i1, k1, j, topJ;
        bool minXEdge, maxXEdge, minZEdge, maxZEdge;

        k1 = 1;

        for (int k = 0; k < CHUNK_SIZE; k++, k1++)
        {
            // Calculate this once, rather than multiple times in the inner loop
            kCS2 = k * CHUNK_SIZE_SQUARED;

            i1 = 1;
            heightMapAccess = k * CHUNK_SIZE;

            // Is the current run on the Z- or Z+ edge of the chunk
            minZEdge = k == 0;
            maxZEdge = k == CHUNK_SIZE_MINUS_ONE;

            for (int i = 0; i < CHUNK_SIZE; i++; i1++)
            {
                // Determine where to start the innermost loop
                j    = MinY[heightMapAccess];
                topJ = MaxY[heightMapAccess];
                heightMapAccess++;

                // Calculate this once, rather than multiple times in the inner loop
                iCS = i * CHUNK_SIZE;

                // Calculate access here and increment it each time in the innermost loop
                access = kCS2 + iCS + j;

                // Is the current run on the X- or X+ edge of the chunk
                minX = i == 0;
                maxX = i == CHUNK_SIZE_MINUS_ONE;

                // X and Z runs search upwards to create runs, so start at the bottom.
                for (; j < topJ; j++, access++)
                {
                    ref Block b = ref data[access];

                    if (b.kind != EMPTY)
                    {
                        CreateRun(ref b, i, j, k << 12, i1, k1 << 12, j + chunkY, access, minX, maxX, j == 0, j == CHUNK_SIZE_MINUS_ONE, minZ, maxZ, iCS, kCS2);
                    }
                }

                // Extend the array if it is nearly full
                if (vertexBuffer.used > vertexBuffer.data.Length - 2048)
                {
                    vertexBuffer.Extend(2048);
                }
            }
        }
예제 #22
0
    public void GenerateChunkBases()
    {
        ChunkBases = new ChunkBase[World.WorldSize, World.WorldSize];
        LandChunks = new List <Vec2i>();
        GenerationRandom genRan = new GenerationRandom(0);

        Vec2i mid   = new Vec2i(World.WorldSize / 2, World.WorldSize / 2);
        float r_sqr = (World.WorldSize / 3) * (World.WorldSize / 3);

        Texture2D t    = new Texture2D(World.WorldSize, World.WorldSize);
        Texture2D hum  = new Texture2D(World.WorldSize, World.WorldSize);
        Texture2D temp = new Texture2D(World.WorldSize, World.WorldSize);



        float[,] humdity = new float[World.WorldSize, World.WorldSize];
        Vec2i offset = genRan.RandomVec2i(World.WorldSize / 8, World.WorldSize / 4);

        Vec2i humMid    = mid + offset;
        float humRadSqr = genRan.Random(World.WorldSize / 4, World.WorldSize / 2);

        humRadSqr *= humRadSqr;


        Vec2i tempMid    = mid - offset;
        float tempRadSqr = genRan.Random(World.WorldSize / 4, World.WorldSize / 2);

        tempRadSqr          *= tempRadSqr;
        float[,] temperature = new float[World.WorldSize, World.WorldSize];

        for (int x = 0; x < World.WorldSize; x++)
        {
            for (int z = 0; z < World.WorldSize; z++)
            {
                float c = 1 - Mathf.Pow(Mathf.PerlinNoise(x * 0.01f, z * 0.01f), 2);

                humdity[x, z]  = 0.4f + 0.6f * Mathf.PerlinNoise(4000 + x * 0.02f, 4000 + z * 0.02f);
                humdity[x, z] /= (((x - humMid.x) * (x - humMid.x) + (z - humMid.z) * (z - humMid.z)) / humRadSqr);
                humdity[x, z]  = Mathf.Clamp(humdity[x, z], 0, 1);

                //temperature[x, z] = Mathf.PerlinNoise(700 + x * 0.02f, 700 + z * 0.02f);
                temperature[x, z]  = 0.4f + 0.6f * Mathf.PerlinNoise(700 + x * 0.02f, 700 + z * 0.02f);
                temperature[x, z] /= (((x - tempMid.x) * (x - tempMid.x) + (z - tempMid.z) * (z - tempMid.z)) / tempRadSqr);
                temperature[x, z]  = Mathf.Clamp(temperature[x, z], 0, 1);
                hum.SetPixel(x, z, new Color(humdity[x, z], humdity[x, z], humdity[x, z]));
                temp.SetPixel(x, z, new Color(temperature[x, z], temperature[x, z], temperature[x, z]));

                c /= (((x - mid.x) * (x - mid.x) + (z - mid.z) * (z - mid.z)) / r_sqr);

                t.SetPixel(x, z, new Color(c, c, c));
                Vec2i v = new Vec2i(x, z);

                //if ((x - mid.x) * (x - mid.x) + (z - mid.z) * (z - mid.z) < r_sqr)
                if (c > 0.5)
                { //If point within this radius of middle
                    ChunkBases[x, z] = new ChunkBase(v, true);
                    LandChunks.Add(v);


                    //Deserts if its hot and dry
                    if (temperature[x, z] > 0.7f && humdity[x, z] < 0.4f)
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.dessert);
                    }
                    else if (humdity[x, z] > 0.4f && temperature[x, z] > 0.5f)
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.forrest);
                    }
                    else
                    {
                        ChunkBases[x, z].SetBiome(ChunkBiome.grassland);
                    }

                    /*
                     * if(temperature[x, z] > 0.7f && humdity[x,z] < 0.4f)
                     * {
                     *  ChunkBases[x, z].SetBiome(ChunkBiome.dessert);
                     * }else if(temperature[x, z] < 0.7f && humdity[x, z] > 0.6f)
                     * if (temperature[x, z] < 0.25f)
                     * {
                     *  ChunkBases[x, z].SetBiome(ChunkBiome.forrest);
                     * }
                     * else
                     * {
                     *      ChunkBases[x, z].SetBiome(ChunkBiome.grassland);
                     * }*/
                }
                else
                {
                    ChunkBases[x, z] = new ChunkBase(v, false);
                }
            }
        }
        t.Apply();
        hum.Apply();
        temp.Apply();

        GameManager.Game.toDrawTexts[0] = t;
        GameManager.Game.toDrawTexts[1] = hum;
        GameManager.Game.toDrawTexts[2] = temp;
    }
예제 #23
0
    private ChunkData GenerateChunk(int[,] landClone, ChunkBase cb)
    {
        int x = cb.Position.x;
        int z = cb.Position.z;

        //If there is a river passing through here
        if (cb.RiverNode != null)
        {
            float sqrt2 = Mathf.Sqrt(2);
            int[,] tiles            = new int[World.ChunkSize, World.ChunkSize];
            WorldObjectData[,] data = new WorldObjectData[World.ChunkSize, World.ChunkSize];

            RiverNode rn        = cb.RiverNode;
            Vec2i     exitDelta = rn.RiverExitDelta;
            Vec2i     entrDelta = rn.RiverEntranceDelta;

            if (exitDelta == null)
            {
                exitDelta = new Vec2i(0, 0);
            }
            if (entrDelta == null)
            {
                entrDelta = new Vec2i(0, 0);
            }

            //Calculatee the tile position of the entrance and exit point of the river
            int entrX = (entrDelta.x == 1) ? 16 : ((entrDelta.x == 0) ? 8 : 0);
            int entrZ = (entrDelta.z == 1) ? 16 : ((entrDelta.z == 0) ? 8 : 0);

            int exitX = (exitDelta.x == 1) ? 16 : ((exitDelta.x == 0) ? 8 : 0);
            int exitZ = (exitDelta.z == 1) ? 16 : ((exitDelta.z == 0) ? 8 : 0);



            float dx = entrX - exitX;
            float dz = entrZ - exitZ;
            //If dx or dz is 0, then
            float a, b, c;
            bool  angle = (dx != 0 && dz != 0);
            float divBy = angle ? 2 : 1;
            if (dx == 0)
            {
                a = 0;
                b = 1;
                c = -entrX;
            }
            else if (dz == 0)
            {
                a = 1;
                b = 0;
                c = -entrZ;
            }
            else
            {
                float m = dz / dx;
                c = -(entrZ - m * entrX);

                a = 1;
                b = -m;
            }


            float dem_sqr = (a * a + b * b);

            for (int tx = 0; tx < World.ChunkSize; tx++)
            {
                for (int tz = 0; tz < World.ChunkSize; tz++)
                {
                    float dist_sqr = ((a * tz + b * tx + c) * (a * tz + b * tx + c)) / dem_sqr;
                    if (dist_sqr < (cb.RiverNode.EntranceWidth * cb.RiverNode.EntranceWidth) / divBy)
                    {
                        Vector2 off = new Vector2(x * World.ChunkSize + tx, z * World.ChunkSize + tz);
                        //Debug.Log("here");
                        tiles[tx, tz] = Tile.WATER.ID;

                        if (!(data[tx, tz] is Water))
                        {
                            data[tx, tz] = new Water(new Vec2i(x * World.ChunkSize + tx, z * World.ChunkSize + tz));
                            (data[tx, tz] as Water).SetUVOffset(off);
                        }

                        if (tx < World.ChunkSize - 1 && !(data[tx + 1, tz] is Water))
                        {
                            data[tx + 1, tz] = new Water(new Vec2i(x * World.ChunkSize + tx + 1, z * World.ChunkSize + tz));
                            (data[tx + 1, tz] as Water).SetUVOffset(off + new Vector2(1, 0));
                        }
                        if (tz < World.ChunkSize - 1 && !(data[tx, tz + 1] is Water))
                        {
                            data[tx, tz + 1] = new Water(new Vec2i(x * World.ChunkSize + tx, z * World.ChunkSize + tz + 1));
                            (data[tx, tz + 1] as Water).SetUVOffset(off + new Vector2(0, 1));
                        }
                        if (tx < World.ChunkSize - 1 && tz < World.ChunkSize - 1 && !(data[tx + 1, tz + 1] is Water))
                        {
                            data[tx + 1, tz + 1] = new Water(new Vec2i(x * World.ChunkSize + tx + 1, z * World.ChunkSize + tz + 1));
                            (data[tx + 1, tz + 1] as Water).SetUVOffset(off + new Vector2(1, 1));
                        }

                        if (tx > 0 && !(data[tx - 1, tz] is Water))
                        {
                            data[tx - 1, tz] = new Water(new Vec2i(x * World.ChunkSize + tx - 1, z * World.ChunkSize + tz));
                            (data[tx - 1, tz] as Water).SetUVOffset(off + new Vector2(-1, 0));
                        }
                        if (tz > 0 && !(data[tx, tz - 1] is Water))
                        {
                            data[tx, tz - 1] = new Water(new Vec2i(x * World.ChunkSize + tx, z * World.ChunkSize + tz - 1));
                            (data[tx, tz - 1] as Water).SetUVOffset(off + new Vector2(0, -1));
                        }
                        if (tx > 0 && tz > 0 && !(data[tx - 1, tz - 1] is Water))
                        {
                            data[tx - 1, tz - 1] = new Water(new Vec2i(x * World.ChunkSize + tx - 1, z * World.ChunkSize + tz - 1));
                            (data[tx - 1, tz - 1] as Water).SetUVOffset(off + new Vector2(-1, -1));
                        }

                        if (tx > 0 && tz < World.ChunkSize - 1 && !(data[tx - 1, tz + 1] is Water))
                        {
                            data[tx - 1, tz + 1] = new Water(new Vec2i(x * World.ChunkSize + tx - 1, z * World.ChunkSize + tz + 1));
                            (data[tx - 1, tz + 1] as Water).SetUVOffset(off + new Vector2(-1, +1));
                        }
                        if (tz > 0 && tx < World.ChunkSize - 1 && !(data[tx + 1, tz - 1] is Water))
                        {
                            data[tx + 1, tz - 1] = new Water(new Vec2i(x * World.ChunkSize + tx + 1, z * World.ChunkSize + tz - 1));
                            (data[tx + 1, tz - 1] as Water).SetUVOffset(off + new Vector2(1, -1));
                        }
                    }
                    else if (dist_sqr < (cb.RiverNode.EntranceWidth * cb.RiverNode.EntranceWidth) * 1.4f / divBy)
                    {
                        tiles[tx, tz] = Tile.SAND.ID;
                    }
                    else
                    {
                        tiles[tx, tz] = Tile.GRASS.ID;
                    }
                }
            }

            data[0, 0] = new Tree(new Vec2i(x * World.ChunkSize, z * World.ChunkSize));


            Dictionary <int, WorldObjectData> data_ = new Dictionary <int, WorldObjectData>();

            for (int i = 0; i < World.ChunkSize; i++)
            {
                for (int j = 0; j < World.ChunkSize; j++)
                {
                    if (data[i, j] != null)
                    {
                        data_.Add(WorldObject.ObjectPositionHash(i, j), data[i, j]);
                    }
                }
            }

            return(new ChunkData(x, z, tiles, cb.IsLand, data_));

            //Debug.Log("river");
        }
        else
        {
            ChunkData cd = new ChunkData(x, z, landClone, cb.IsLand);
            return(cd);
        }
    }
예제 #24
0
    private ChunkData GenerateLakeChunk(int x, int z, ChunkBase cb)
    {
        ChunkData cd = new ChunkData(x, z, (int[, ])OCEAN.Clone(), false);

        return(cd);
    }
예제 #25
0
    private void GenerateWorld3()
    {
        World world = new World();

        //Create chunk bases
        ChunkBase[,] chunk_b = new ChunkBase[World.RegionSize, World.RegionSize];

        ChunkData[,] chunks = new ChunkData[World.RegionSize, World.RegionSize];



        River r = new River();



        r.SetFirstChunk(new Vec2i(2, 2), 6);
        r.AddChunk(new Vec2i(3, 2), 6);
        r.AddChunk(new Vec2i(4, 2), 6);
        r.AddChunk(new Vec2i(4, 3), 6);
        r.AddChunk(new Vec2i(5, 3), 6);

        /*
         * r.AddChunk(new Vec2i(3,2), 6);
         * r.AddChunk(new Vec2i(3, 3), 6);
         * r.AddChunk(new Vec2i(4, 3), 6);
         * r.AddChunk(new Vec2i(4, 2), 6);
         * r.AddChunk(new Vec2i(4, 1), 6);
         * r.AddChunk(new Vec2i(3, 1), 6);
         * r.AddChunk(new Vec2i(2, 1), 6);
         * r.AddChunk(new Vec2i(1, 1), 6);
         */
        /*
         * Vec2i last = new Vec2i(2, 2);
         * for(int i=0; i<10; i++)
         * {
         *  int t = (i % 8);
         *  int dx = 0;
         *  int dz = 0;
         *  if (t == 0 || t==1)
         *      dx = 1;
         *  else if (t == 2 || t == 3)
         *      dz = 1;
         *  else if (t == 3 || t == 5)
         *      dx = -1;
         *  else
         *      dz = -1;
         *  //int dx = (i % 2);
         *  //int dz = (i + 1) % 2;
         *  last = last + new Vec2i(dx, dz);
         *  r.AddChunk(last, 6);
         * }*/


        for (int rx = 0; rx < World.RegionSize; rx++)
        {
            for (int rz = 0; rz < World.RegionSize; rz++)
            {
                chunk_b[rx, rz] = new ChunkBase(new Vec2i(rx, rz), true);
            }
        }

        foreach (KeyValuePair <Vec2i, RiverNode> kvp in r.GenerateRiverNodes())
        {
            chunk_b[kvp.Key.x, kvp.Key.z].AddRiver(kvp.Value);
        }

        int[,] emptyLandChunk = new int[World.ChunkSize, World.ChunkSize];
        for (int x = 0; x < World.ChunkSize; x++)
        {
            for (int z = 0; z < World.ChunkSize; z++)
            {
                emptyLandChunk[x, z] = Tile.GRASS.ID;
            }
        }
        for (int rx = 0; rx < World.RegionSize; rx++)
        {
            for (int rz = 0; rz < World.RegionSize; rz++)
            {
                chunks[rx, rz] = GenerateChunk((int[, ])emptyLandChunk.Clone(), chunk_b[rx, rz]);
            }
        }

        ChunkRegion region = new ChunkRegion(0, 0, chunks);

        WorldManager.SetWorld(world);
        WorldManager.LoadedRegions[0, 0] = region;
        world.SetChunkBases(chunk_b);
        for (int rx = 0; rx < World.RegionSize - 1; rx++)
        {
            for (int rz = 0; rz < World.RegionSize - 1; rz++)
            {
                WorldManager.CRManager.LoadChunk(new Vec2i(rx, rz));
            }
        }
    }
예제 #26
0
    private void GenerateRiverBridge(ChunkBase cb, WorldObjectData[,] chunkObjs, int bridgeWidth = 5)
    {
        RiverNode rn    = cb.RiverNode;
        int       rDirX = Mathf.Abs(rn.RiverNodeDirection().x);
        int       rDirZ = Mathf.Abs(rn.RiverNodeDirection().z);

        if (rDirX == 1 && rDirZ == 1)
        {
            return;
        }

        Vec2i absDir = new Vec2i(rDirX, rDirZ);

        int riverWidth = (int)rn.EntranceWidth;
        int halfWidth  = bridgeWidth / 2;

        Vec2i start, end;

        if (rDirX == 1)
        {
            start = new Vec2i(World.ChunkSize / 2 - halfWidth, World.ChunkSize / 2 - riverWidth);
            end   = new Vec2i(World.ChunkSize / 2 + halfWidth, World.ChunkSize / 2 + riverWidth + 1);
        }
        else
        {
            start = new Vec2i(World.ChunkSize / 2 - riverWidth, World.ChunkSize / 2 - halfWidth);
            end   = new Vec2i(World.ChunkSize / 2 + riverWidth + 1, World.ChunkSize / 2 + halfWidth);
        }


        RiverBridgeObject rbObj = new RiverBridgeObject(start, end, absDir);

        IMultiTileObjectChild[,] childs = rbObj.GetChildren();

        for (int x = 0; x < rbObj.Size.x; x++)
        {
            for (int z = 0; z < rbObj.Size.z; z++)
            {
                chunkObjs[start.x + x, start.z + z] = childs[x, z] as WorldObjectData;
            }
        }

        /*
         * //If these do not sum to 1, the direction is not simple (i.e, diagonal) and no bridge can be made
         * if (rnDir.x + rnDir.z != 1)
         *  return;
         * //If the river is travelling in the z direction
         * if (rnDir.x == 0)
         * {
         *  Vec2i start = new Vec2i(World.ChunkSize / 2 - halfWidth, World.ChunkSize / 2 - riverWidth);
         *  Vec2i end = new Vec2i(World.ChunkSize / 2 + halfWidth, World.ChunkSize / 2 + riverWidth);
         *
         *  RiverBridgeObject rbObj = new RiverBridgeObject(start, end, new Vec2i(1,0));
         *  IMultiTileObjectChild[,] childs = rbObj.GetChildren();
         *  for(int x=0; x<rbObj.Size.x; x++)
         *  {
         *      for(int z=0; z<rbObj.Size.z; z++)
         *      {
         *          chunkObjs[start.x + x, start.z + z] = childs[x, z] as WorldObjectData;
         *      }
         *  }
         * }
         * else
         * {
         *
         * }*/
    }
예제 #27
0
        public static ChunkColumn DecocedChunkColumn(byte[] buffer)
        {
            return(null);

            lock (_chunkRead)
            {
                MemoryStream stream = new MemoryStream(buffer);
                {
                    NbtBinaryReader defStream = new NbtBinaryReader(stream, true);

                    Log.Debug("New chunk column");

                    int count = defStream.ReadByte();
                    if (count < 1)
                    {
                        Log.Warn("Nothing to read");
                        return(null);
                    }

                    Log.Debug($"Reading {count} sections");

                    ChunkColumn chunkColumn = new ChunkColumn();

                    for (int s = 0; s < count; s++)
                    {
                        int idx = defStream.ReadByte();

                        Log.Debug($"New section {s}, index={idx}");
                        ChunkBase chunk = chunkColumn[s];

                        int chunkSize = 16 * 16 * 16;
                        //defStream.Read(chunk.blocks, 0, chunkSize);
                        //Log.Debug($"Blocks1:\n{Package.HexDump(chunk.blocks)}");

                        //if (defStream.Read(chunk.metadata.Data, 0, chunkSize/2) != chunkSize/2) Log.Error($"Out of data: metadata");

                        //Log.Debug($"metadata:\n{Package.HexDump(chunk.metadata.Data)}");

                        //if (defStream.Read(chunk.skylight.Data, 0, chunkSize/2) != chunkSize/2) Log.Error($"Out of data: skylight");
                        //Log.Debug($"skylight:\n{Package.HexDump(chunk.skylight.Data)}");

                        //if (defStream.Read(chunk.blocklight.Data, 0, chunkSize/2) != chunkSize/2) Log.Error($"Out of data: blocklight");
                        //Log.Debug($"blocklight:\n{Package.HexDump(chunk.blocklight.Data)}");

                        //Log.Debug($"skylight.Data:\n{Package.HexDump(chunk.skylight.Data, 64)}");
                        //Log.Debug($"blocklight.Data:\n{Package.HexDump(chunk.blocklight.Data)}");

                        //byte[] ints = new byte[256*4];
                        //var readLen = defStream.Read(ints, 0, ints.Length);
                        //if (readLen != ints.Length) Log.Error($"Out of data biomeColors, read lenght {readLen}");
                        //Log.Debug($"biomeColor (pre):\n{Package.HexDump(ints)}");

                        //return null;
                        //int j = 0;
                        //for (int i = 0; i < ints.Length; i = i + 4)
                        //{
                        //	chunk.biomeId[j] = ints[i];
                        //	chunk.biomeColor[j++] = BitConverter.ToInt32(new[] {(byte) 0, ints[i + 1], ints[i + 2], ints[i + 3]}, 0);
                        //}
                        //Log.Debug($"biomeId (post):\n{Package.HexDump(chunk.biomeId)}");

                        //if (stream.Position >= stream.Length - 1) return chunk;

                        ////return chunk;

                        //return chunk;
                    }

                    //if (stream.Position >= stream.Length - 1) continue;


                    byte[] ba = new byte[512];
                    if (defStream.Read(ba, 0, 256 * 2) != 256 * 2)
                    {
                        Log.Error($"Out of data height");
                    }

                    Buffer.BlockCopy(ba, 0, chunkColumn.height, 0, 512);
                    //Log.Debug($"Heights:\n{Package.HexDump(ba)}");

                    //if (stream.Position >= stream.Length - 1) continue;

                    if (defStream.Read(chunkColumn.biomeId, 0, 256) != 256)
                    {
                        Log.Error($"Out of data biomeId");
                    }
                    //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}");

                    //if (stream.Position >= stream.Length - 1) continue;


                    int borderBlock = VarInt.ReadInt32(stream);
                    if (borderBlock != 0)
                    {
                        byte[] buf = new byte[borderBlock];
                        int    len = defStream.Read(buf, 0, borderBlock);
                        Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes");
                        Log.Debug($"{Packet.HexDump(buf)}");
                        for (int i = 0; i < borderBlock; i++)
                        {
                            int x = (buf[i] & 0xf0) >> 4;
                            int z = buf[i] & 0x0f;
                            Log.Debug($"x={x}, z={z}");
                        }
                    }

                    int extraCount = VarInt.ReadSInt32(stream);
                    if (extraCount != 0)
                    {
                        //Log.Warn($"Got extradata\n{Package.HexDump(defStream.ReadBytes(extraCount*10))}");
                        for (int i = 0; i < extraCount; i++)
                        {
                            var hash      = VarInt.ReadSInt32(stream);
                            var blockData = defStream.ReadInt16();
                            Log.Warn($"Got extradata: hash=0x{hash:X2}, blockdata=0x{blockData:X2}");
                        }
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        //Log.Debug($"Got NBT data\n{Package.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}");

                        while (stream.Position < stream.Length)
                        {
                            NbtFile file = new NbtFile()
                            {
                                BigEndian = false, UseVarInt = true
                            };

                            file.LoadFromStream(stream, NbtCompression.None);

                            Log.Debug($"Blockentity: {file.RootTag}");
                        }
                    }
                    if (stream.Position < stream.Length - 1)
                    {
                        Log.Warn($"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}");
                    }

                    return(chunkColumn);
                }
            }
        }
예제 #28
0
        /// <summary>
        /// Reads the fiche's description and HTML content
        /// </summary>
        /// <param name="_reader"></param>
        /// <remarks>Heavy chunks are NOT read and will only be accessible asynchronously</remarks>
        public void             Read(BinaryReader _reader)
        {
            uint signature = _reader.ReadUInt32();

            if (signature != SIGNATURE)
            {
                throw new Exception("Unexpected signature!");
            }

            uint versionMajor, versionMinor;

            versionMajor = (uint)_reader.ReadUInt16();
            versionMinor = (uint)_reader.ReadUInt16();
            uint version = (versionMajor << 16) | versionMinor;

            // Read hierarchy
            string strGUID = _reader.ReadString();

            if (!Guid.TryParse(strGUID, out m_GUID))
            {
                throw new Exception("Failed to parse fiche GUID!");
            }

            string strCreationTime = _reader.ReadString();

            if (!DateTime.TryParse(strCreationTime, out m_creationTime))
            {
                throw new Exception("Failed to parse fiche creation time!");
            }

            // We only read the GUIDs while the actual fiches will be processed later
            uint parentsCount = _reader.ReadUInt32();

            while (m_tags.Count > 0)
            {
                RemoveTag(m_tags[0]);
            }
            m_tagGUIDs = new Guid[parentsCount];
            for (int parentIndex = 0; parentIndex < parentsCount; parentIndex++)
            {
                strGUID = _reader.ReadString();
                if (!Guid.TryParse(strGUID, out m_tagGUIDs[parentIndex]))
                {
                    throw new Exception("Failed to parse fiche's parent GUID!");
                }
            }

            // Read content
            string strType = _reader.ReadString();

            if (!Enum.TryParse(strType, out m_type))
            {
                throw new Exception("Failed to parse fiche's type!");
            }
            m_title = _reader.ReadString();
            if (_reader.ReadBoolean())
            {
                string strURL = _reader.ReadString();
                m_URL = WebHelpers.CreateCanonicalURL(strURL);
            }
            if (_reader.ReadBoolean())
            {
                m_HTMLContent = _reader.ReadString();
            }
            if (_reader.ReadBoolean())
            {
                m_rootElement = new Brain2.DOMElement(_reader);
            }

            // Read chunks
            while (m_chunks.Count > 0)
            {
                m_chunks[0].Dispose();
                m_chunks.RemoveAt(0);
            }
            uint chunksCount = _reader.ReadUInt32();

            for (uint chunkIndex = 0; chunkIndex < chunksCount; chunkIndex++)
            {
                string chunkType        = _reader.ReadString();
                uint   chunkLength      = _reader.ReadUInt32();
                ulong  chunkStartOffset = (ulong)_reader.BaseStream.Position;

                ChunkBase chunk = CreateChunkFromType(chunkType, chunkStartOffset, chunkLength);
                if (chunk != null)
                {
                    chunk.Read(_reader);                        // Only shallow data will be available, heavy data will be loaded asynchonously on demand
                }

                // Always jump to chunk's end, whether it read something or not...
                ulong chunkEndOffset = chunkStartOffset + chunkLength;
                _reader.BaseStream.Seek((long)chunkEndOffset, SeekOrigin.Begin);
            }

            // Fiche is now ready!
            m_status = STATUS.READY;
        }