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; } } }
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); } }
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))); }
public override Task OnActivateAsync() { var keys = this.GetWorldAndChunkWorldPos(); World = GrainFactory.GetGrain <IWorld>(keys.WorldKey); ChunkWorldPos = keys.ChunkWorldPos; return(base.OnActivateAsync()); }
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; } }
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)); }
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)); }
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); } }
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); }
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); }
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); } }
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); }
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); } }
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 })); }
/// <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()); } }
// 添加生物群系特有的生物 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)); } } }
/// <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)); }
// ��������Ⱥϵ���еĹ��� 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)); } } }
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); }
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); }
/// <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); }
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 }); } }