Exemplo n.º 1
0
        /// <summary>
        /// check the given chain is valid.
        /// </summary>
        /// <param name="blockchain"></param>
        /// <returns></returns>

        public static bool IsValid(Blockchain blockchain)
        {
            if (blockchain == null)
            {
                return(false);
            }

            var blocks = blockchain.Blocks;

            if (blocks.Count < 1)
            {
                return(false);
            }

            if (blocks[0].ToString() != BlockUtil.GenesisBlock.ToString())
            {
                return(false);
            }

            for (var i = 0; i < blocks.Count; i++)
            {
                var block     = blocks[i];
                var lastblock = blocks[i - 1];

                if (block.PreviousHash != lastblock.Hash || block.Hash != BlockUtil.GenerateHash(block))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 2
0
    /// <summary>
    /// Generate all the chunks within a given sector and return the sector reference
    /// </summary>
    /// <param name="world"></param>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public Sector generateSector(World world, int x, int y)
    {
        Sector sector = new Sector(world);

        sector.setPosition(new Vector2I(x, y));

        int dim = Sector.chunkDimension;

        Chunk[,] chunks = new Chunk[dim, dim];

        Vector2I chunkPos = BlockUtil.SectorToChunk(new Vector2I(x, y));

        for (int i = 0; i < dim; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                // Create the corresponding chunk based on its world position
                Chunk chunk = generateChunk(world, chunkPos.x + i, chunkPos.y + j);
                chunks[i, j] = chunk;
            }
        }

        sector.setChunks(chunks);
        return(sector);
    }
Exemplo n.º 3
0
    public MapHandler(World world, Vector2I startingPosition)
    {
        _activeSectors = new List <Sector>();
        _generator     = new ChunkGenerator();
        _saving        = new Queue <Sector>();
        _loading       = new Queue <Vector2I>();
        _world         = world;

        // Work out the bottom left corner from the starting chunk
        int      half         = (_loadedDimension - 1) / 2;
        Vector2I cornerSector = BlockUtil.SectorFromChunk(startingPosition) + new Vector2I(-half, -half);

        Debug.Log("Setting corner to " + cornerSector);

        // Set the starting position
        _position = cornerSector;

        // Create the initial sectors
        for (int i = 0; i < _loadedDimension; i++)
        {
            for (int j = 0; j < _loadedDimension; j++)
            {
                Vector2I pos    = _position + new Vector2I(i, j);
                Sector   sector = getSector(pos);
                _activeSectors.Add(sector);
            }
        }

        updatePosition(startingPosition);
    }
    void Update()
    {
        _lastChunk = _currentChunk;

        Vector2I chunkPos = BlockUtil.chunkPositionFromWorld(transform.position);

        _currentChunk = chunkPos;

        // The chunk loader has moved!
        if (_lastChunk != _currentChunk)
        {
            //Debug.Log(String.Format("Chunk changed from {0} to {1}", _lastChunk, _currentChunk));
            _world.loaderMoved(chunkPos);
        }
    }
Exemplo n.º 5
0
    public Chunk getChunk(Vector2I chunkPos)
    {
        Vector2I sector = BlockUtil.SectorFromChunk(chunkPos);

        int sectorX = Mathf.FloorToInt((float)chunkPos.x / Sector.chunkDimension);
        int sectorY = Mathf.FloorToInt((float)chunkPos.y / Sector.chunkDimension);

        int chunkX = chunkPos.x - (sectorX * Sector.chunkDimension);
        int chunkY = chunkPos.y - (sectorY * Sector.chunkDimension);

        for (int i = 0; i < _activeSectors.Count; i++)
        {
            // Has the sector been found?
            if (_activeSectors[i].position == new Vector2I(sectorX, sectorY))
            {
                return(_activeSectors[i].getChunk(chunkPos.x, chunkPos.y));
            }
        }

        return(null);
    }
Exemplo n.º 6
0
 private static GameObject createBlock(float x, float y, float z, int id, float addX, float addY, float addZ, float widthX, float widthY, float widthZ, Material m)
 {
     return(BlockUtil.createBlock(x, y, z, "BlockSpawner", id, addX, addY, addZ, widthX, widthY, widthZ, m));
 }
Exemplo n.º 7
0
 public bool ContainsPoint(int2 point) => BlockUtil.ContainsPoint(point, GroupSize);
Exemplo n.º 8
0
    /// <summary>
    /// Generate the data for a corresponding chunk depending on where it should be in the world
    /// </summary>
    /// <param name="world"></param>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public Chunk generateChunk(World world, int x, int y)
    {
        Chunk chunk = new Chunk(world, new Vector2I(x, y));

        int dim = Chunk.tileDimension;

        Tile[,,] tiles = new Tile[dim, dim, 2];

        // Very simple terrain test
        for (int i = 0; i < dim; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                Vector2I globalPos = BlockUtil.localBlockToWorldBlock(new Vector2I(i, j), new Vector2I(x, y));

                if (globalPos.y <= 21)     // Flat terrain 20 blocks deep
                {
                    if (globalPos.y == 21) // Varying grass / flower
                    {
                        if (UnityEngine.Random.Range(0, 10) < 7)
                        {
                            if (UnityEngine.Random.Range(0, 10) < 2) // Flowers are rarer than tallgrass
                            {
                                tiles[i, j, 0] = new Tile(5, 0);
                                tiles[i, j, 1] = new Tile(0, 0);
                            }
                            else // Tallgrass is more common
                            {
                                tiles[i, j, 0] = new Tile(3, 0);
                                tiles[i, j, 1] = new Tile(0, 0);
                            }
                        }
                        else // Non-grass or flower, set air
                        {
                            tiles[i, j, 0] = new Tile(0, 0);
                            tiles[i, j, 1] = new Tile(0, 0);
                        }
                    }
                    else if (globalPos.y == 20) // Grass
                    {
                        tiles[i, j, 0] = new Tile(4, 0);
                        tiles[i, j, 1] = new Tile(6, 0);
                    }
                    else if (globalPos.y < 20 && globalPos.y > 15) // dirt
                    {
                        tiles[i, j, 0] = new Tile(1, 0);
                        tiles[i, j, 1] = new Tile(6, 0);
                    }
                    else if (globalPos.y <= 15 && globalPos.y > 11 && UnityEngine.Random.Range(0, 10) < 7) // random invariation of dirt
                    {
                        tiles[i, j, 0] = new Tile(1, 0);
                        tiles[i, j, 1] = new Tile(6, 0);
                    }
                    else // stone
                    {
                        tiles[i, j, 0] = new Tile(2, 0);
                        tiles[i, j, 1] = new Tile(10, 0);
                    }
                }
                else // Air
                {
                    tiles[i, j, 0] = new Tile(0, 0);
                    tiles[i, j, 1] = new Tile(0, 0);
                }
            }
        }

        chunk.setData(tiles);

        return(chunk);

        /*  for(int i = 0; i < dim; i++)
         * {
         *    Vector2I globalPos = BlockUtil.localBlockToWorldBlock(new Vector2I(i, 0), new Vector2I(x, 0));
         *    float noise = Mathf.PerlinNoise((float)globalPos.x + seed, (float)globalPos.y);
         *
         *
         * }*/
    }
        protected override void OnUpdate()
        {
            if (groupSystem.IsReady == false)
            {
                return;
            }

            var map = groupSystem.BlocksMap;

            EntityCommandBuffer buffer = commandBufferSystem.CreateCommandBuffer();

            ComponentDataFromEntity <Depth> depthLookup = GetComponentDataFromEntity <Depth>();

            float time = (float)Time.ElapsedTime;

            float deltaTime = Time.DeltaTime;
            var   size      = groupSystem.GroupSize;

            NativeHashMap <int2, int> checkMap = new
                                                 NativeHashMap <int2, int>(groupSystem.GroupSize.x * groupSystem.GroupSize.y,
                                                                           Allocator.TempJob);

            NativeList <int2> pointBuffer = new
                                            NativeList <int2>(groupSystem.GroupSize.x * groupSystem.GroupSize.y,
                                                              Allocator.TempJob);

            var    rand            = Random.CreateFromIndex((uint)Time.ElapsedTime);;
            var    isDrilledLookup = GetComponentDataFromEntity <IsBeingDrilled>();
            var    markLookup      = GetComponentDataFromEntity <Mark>();
            float3 origin          = groupSystem.VisualOrigin;

            float scaleMultiplierThreshold = 0.25f;

            Dependency = Entities.WithReadOnly(depthLookup)
                         .ForEach((Entity entity,
                                   ref Worker worker,
                                   ref Translation translation,
                                   ref NonUniformScale scale,
                                   ref DestinationPoint destination,
                                   ref VerticalLimit verticalLimit,
                                   ref DrillPower power,
                                   in WorkerAnimations animations) =>
            {
                float drillTime = worker.Timer;

                bool isBouncing = power.Bounces < worker.MaxBounces;

                if (isBouncing == false && worker.Timer >= 1)
                {
                    power.Bounces = 0;
                }

                float y =
                    verticalLimit.Value + CurveUtil.Evaluate(ref animations.Bounce.Value.Keyframes, drillTime) * verticalLimit.FlightHeight * scale.Value.x;

                if (isBouncing == false)
                {
                    var t         = CurveUtil.Evaluate(ref animations.Move.Value.Keyframes, drillTime);
                    float3 newPos = origin +
                                    math.lerp(
                        new float3(destination.PreviousPoint.x, y, destination.PreviousPoint.y),
                        new float3(destination.Value.x, y, destination.Value.y), t);
                    translation.Value = newPos;
                }
                else
                {
                    translation.Value = new float3(translation.Value.x, y, translation.Value.z);
                }

                if (worker.Timer >= 1 && isBouncing)
                {
                    worker.Timer         = 0;
                    float newScale       = scale.Value.x - worker.SizeLossPerHit;
                    scale.Value          = new float3(newScale, newScale, newScale);
                    Depth depth          = depthLookup[worker.CurrentBlock];
                    var centerMarkAmount = power.Amount * math.max(scale.Value.x, 0.1f);
                    int2 center          = destination.Value;
                    verticalLimit.Value  = -(depth.Value + centerMarkAmount);

                    LeaveMark(size, center, buffer, centerMarkAmount, map,
                              depthLookup, worker);

                    if (worker.Radius > 0)
                    {
                        float factor = 0.8f;

                        LeaveMark(size, new int2(center.x + 1, center.y), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 1)
                    {
                        float factor = 0.6f;

                        LeaveMark(size, new int2(center.x + 1, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 2)
                    {
                        float spread = 0.4f;

                        LeaveMark(size, new int2(center.x + 2, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 3)
                    {
                        float spread = 0.2f;

                        LeaveMark(size, new int2(center.x - 1, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y + 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y - 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 2, center.y - 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 2, center.y + 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }


                    if (worker.Radius > 4)
                    {
                        float spread = 0.1f;

                        LeaveMark(size, new int2(center.x - 3, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 3, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 3), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 3), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }

                    power.Bounces++;

                    if (power.Bounces >= worker.MaxBounces)
                    {
                        if (BlockUtil.GetClosestBlockOnSameLevel(rand, destination.Value, depthLookup, isDrilledLookup, map, checkMap, pointBuffer, size, out int2 next))
                        {
                            buffer.RemoveComponent <IsBeingDrilled>(worker.CurrentBlock);
                            destination.PreviousPoint = destination.Value;
                            destination.Value         = next;
                            worker.CurrentBlock       = map[next];
                        }
                    }

                    if (newScale <= 0.1f)
                    {
                        buffer.DestroyEntity(entity);
                        buffer.RemoveComponent <IsBeingDrilled>(worker.CurrentBlock);
                    }
                }

                float scaleMultiplier = math.max(scale.Value.x, scaleMultiplierThreshold);
                worker.Timer         += deltaTime / worker.Frequency / scaleMultiplier;
                worker.Timer          = math.min(1, worker.Timer);
            }).Schedule(Dependency);

            Dependency.Complete();

            pointBuffer.Dispose(Dependency);
            checkMap.Dispose(Dependency);

            commandBufferSystem.AddJobHandleForProducer(Dependency);

            CurrentJob = Dependency;
        }
Exemplo n.º 10
0
    public void updatePosition(Vector2I chunkPosition)
    {
        // Convert chunk coordinates to sector coordinates
        Vector2I currentSector = BlockUtil.SectorFromChunk(chunkPosition);

        // Determine the min and max points of the current zone
        Vector2I min = _position;
        Vector2I max = _position + new Vector2I(_loadedDimension - 1, _loadedDimension - 1);

        Debug.Log("Min: " + min + ", Max: " + max + ", Current: " + currentSector);

        // Is the sector out of the bounds or on the edge?
        if (currentSector.x >= max.x || currentSector.x <= min.x || currentSector.y >= max.y || currentSector.y <= min.y)
        {
            int      half      = (_loadedDimension - 1) / 2;
            Vector2I newCorner = currentSector - new Vector2I(half, half);

            List <Vector2I> newPositions    = new List <Vector2I>();
            List <Vector2I> oldPositions    = new List <Vector2I>();
            List <Sector>   cachedPositions = new List <Sector>();

            // Find the new sectors to be part of the zone
            for (int i = 0; i < _loadedDimension; i++)
            {
                for (int j = 0; j < _loadedDimension; j++)
                {
                    newPositions.Add(newCorner + new Vector2I(i, j));
                    oldPositions.Add(_position + new Vector2I(i, j));
                }
            }

            int saving = 0;

            // Compare the old and new positions to determine which shall
            // remain cached and which need saving
            for (int i = 0; i < _activeSectors.Count; i++)
            {
                Sector sector = _activeSectors[i];

                // Only sectors which are existent (to prevent un-bounded sectors from being saved)
                if (sector != null)
                {
                    Vector2I pos = sector.position;

                    // This sector is going to be part of the new zone
                    if (newPositions.Contains(pos))
                    {
                        cachedPositions.Add(sector);
                    }
                    else // This sector needs saving as it will be despawned
                    {
                        // Push the sector for saving
                        queueSector(sector);
                        saving++;
                    }
                }
            }

            // Remove the cached positions from the new list
            for (int i = 0; i < cachedPositions.Count; i++)
            {
                for (int j = 0; j < newPositions.Count; j++)
                {
                    // Do they match? Remove the new position as it doesn't need loading
                    if (cachedPositions[i].position == newPositions[j])
                    {
                        newPositions.RemoveAt(j);
                        break;
                    }
                }
            }

            // Load the desired chunks
            for (int i = 0; i < newPositions.Count; i++)
            {
                _loading.Enqueue(newPositions[i]);
            }

            //// A flag used to keep state for the following logical loop
            //bool flag = false;

            //int loading = 0;
            //int caching = 0;

            //// Iterate over all the new positions and determine
            //// which new positions need to be loaded
            //for (int i = 0; i < newPositions.Count; i++)
            //{
            //    Vector2I pos = newPositions[i];

            //    // Iterate over the cache to find the position to see if it matches
            //    for (int j = 0; j < cachedPositions.Count; j++)
            //    {
            //        if (cachedPositions[j].position == pos)
            //        {
            //            flag = true;
            //            break;
            //        }
            //    }

            //    // The position isn't in the cache so it means it will need to be loaded
            //    if (!flag)
            //    {
            //        loading++;
            //        _loading.Enqueue(pos);
            //    }
            //    else
            //    {
            //        caching++;
            //    }
            //}

            //Debug.Log("Enqueued " + loading + " sectors to load and caching " + caching + " / " + newPositions.Count);

            // Clean up the active sectors ready to re-place them
            _activeSectors.Clear();

            // Re-add the sectors
            for (int i = 0; i < cachedPositions.Count; i++)
            {
                _activeSectors.Add(cachedPositions[i]);
            }

            //// Iterate over and re-position all cached sectors
            //for (int i = 0; i < _loadedDimension; i++)
            //{
            //    for (int j = 0; j < _loadedDimension; j++)
            //    {
            //        Vector2I pos = newCorner + new Vector2I(i, j);

            //        // Search through the cache to find the specified sector
            //        for (int k = 0; k < cachedPositions.Count; k++)
            //        {
            //            // The position has been found, set the sector
            //            if (cachedPositions[k].position == pos)
            //            {
            //                _sectors[i, j] = cachedPositions[k];
            //            }
            //        }

            //        // The sector was not found, allocate the sector as NULL
            //        _sectors[i, j] = null;
            //    }
            //}
            //}

            _position = newCorner;
        }
    }
Exemplo n.º 11
0
 public Coord3 ModWrap(int m) => new Coord3(BlockUtil.ModWrap(x, m), BlockUtil.ModWrap(y, m), BlockUtil.ModWrap(z, m));