Beispiel #1
0
        private async Task ActionLook()
        {
            // 通知周围creature entity看着玩家
            EntityWorldPos    entityPos = AttachedObject.GetValue(EntityWorldPositionComponent.EntityWorldPositionProperty);
            ChunkWorldPos     chunkPos  = entityPos.ToChunkWorldPos();
            IChunkTrackingHub tracker   = GrainFactory.GetGrain <IChunkTrackingHub>(AttachedObject.GetAddressByPartitionKey());
            var list = await tracker.GetTrackedPlayers();

            // TODO 多位玩家的话只看一位
            foreach (IPlayer each in list)
            {
                EntityWorldPos playerPosition = await each.GetPosition();

                // 三格内玩家
                if (EntityWorldPos.Distance(playerPosition, entityPos) < 3)
                {
                    (var yaw, var pitch) = VectorToYawAndPitch(entityPos, playerPosition);

                    await AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, yaw);

                    await AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, yaw);

                    await AttachedObject.SetLocalValue(EntityLookComponent.PitchProperty, pitch);

                    break;
                }
            }
        }
Beispiel #2
0
        private async Task <bool> StreamNextChunk(ChunkWorldPos currentChunk)
        {
            if (_lastStreamedChunk.HasValue && _lastStreamedChunk.Value == currentChunk)
            {
                return(true);
            }

            for (int d = 0; d <= _viewDistance; d++)
            {
                for (int x = -d; x <= d; x++)
                {
                    var z = d - Math.Abs(x);

                    if (await StreamChunk(new ChunkWorldPos(currentChunk.X + x, currentChunk.Z + z)))
                    {
                        return(false);
                    }
                    if (await StreamChunk(new ChunkWorldPos(currentChunk.X + x, currentChunk.Z - z)))
                    {
                        return(false);
                    }
                }
            }

            _lastStreamedChunk = currentChunk;
            return(true);
        }
 /// <summary>
 /// Makes a chunk in the given positon if it does not already exist
 /// </summary>
 /// <param name="pos">hte positon of the new chunk</param>
 void BuildChunk(ChunkWorldPos pos)
 {
     if (world.GetChunk(pos.x, pos.y, pos.z) == null)
     {
         world.CreateChunk(pos.x, pos.y, pos.z);
     }
 }
Beispiel #4
0
        protected async Task GenerateOre(IWorld world, ChunkWorldPos chunkWorldPos, GeneratorSettings settings)
        {
            var oreGenerator = GrainFactory.GetGrain <IMinableGenerator>(0);
            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.Dirt(), settings.DirtCount, settings.DirtSize, settings.DirtMinHeight, settings.DirtMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.Gravel(), settings.GravelCount, settings.GravelSize, settings.GravelMinHeight, settings.GravelMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.Granite(), settings.GraniteCount, settings.GraniteSize, settings.GraniteMinHeight, settings.GraniteMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.Diorite(), settings.DioriteCount, settings.DioriteSize, settings.DioriteMinHeight, settings.DioriteMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.Andesite(), settings.AndesiteCount, settings.AndesiteSize, settings.AndesiteMinHeight, settings.AndesiteMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.CoalOre(), settings.CoalCount, settings.CoalSize, settings.CoalMinHeight, settings.CoalMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.IronOre(), settings.IronCount, settings.IronSize, settings.IronMinHeight, settings.IronMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.GoldOre(), settings.GoldCount, settings.GoldSize, settings.GoldMinHeight, settings.GoldMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.DiamondOre(), settings.DiamondCount, settings.DiamondSize, settings.DiamondMinHeight, settings.DiamondMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.RedstoneOre(), settings.RedstoneCount, settings.RedstoneSize, settings.RedstoneMinHeight, settings.RedstoneMaxHeight);

            await oreGenerator.Generate(world, chunkWorldPos, BlockStates.LapisLazuliOre(), settings.LapisCount, settings.LapisSize, settings.LapisCenterHeight - settings.LapisSpread, settings.LapisCenterHeight + settings.LapisSpread);
        }
        public async override Task Decorate(IWorld world, ChunkWorldPos chunkWorldPos, GeneratorSettings settings)
        {
            await GenerateOre(world, chunkWorldPos, settings);

            var grassGenerator = GrainFactory.GetGrain <IGrassGenerator>(JsonConvert.SerializeObject(new PlantsInfo {
            }));
            await grassGenerator.Generate(world, chunkWorldPos, 10);

            /*
             * var jungletreeGenerator = GrainFactory.GetGrain<IJungleGenerator>(
             *  JsonConvert.SerializeObject(new PlantsInfo
             *  {
             *      PlantType = PlantsType.Jungle,
             *      TreeHeight = 10,
             *      ExtraHeight = 20
             *  }));
             * await jungletreeGenerator.Generate(world, chunkWorldPos, 1);
             */
            var savannatreeGenerator = GrainFactory.GetGrain <ISavannaTreeGenerator>(
                JsonConvert.SerializeObject(new PlantsInfo
            {
                PlantType = PlantsType.AcaciaTree,
            }));
            await savannatreeGenerator.Generate(world, chunkWorldPos, 1);
        }
        /// <summary>
        /// Finds the <see cref="Chunk"/>s that should be rendered
        /// </summary>
        void FindChunksToLoad()
        {
            if (buildList.Count == 0)
            {
                //* gets the player position in chunk coordinates
                ChunkWorldPos playerPos = new ChunkWorldPos(Mathf.FloorToInt(transform.position.x / Chunk.chunkSize) * Chunk.chunkSize, Mathf.FloorToInt(transform.position.y / Chunk.chunkSize) * Chunk.chunkSize, Mathf.FloorToInt(transform.position.z / Chunk.chunkSize) * Chunk.chunkSize);

                //* check all of the chunk positions and if that position does not have a chunk in it make it
                for (int i = 0; i < chunkPositions.Length; i++)
                {
                    ChunkWorldPos newChunkPos = new ChunkWorldPos(chunkPositions[i].x * Chunk.chunkSize + playerPos.x, 0, chunkPositions[i].z * Chunk.chunkSize + playerPos.z);

                    Chunk newChunk = world.GetChunk(newChunkPos.x, newChunkPos.y, newChunkPos.z);

                    if (newChunk != null && (newChunk.rendered || buildList.Contains(newChunkPos)))
                    {
                        continue;
                    }

                    for (int y = -1; y < 2; y++)
                    {
                        for (int x = newChunkPos.x - Chunk.chunkSize; x < newChunkPos.x + Chunk.chunkSize; x += Chunk.chunkSize)
                        {
                            for (int z = newChunkPos.z - Chunk.chunkSize; z < newChunkPos.z + Chunk.chunkSize; z += Chunk.chunkSize)
                            {
                                buildList.Add(new ChunkWorldPos(x, y * Chunk.chunkSize, z));
                            }
                        }
                    }
                    return;
                }
            }
        }
        public async override Task Decorate(IWorld world, ChunkWorldPos chunkWorldPos, GeneratorSettings settings)
        {
            await GenerateOre(world, chunkWorldPos, settings);

            var grassGenerator = GrainFactory.GetGrain <IGrassGenerator>(JsonConvert.SerializeObject(new PlantsInfo {
            }));
            await grassGenerator.Generate(world, chunkWorldPos, 10);

            var poppyGenerator = GrainFactory.GetGrain <IFlowersGenerator>(
                JsonConvert.SerializeObject(new PlantsInfo
            {
                PlantType = PlantsType.Poppy
            }));
            await poppyGenerator.Generate(world, chunkWorldPos, 3);

            var dandelionGenerator = GrainFactory.GetGrain <IFlowersGenerator>(
                JsonConvert.SerializeObject(new PlantsInfo
            {
                PlantType = PlantsType.Dandelion
            }));
            await dandelionGenerator.Generate(world, chunkWorldPos, 3);

            var oaktreeGenerator = GrainFactory.GetGrain <ITreeGenerator>(
                JsonConvert.SerializeObject(new PlantsInfo
            {
                PlantType = PlantsType.Oak
            }));
            await oaktreeGenerator.Generate(world, chunkWorldPos, 1);
        }
        public Task <IChunkColumn> GetChunk(ChunkWorldPos pos)
        {
            IWorld world          = AttachedObject.GetWorld();
            var    chunkColumnKey = world.MakeAddressByPartitionKey(new ChunkWorldPos(pos.X, pos.Z));

            return(Task.FromResult(GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey)));
        }
Beispiel #9
0
        public override Task OnActivateAsync()
        {
            var keys = this.GetWorldAndChunkWorldPos();

            World         = GrainFactory.GetGrain <IWorld>(keys.WorldKey);
            ChunkWorldPos = keys.ChunkWorldPos;
            return(base.OnActivateAsync());
        }
Beispiel #10
0
 protected virtual void TrySetBlock(ChunkColumnStorage chunk, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state)
 {
     if (pos.ToChunkWorldPos() == chunkWorldPos)
     {
         BlockChunkPos blockChunkPos = pos.ToBlockChunkPos();
         chunk[blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z] = state;
     }
 }
Beispiel #11
0
        protected virtual Task <BlockState> GetBlock(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos)
        {
            var           chunkColumnKey = world.MakeAddressByPartitionKey(pos.ToChunkWorldPos());
            var           chunkGrain     = GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey);
            BlockChunkPos blockChunkPos  = pos.ToBlockChunkPos();

            return(chunkGrain.GetBlockStateUnsafe(blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z));
        }
Beispiel #12
0
        private Task <int> GetGroundHeight(IWorld world, ChunkWorldPos chunkWorldPos, int x, int z)
        {
            var blockChunkPos = new BlockWorldPos {
                X = x, Z = z
            }.ToBlockChunkPos();
            var chunkColumnKey = world.MakeAddressByPartitionKey(chunkWorldPos);

            return(GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey).GetGroundHeight(blockChunkPos.X, blockChunkPos.Z));
        }
Beispiel #13
0
        protected async virtual Task RandomSetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState block, Random rand, float freq)
        {
            BlockState state = await GetBlock(world, chunkWorldPos, pos);

            if (rand.NextDouble() < freq && state.IsAir())
            {
                await SetBlock(world, chunkWorldPos, pos, block);
            }
        }
Beispiel #14
0
        public async Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state, int size)
        {
            int seed = await world.GetSeed();

            int    oreSeed = pos.X ^ pos.Z ^ seed ^ state.GetHashCode();
            Random random  = new Random(oreSeed);

            await GenerateImpl(world, chunkWorldPos, pos, state, size, random);
        }
Beispiel #15
0
        public override Task OnActivateAsync()
        {
            var keys = this.GetWorldAndChunkWorldPos();

            _world         = GrainFactory.GetGrain <IWorld>(keys.worldKey);
            _chunkPos      = keys.chunkWorldPos;
            _blockEntities = new Dictionary <BlockChunkPos, IBlockEntity>();
            return(Task.CompletedTask);
        }
Beispiel #16
0
        protected async virtual Task SetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, int x, int y, int z, BlockState block)
        {
            BlockState state = await GetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z));

            if (state.IsAir())
            {
                await SetBlock(world, chunkWorldPos, new BlockWorldPos(x, y, z), block);
            }
        }
Beispiel #17
0
        public override async Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos)
        {
            int seed = await world.GetSeed();

            int    treeSeed = pos.X ^ pos.Z ^ seed;
            Random rand     = new Random(treeSeed);

            await GenerateImpl(world, chunkWorldPos, pos, rand);
        }
Beispiel #18
0
        protected async virtual Task SetIfAir(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState block)
        {
            BlockState state = await GetBlock(world, chunkWorldPos, pos);

            if (state.IsAir())
            {
                await SetBlock(world, chunkWorldPos, pos, block);
            }
        }
Beispiel #19
0
 protected async Task SetIfStone(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state)
 {
     if (pos.Y >= 0 &&
         pos.Y < 255 &&
         (await GetBlock(world, chunkWorldPos, pos)) == BlockStates.Stone())
     {
         // replace as ore
         await SetBlock(world, chunkWorldPos, pos, state);
     }
 }
        public Task <BiomeId> GetBlockBiome(BlockWorldPos pos)
        {
            BlockChunkPos blockChunkPos  = pos.ToBlockChunkPos();
            ChunkWorldPos chunkWorldPos  = pos.ToChunkWorldPos();
            IWorld        world          = AttachedObject.GetWorld();
            var           chunkColumnKey = world.MakeAddressByPartitionKey(new ChunkWorldPos(chunkWorldPos.X, chunkWorldPos.Z));

            return(GrainFactory.GetGrain <IChunkColumn>(chunkColumnKey).GetBlockBiome(
                       blockChunkPos.X,
                       blockChunkPos.Z));
        }
        public Task PostChunk(ChunkWorldPos chunkPos, IReadOnlyCollection <IClientboundPacketSink> clients, IReadOnlyCollection <IUserChunkLoader> loaders)
        {
            var stream = GetStreamProvider(StreamProviders.JobsProvider).GetStream <SendChunkJob>(_jobWorkerId, StreamProviders.Namespaces.ChunkSender);

            return(stream.OnNextAsync(new SendChunkJob
            {
                World = GrainFactory.GetGrain <IWorld>(this.GetPrimaryKeyString()),
                ChunkPosition = chunkPos,
                Clients = clients,
                Loaders = loaders
            }));
        }
Beispiel #22
0
        /// <summary>
        /// Updates a chunk if <paramref name="value1"/> and <paramref name="value2"/> are equal
        /// </summary>
        /// <param name="value1">First value to check</param>
        /// <param name="value2">Second value to check</param>
        /// <param name="pos">Position of chunk to update if values are equal</param>
        void UpdateIfEqual(int value1, int value2, ChunkWorldPos pos)
        {
            if (value1 == value2)
            {
                Chunk chunk = GetChunk(pos.x, pos.y, pos.z);

                if (chunk != null)
                {
                    chunk.update = true;
                }
            }
        }
        public override async Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos)
        {
            // TODO use block accessor
            var curBlock = await GetBlock(world, chunkWorldPos, pos);

            var downBlock = await GetBlock(world, chunkWorldPos, new BlockWorldPos { X = pos.X, Y = pos.Y - 1, Z = pos.Z });

            if (curBlock.IsAir() &&
                downBlock == BlockStates.GrassBlock())
            {
                await SetBlock(world, chunkWorldPos, pos, BlockStates.Grass());
            }
        }
Beispiel #24
0
        // 添加生物群系特有的生物
        public override void SpawnMob(IWorld world, IGrainFactory grainFactory, ChunkColumnCompactStorage chunk, Random rand, BlockWorldPos pos)
        {
            ChunkWorldPos chunkPos = pos.ToChunkWorldPos();
            int           seed     = chunkPos.Z * 16384 + chunkPos.X;
            Random        r        = new Random(seed);

            foreach (MobType eachType in _passiveMobList)
            {
                if (r.Next(32) == 0)
                {
                    PassiveMobSpawner spawner = new PassiveMobSpawner(eachType, 15);
                    spawner.Spawn(world, grainFactory, chunk, rand, new BlockWorldPos(pos.X, pos.Y, pos.Z));
                }
            }
        }
Beispiel #25
0
        /// <summary>
        /// Get a <see cref="Block"/> at the given position
        /// </summary>
        /// <param name="hit">Where to get the block from</param>
        /// <param name="adjacent">Should the adjacent <see cref="Block"/> be returned</param>
        /// <returns><see cref="Block"/> at <paramref name="hit.point"/>, Null if no block was found</returns>
        public static Block GetBlock(RaycastHit hit, bool adjacent = false)
        {
            //* checks that a chunk was hit and if it wasnt return early
            Chunk chunk = hit.collider.GetComponent <Chunk>();

            if (chunk == null)
            {
                return(null);
            }

            //* allignes the hit to the block grid and returns the block
            ChunkWorldPos pos = GetBlockPos(hit, adjacent);

            return(chunk.world.GetBlock(pos.x, pos.y, pos.z));
        }
Beispiel #26
0
        // ��������Ⱥϵ���еĹ���
        public virtual void SpawnMonster(IWorld world, IGrainFactory grainFactory, IChunkColumnStorage chunk, Random rand, BlockWorldPos pos)
        {
            ChunkWorldPos chunkPos = pos.ToChunkWorldPos();
            int           seed     = chunkPos.Z * 16384 + chunkPos.X;
            Random        r        = new Random(seed);

            foreach (MobType eachType in _monsterList)
            {
                if (r.Next(64) == 0)
                {
                    MonsterSpawner spawner = new MonsterSpawner(eachType, 3);
                    spawner.Spawn(world, grainFactory, chunk, rand, new BlockWorldPos(pos.X, pos.Y, pos.Z));
                }
            }
        }
Beispiel #27
0
        private async Task <bool> StreamChunk(ChunkWorldPos chunkPos)
        {
            var trunkSender = GrainFactory.GetGrain <IChunkSender>(_world.GetPrimaryKeyString());

            if (!_sentChunks.Contains(chunkPos) && _sendingChunks.Add(chunkPos))
            {
                await trunkSender.PostChunk(chunkPos, new[] { _sink }, new[] { this.AsReference <IUserChunkLoader>() });

                await GrainFactory.GetGrain <IChunkTrackingHub>(_world.MakeAddressByPartitionKey(chunkPos)).Subscribe(_player);

                return(true);
            }

            return(false);
        }
Beispiel #28
0
        public async Task <bool> CanTreeGrow(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, int height)
        {
            bool result = true;

            // 检查所有方块可替换
            for (int y = pos.Y; y <= pos.Y + 1 + height; ++y)
            {
                int xzSize = 1;

                // 底端
                if (y == pos.Y)
                {
                    xzSize = 0;
                }

                // 顶端
                if (y >= pos.Y + height - 1)
                {
                    xzSize = 2;
                }

                // 检查这个平面所有方块可替换
                for (int x = pos.X - xzSize; x <= pos.X + xzSize && result; ++x)
                {
                    for (int z = pos.Z - xzSize; z <= pos.Z + xzSize && result; ++z)
                    {
                        if (y >= 0 && y < 256)
                        {
                            var        checkPos = new BlockWorldPos(x, y, z);
                            BlockState state    = await GetBlock(world, chunkWorldPos, checkPos);

                            if (!state.IsAir() &&
                                !state.IsSameId(BlockStates.Leaves()) &&
                                !state.IsSameId(BlockStates.Leaves2()))
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }
Beispiel #29
0
        /// <summary>
        /// Gets a chunk at eh given x, y, z
        /// </summary>
        /// <param name="x">X pos of the chunk</param>
        /// <param name="y">Y pos of the chunk</param>
        /// <param name="z">Z pos of the chunk</param>
        /// <returns><see cref="Chunk"/> at given x, y, z</returns>
        public Chunk GetChunk(int x, int y, int z)
        {
            float multiple = Chunk.chunkSize;
            //* rounds the given x, y, z to a multiple of 16 as chunks are 16x16x16 in size
            ChunkWorldPos pos = new ChunkWorldPos()
            {
                x = Mathf.FloorToInt(x / multiple) * Chunk.chunkSize,
                y = Mathf.FloorToInt(y / multiple) * Chunk.chunkSize,
                z = Mathf.FloorToInt(z / multiple) * Chunk.chunkSize
            };

            //* gets the chunk if it exists
            chunks.TryGetValue(pos, out Chunk chunk);
            //* if the chunk does not exist will return null
            return(chunk);
        }
Beispiel #30
0
        public virtual async Task Generate(IWorld world, ChunkWorldPos pos, int countPerChunk)
        {
            int seed = await world.GetSeed();

            BlockWorldPos curChunkCorner = pos.ToBlockWorldPos();

            int    chunkSeed     = pos.X ^ pos.Z ^ seed ^ this.GetType().GetHashCode() ^ this.GetPrimaryKeyString().GetHashCode();
            Random rand          = new Random(chunkSeed);
            int    countCurChunk = rand.Next(countPerChunk + 1);

            for (int count = 0; count < countCurChunk; ++count)
            {
                int x            = curChunkCorner.X + rand.Next(16);
                int z            = curChunkCorner.Z + rand.Next(16);
                int groundHeight = await GetGroundHeight(world, pos, x, z);
                await GenerateSingle(world, pos, new BlockWorldPos { X = x, Y = groundHeight, Z = z });
            }
        }