Beispiel #1
0
    // public static void SetAndSwitchCell(ChunkWithNeighbors chunkWithNeighbors, int2 oldCellPosition, int2 absoluteNewCellPosition, Cell cell)
    // {
    //     if (GetRelativeCellPosition(chunkWithNeighbors, absoluteNewCellPosition, out var newChunkPosition,
    //         out var newCellPosition))
    //     {
    //         var oldCellChunk = chunkWithNeighbors.Chunk;
    //         var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition);
    //
    //         var existingCell = oldCellChunk.GetCell(oldCellPosition);
    //
    //         oldCellChunk.SetCell(oldCellPosition, existingCell);
    //         newCellChunk.SetCell(newCellPosition, cell);
    //     }
    // }

    // public static bool MoveToIfEmpty(ChunkWithNeighbors chunkWithNeighbors, int2 oldCellPosition, int2 newCellPosition, Cell cell)
    // {
    //     if (GetCellAtPosition(chunkWithNeighbors, newCellPosition, out var neighborChunkPosition, out var neighborCellPosition))
    //     {
    //         var neighborChunk = chunkWithNeighbors.ChunkFromPosition(neighborChunkPosition);
    //         var neighborCell = neighborChunk.GetCell(oldCellPosition);
    //
    //         if (neighborCell.type == CellType.None)
    //         {
    //             chunkWithNeighbors.Chunk.SetCell(newCellPosition, default);
    //             neighborChunk.SetCell(neighborCellPosition, cell);
    //
    //             return true;
    //         }
    //     }
    //
    //     return false;
    // }

    // public static bool SwitchCellsIfTargetEmpty(ChunkWithNeighbors chunkWithNeighbors, int2 absoluteCurrentCellPosition,
    //     int2 absoluteTargetCellPosition)
    // {
    //     if (GetCellAtPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition,
    //         out var oldCellPosition))
    //     {
    //         if (GetCellAtPosition(chunkWithNeighbors, absoluteTargetCellPosition, out var newChunkPosition,
    //             out var newCellPosition))
    //         {
    //             var oldCellChunk = chunkWithNeighbors.Chunk;
    //             var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition);
    //
    //             var oldCell = oldCellChunk.GetCell(oldCellPosition);
    //             var newCell = newCellChunk.GetCell(newCellPosition);
    //
    //             if (newCell.type == CellType.None)
    //             {
    //                 oldCellChunk.SetCell(oldCellPosition, newCell);
    //                 newCellChunk.SetCell(newCellPosition, oldCell);
    //
    //                 return true;
    //             }
    //         }
    //     }
    // }

    public static bool SwitchCellsIfTargetEmpty(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 absoluteCurrentCellPosition, int2 absoluteTargetCellPosition)
    {
        if (GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition, out var oldCellPosition))
        {
            if (GetRelativeCellPosition(chunkWithNeighbors, absoluteTargetCellPosition, out var newChunkPosition, out var newCellPosition))
            {
                var oldCellChunk = chunkWithNeighbors.Value;
                var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition);

                if (newCellChunk.IsOutOfBounds)
                {
                    return(false);
                }

                var oldCell = oldCellChunk.GetCell(oldCellPosition);
                var newCell = newCellChunk.GetCell(newCellPosition);

                if (newCell.type == CellType.None)
                {
                    oldCellChunk.SetCell(oldCellPosition, newCell);
                    newCellChunk.SetCell(newCellPosition, oldCell);

                    return(true);
                }
            }
        }

        return(false);
    }
Beispiel #2
0
    // public static void SwitchCells(ChunkWithNeighbors chunkWithNeighbors, int2 absoluteOldCellPosition, int2 absoluteNewCellPosition, Cell cell)
    // {
    //     if (GetRelativeCellPosition(chunkWithNeighbors, absoluteNewCellPosition, out var newChunkPosition,
    //         out var newCellPosition))
    //     {
    //         var oldCellChunk = chunkWithNeighbors.Chunk;
    //         var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition);
    //
    //         var existingCell = oldCellChunk.GetCell(oldCellPosition);
    //
    //         oldCellChunk.SetCell(oldCellPosition, existingCell);
    //         newCellChunk.SetCell(newCellPosition, cell);
    //     }
    // }
    //
    public static bool SwitchCells(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 absoluteCurrentCellPosition,
                                   int2 offset)
    {
        if (!GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition,
                                     out var oldCellPosition))
        {
            return(false);
        }
        if (!GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition + offset, out var newChunkPosition,
                                     out var newCellPosition))
        {
            return(false);
        }

        var oldCellChunk = chunkWithNeighbors.Value;
        var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition);

        if (newCellChunk.IsOutOfBounds)
        {
            return(false);
        }

        var oldCell = oldCellChunk.GetCell(oldCellPosition);
        var newCell = newCellChunk.GetCell(newCellPosition);

        oldCellChunk.SetCell(oldCellPosition, newCell);
        newCellChunk.SetCell(newCellPosition, oldCell);

        return(true);
    }
Beispiel #3
0
    public static Cell?GetCellAtPosition(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition)
    {
        if (GetRelativeCellPosition(chunkWithNeighbors, cellPosition, out var relativeChunkPosition, out var relativeCellPosition))
        {
            return(chunkWithNeighbors.ChunkFromPosition(relativeChunkPosition).GetCell(relativeCellPosition));
        }

        return(null);
    }
Beispiel #4
0
 public UpdateChunkJob(ValueWithNeighbors <Chunk> chunkWithNeighbors, uint frameCount, Unity.Mathematics.Random random, CommandBuilder drawingCommands, float2 chunkPosition, float chunkScale, float simulationStep)
 {
     this.chunkWithNeighbors = chunkWithNeighbors;
     this.frameCount         = frameCount;
     this.random             = random;
     this.drawingCommands    = drawingCommands;
     this.chunkPosition      = chunkPosition;
     this.chunkScale         = chunkScale;
     this.simulationStep     = simulationStep;
 }
Beispiel #5
0
    public static bool GetRelativeCellPosition(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, out int2 relativeChunkPosition, out int2 relativeCellPosition)
    {
        var chunkOffset        = math.int2(math.floor(math.float2(cellPosition) / math.float2(chunkSize, chunkSize)));
        var relativeTargetCell = (cellPosition - (chunkOffset * chunkSize));

        var neighborChunk = chunkWithNeighbors.ChunkFromPosition(chunkOffset);

        if (neighborChunk.IsOutOfBounds)
        {
            relativeChunkPosition = default;
            relativeCellPosition  = default;
            return(false);
        }

        relativeChunkPosition = chunkOffset;
        relativeCellPosition  = relativeTargetCell;
        return(true);
    }
Beispiel #6
0
    public bool Update(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, Random random)
    {
        Cell?GetCellAtOffset(int2 offset)
        {
            return(CellUtils.GetCellAtPosition(chunkWithNeighbors, cellPosition + offset));
        }

        bool MoveTo(int2 offset)
        {
            return(CellUtils.SwitchCells(chunkWithNeighbors, cellPosition, offset));
        }

        var randomDirection = random.NextBool() ? -1 : 1;

        {
            var cellType = GetCellAtOffset(int2(0, -1))?.type;

            if (cellType == CellType.None || cellType == CellType.Water)
            {
                return(MoveTo(int2(0, -1)));
            }
        }

        {
            var cellType = GetCellAtOffset(int2(randomDirection, -1))?.type;

            if (cellType == CellType.None || cellType == CellType.Water)
            {
                return(MoveTo(int2(randomDirection, -1)));
            }
        }

        {
            var cellType = GetCellAtOffset(int2(-randomDirection, -1))?.type;

            if (cellType == CellType.None || cellType == CellType.Water)
            {
                return(MoveTo(int2(-randomDirection, -1)));
            }
        }

        return(false);
    }
Beispiel #7
0
    private IEnumerator UpdateWorldCoroutine()
    {
        var random = new System.Random();

        while (true)
        {
            if (loadedChunks.Count == 0)
            {
                yield return(new WaitForSeconds(simulationStep));

                continue;
            }

            using var drawingCommands = DrawingManager.GetBuilder();

            var minChunkX = loadedChunks.Min(a => a.Key.x);
            var minChunkY = loadedChunks.Min(a => a.Key.y);
            var maxChunkX = loadedChunks.Max(a => a.Key.x);
            var maxChunkY = loadedChunks.Max(a => a.Key.y);

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    JobHandle?jobHandle = null;

                    for (var chunkX = minChunkX; chunkX <= maxChunkX; chunkX++)
                    {
                        for (var chunkY = minChunkY; chunkY <= maxChunkY; chunkY++)
                        {
                            if (!((abs(chunkX % 2) == i) || (abs(chunkY % 2) == j)))
                            {
                                continue;
                            }

                            var chunkPosition = int2(chunkX, chunkY);
                            if (!loadedChunks.TryGetValue(chunkPosition, out var chunkContainer))
                            {
                                continue;
                            }

                            var chunkContainersWithNeighbors = new ValueWithNeighbors <ChunkContainer?>
                            {
                                Value     = chunkContainer,
                                North     = loadedChunks.TryGetValue(chunkPosition + int2(0, 1)),
                                NorthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, 1)),
                                East      = loadedChunks.TryGetValue(chunkPosition + int2(1, 0)),
                                SouthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, -1)),
                                South     = loadedChunks.TryGetValue(chunkPosition + int2(0, -1)),
                                SouthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, -1)),
                                West      = loadedChunks.TryGetValue(chunkPosition + int2(-1, 0)),
                                NorthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, 1)),
                            };

                            var chunkWithNeighbors = new ValueWithNeighbors <Chunk>
                            {
                                Value     = chunkContainer.Chunk,
                                North     = chunkContainersWithNeighbors.North?.Chunk ?? outOfBoundsChunk,
                                NorthEast = chunkContainersWithNeighbors.NorthEast?.Chunk ?? outOfBoundsChunk,
                                East      = chunkContainersWithNeighbors.East?.Chunk ?? outOfBoundsChunk,
                                SouthEast = chunkContainersWithNeighbors.SouthEast?.Chunk ?? outOfBoundsChunk,
                                South     = chunkContainersWithNeighbors.South?.Chunk ?? outOfBoundsChunk,
                                SouthWest = chunkContainersWithNeighbors.SouthWest?.Chunk ?? outOfBoundsChunk,
                                West      = chunkContainersWithNeighbors.West?.Chunk ?? outOfBoundsChunk,
                                NorthWest = chunkContainersWithNeighbors.NorthWest?.Chunk ?? outOfBoundsChunk
                            };

                            var job = new UpdateChunkJob(chunkWithNeighbors, (uint)Time.frameCount,
                                                         new Unity.Mathematics.Random((uint)random.Next()), drawingCommands,
                                                         (float2)chunkPosition * ChunkScale, ChunkScale, simulationStep);
                            var newJobHandle = job.Schedule();

                            if (jobHandle == null)
                            {
                                jobHandle = newJobHandle;
                            }
                            else
                            {
                                jobHandle = JobHandle.CombineDependencies(jobHandle.Value, newJobHandle);
                            }
                        }
                    }

                    if (jobHandle != null)
                    {
                        jobHandle.Value.Complete();
                    }
                }
            }

            yield return(new WaitForSeconds(simulationStep));
        }
    }
Beispiel #8
0
    public bool Update(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, Random random)
    {
        Cell?GetCellAtOffset(int2 offset)
        {
            return(CellUtils.GetCellAtPosition(chunkWithNeighbors, cellPosition + offset));
        }

        bool MoveTo(int2 offset)
        {
            return(CellUtils.SwitchCells(chunkWithNeighbors, cellPosition, offset));
        }

        var randomDirection = random.NextBool() ? -1 : 1;

        if (GetCellAtOffset(int2(0, -1))?.type == CellType.None)
        {
            return(MoveTo(int2(0, -1)));
        }
        else if (GetCellAtOffset(int2(randomDirection, -1))?.type == CellType.None)
        {
            if (GetCellAtOffset(int2(randomDirection * 2, -2))?.type == CellType.None)
            {
                return(MoveTo(int2(randomDirection * 2, -2)));
            }
            else
            {
                return(MoveTo(int2(randomDirection, -1)));
            }
        }
        else if (GetCellAtOffset(int2(-randomDirection, -1))?.type == CellType.None)
        {
            if (GetCellAtOffset(int2(-randomDirection * 2, -2))?.type == CellType.None)
            {
                return(MoveTo(int2(-randomDirection * 2, -2)));
            }
            else
            {
                return(MoveTo(int2(-randomDirection, -1)));
            }
        }
        else if (GetCellAtOffset(int2(randomDirection, 0))?.type == CellType.None)
        {
            if (GetCellAtOffset(int2(randomDirection * 2, 0))?.type == CellType.None)
            {
                return(MoveTo(int2(randomDirection * 2, 0)));
            }
            else
            {
                return(MoveTo(int2(randomDirection, 0)));
            }
        }
        else if (GetCellAtOffset(int2(-randomDirection, 0))?.type == CellType.None)
        {
            if (GetCellAtOffset(int2(-randomDirection * 2, 0))?.type == CellType.None)
            {
                return(MoveTo(int2(-randomDirection * 2, 0)));
            }
            else
            {
                return(MoveTo(int2(-randomDirection, 0)));
            }
        }

        // return
        //     TryMoveTo(math.int2(0, -1)) ||
        //     TryMoveTo(math.int2(randomDirection * 2, -1)) ||
        //     TryMoveTo(math.int2(-randomDirection * 2, -1)) ||
        //     TryMoveTo(math.int2(randomDirection * 2, 0)) ||
        //     TryMoveTo(math.int2(-randomDirection * 2, 0)) ||
        //     TryMoveTo(math.int2(randomDirection, -1)) ||
        //     TryMoveTo(math.int2(-randomDirection, -1)) ||
        //     TryMoveTo(math.int2(randomDirection, 0)) ||
        //     TryMoveTo(math.int2(-randomDirection, 0));

        return(false);
    }