internal void SpawnStack(EntityStack stack) { PositionChunk positionChunk = PositionChunk.CreateFrom(stack.Position); Chunk chunk = GetChunk(positionChunk); chunk.AddEntity(stack); }
internal List <ChunkColumn> AllNeighborColumns(ChunkColumn chunkColumn) { Vector2[] deltas = new Vector2[] { new Vector2(-1, -1), new Vector2(0, -1), new Vector2(1, -1), new Vector2(-1, 0), new Vector2(1, 0), new Vector2(-1, 1), new Vector2(0, 1), new Vector2(1, 1), }; List <ChunkColumn> neighbors = new List <ChunkColumn>(); foreach (Vector2 delta in deltas) { PositionChunk chunkPos = new PositionChunk(chunkColumn.Position.X + (int)delta.X, 0, chunkColumn.Position.Z + (int)delta.Y); if (ChunkColumns.ContainsKey(chunkPos.Key)) { neighbors.Add(ChunkColumns[chunkPos.Key]); } else { neighbors.Add(null); } } return(neighbors); }
private void ChangeChunk(int x, int y, int z) { PositionChunk positionChunk = PositionChunk.CreateFrom(new PositionBlock(x, y, z)); chunkCache = World.Instance.GetCachedChunks(); chunk = chunkCache.GetChunk(positionChunk); chunk.Position.GetMinCornerBlock(out chunkCorner); }
internal void SetBlock(PositionBlock pos, int blockId) { PositionChunk positionChunk = PositionChunk.CreateFrom(pos); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref pos); chunk.SetLocalBlock(pos.X, pos.Y, pos.Z, blockId); }
internal Chunk GetChunk(PositionChunk positionChunk) { if (chunks.ContainsKey(positionChunk.Key)) { return(chunks[positionChunk.Key]); } return(null); }
internal Entity GetBlockEntity(PositionBlock position) { PositionChunk positionChunk = PositionChunk.CreateFrom(position); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref position); Entity entity = chunk.GetBlockEntity(position); return(entity); }
internal Chunk GetChunk(PositionChunk positionChunk) { Chunk chunk = storage.GetChunk(positionChunk); if (chunk == null) { chunk = new Chunk(); chunk.Position = positionChunk; storage.AddChunk(chunk); } return(chunk); }
internal override void OnDestroy(PositionBlock pos) { Chunk chunk = World.Instance.GetChunk(PositionChunk.CreateFrom(pos)); PositionBlock localpos = pos; chunk.Position.ConvertToLocalPosition(ref localpos); float stage = (float)chunk.GetBlockMetaData(localpos, "stage"); if (stage != 1f) { DropStack(new EntityStack(ItemRepository.SeedsWheat.Id, 1), pos); return; } base.OnDestroy(pos); }
internal object GetBlockMetaData(PositionBlock pos, string variable) { if (pos.Y < 0) { return(null); } if (pos.Y >= Chunk.MaxSizeY) { return(null); } PositionChunk positionChunk = PositionChunk.CreateFrom(pos); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref pos); return(chunk.GetBlockMetaData(pos, variable)); }
internal void SetBlockMetaData(PositionBlock pos, string variable, object value) { if (pos.Y < 0) { return; } if (pos.Y >= Chunk.MaxSizeY) { return; } PositionChunk positionChunk = PositionChunk.CreateFrom(pos); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref pos); chunk.SetBlockMetaData(pos, variable, value); }
internal Entity GetBlockEntityFromPosition(PositionBlock pos) { if (pos.Y < 0) { return(null); } if (pos.Y >= Chunk.MaxSizeY) { return(null); } PositionChunk positionChunk = PositionChunk.CreateFrom(pos); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref pos); return(chunk.GetBlockEntityFromPosition(pos)); }
private ChunkColumn GetChunkColumn(PositionChunk chunkPos) { PositionChunk columnPos = new PositionChunk(chunkPos.X, 0, chunkPos.Z); ChunkColumn column; if (ChunkColumns.ContainsKey(columnPos.Key)) { column = ChunkColumns[columnPos.Key]; } else { column = new ChunkColumn(columnPos.X, columnPos.Z); ChunkColumns.Add(columnPos.Key, column); column.InitializeStage(); } column.Active = true; return(column); }
internal int GetBlock(PositionBlock pos) { if (pos.Y < 0) { return(0); } if (pos.Y >= Chunk.MaxSizeY) { return(0); } PositionChunk positionChunk = PositionChunk.CreateFrom(pos); Chunk chunk = GetChunk(positionChunk); positionChunk.ConvertToLocalPosition(ref pos); int blockId = chunk.GetLocalBlock(pos.X, pos.Y, pos.Z); return(blockId); }
internal List<ChunkColumn> AllNeighborColumns(ChunkColumn chunkColumn) { Vector2[] deltas = new Vector2[] { new Vector2(-1,-1), new Vector2(0,-1), new Vector2(1,-1), new Vector2(-1,0), new Vector2(1,0), new Vector2(-1,1), new Vector2(0,1), new Vector2(1,1), }; List<ChunkColumn> neighbors = new List<ChunkColumn>(); foreach (Vector2 delta in deltas) { PositionChunk chunkPos = new PositionChunk(chunkColumn.Position.X + (int)delta.X, 0, chunkColumn.Position.Z + (int)delta.Y); if (ChunkColumns.ContainsKey(chunkPos.Key)) neighbors.Add(ChunkColumns[chunkPos.Key]); else neighbors.Add(null); } return neighbors; }
public ChunkColumn(int x, int z) { Position = new PositionChunk(x, 0, z); }
internal void Update(Vector3 centerPos) { float chunkRadius = (int)((GameSettings.CachingRadius) / 16f); float chunkRadiusSquared = chunkRadius * chunkRadius; Vector3 centerBlockPos = new Vector3( MathLibrary.FloorToWorldGrid(centerPos.X), MathLibrary.FloorToWorldGrid(centerPos.Y), MathLibrary.FloorToWorldGrid(centerPos.Z)); if (centerBlockPos.Y > Chunk.MaxSizeY - 1) { centerBlockPos.Y = Chunk.MaxSizeY - 1; } else if (centerBlockPos.Y < 0) { centerBlockPos.Y = 0; } PositionChunk centerChunk = PositionChunk.CreateFrom(centerBlockPos); PositionChunk minChunk = new PositionChunk(centerChunk.X - (int)chunkRadius, 0, centerChunk.Z - (int)chunkRadius); PositionChunk maxChunk = new PositionChunk(centerChunk.X + (int)chunkRadius, Chunk.MaxSizeY / 16 - 1, centerChunk.Z + (int)chunkRadius); // add all chunks within blockradius if (!centerChunk.SameAs(LastCenterChunk)) { // update the cache for (int x = minChunk.X; x <= maxChunk.X; x++) { for (int z = minChunk.Z; z <= maxChunk.Z; z++) { int dx = x - centerChunk.X; int dz = z - centerChunk.Z; double chunkCurrentDistSquared = dx * dx + dz * dz; if (chunkCurrentDistSquared > chunkRadiusSquared) { continue; } for (int y = minChunk.Y; y <= maxChunk.Y; y++) { Chunk chunk = World.Instance.GetChunk(new PositionChunk(x, y, z)); if (!cachedChunks.ContainsKey(chunk.Position.Key)) { cachedChunks.Add(chunk.Position.Key, chunk); } } } } OrderedChunks = cachedChunks.Values.Where(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return(dx * dx + dz * dz <= chunkRadiusSquared); }).OrderBy(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return(dx * dx + dz * dz); }).ThenBy(c => { float dy = c.Position.Y - centerChunk.Y; return(dy * dy); }).ToList(); IsDirty = true; } // update chunks... bool allowHeavyTask = true; foreach (var column in ChunkColumns.Values) { column.Active = false; } foreach (Chunk chunk in OrderedChunks) { chunk.Column = GetChunkColumn(chunk.Position); chunk.HeavyTaskAllowed = allowHeavyTask; chunk.Update(); if (chunk.HeavyTaskExecuted) { allowHeavyTask = false; } // relocate entities foreach (EntityStack stack in chunk.StackEntities.ToArray()) { PositionChunk destChunk = PositionChunk.CreateFrom(stack.Position); if (!chunk.Position.SameAs(destChunk)) { // relocate chunk.RemoveEntity(stack); if (cachedChunks.ContainsKey(destChunk.Key)) { cachedChunks[destChunk.Key].AddEntity(stack); } } } } // dispose and remove expired chunks var expiredChunks = cachedChunks.Where(pair => pair.Value.Expired).ToList(); expiredChunks.ForEach(pair => { pair.Value.Dipose(); cachedChunks.Remove(pair.Key); }); // remove unused columnds var columnsToRemove = ChunkColumns.Where(pair => pair.Value.Active == false).ToList(); columnsToRemove.ForEach(pair => { ChunkColumns.Remove(pair.Key); }); LastCenterChunk = centerChunk; }
internal void ProfilerSnapshot() { VertexBuffer.Dispose(ref profileVertexBuffer); t.ResetTransformation(); FontRenderer f = FontRenderer.Instance; Player player = World.Instance.Player; f.BeginBatch(); f.CharScale = 1; string report = p.Report(); float y = TheGame.Instance.Height - FontRenderer.Instance.LineHeight; using (StringReader sr = new StringReader(report)) { string line; while ((line = sr.ReadLine()) != null) { f.RenderTextShadow(line, 0, y); y -= f.LineHeight; } } // log... y -= f.LineHeight; if (World.Instance.PlayerVoxelTrace.Hit) { Vector4 impactpos = World.Instance.PlayerVoxelTrace.ImpactPosition; string line = string.Format(GetVectorAsString("impactpos", impactpos)); f.RenderTextShadow(line, 0, y); y -= f.LineHeight; } else { f.RenderTextShadow("impactpos", 0, y); y -= f.LineHeight; Vector3 pos = new Vector3(player.Position.X, player.Position.Y, player.Position.Z); if (pos.Y > Chunk.MaxSizeY - 1) { pos.Y = Chunk.MaxSizeY - 1; } else if (pos.Y < 0) { pos.Y = 0; } PositionChunk chunkPos = PositionChunk.CreateFrom(pos); Vector3 chunkPos3 = new Vector3(chunkPos.X, chunkPos.Y, chunkPos.Z); f.RenderTextShadow(string.Format(GetVectorAsString("chunkpos", chunkPos3)), 0, y); y -= f.LineHeight; ChunkCache cache = World.Instance.GetCachedChunks(); Chunk c = cache.GetChunk(chunkPos); if (c != null) { f.RenderTextShadow(string.Format("chunk.Stage = {0}", c.Stage.ToString()), 0, y); y -= f.LineHeight; f.RenderTextShadow(string.Format("chunk.col.stage = {0}", c.Column.Stage.ToString()), 0, y); y -= f.LineHeight; f.RenderTextShadow(string.Format("chunk.col.active = {0}", c.Column.Active.ToString()), 0, y); y -= f.LineHeight; f.RenderTextShadow(string.Format("cache.alleighbors= {0}", cache.AllNeighborColumns(c.Column).Where(cc => cc != null).Count()), 0, y); y -= f.LineHeight; List <Chunk> chunks = new List <Chunk>(); for (int i = 0; i < 8; i++) { chunks.Add(cache.GetChunk(new PositionChunk(c.Position.X, i, c.Position.Z))); } } } f.RenderTextShadow(GetVectorAsString("direction", player.Direction), 0, y); y -= f.LineHeight; f.RenderTextShadow(GetVectorAsString("position", player.Position), 0, y); y -= f.LineHeight; y -= f.LineHeight; string[] lastLines = Log.Instance.Last(70); foreach (string line in lastLines) { f.RenderTextShadow(line, 0, y); y -= f.LineHeight; } f.StopBatch(); profileVertexBuffer = t.GetVertexBuffer(); }
private ChunkColumn GetChunkColumn(PositionChunk chunkPos) { PositionChunk columnPos = new PositionChunk(chunkPos.X, 0, chunkPos.Z); ChunkColumn column; if (ChunkColumns.ContainsKey(columnPos.Key)) { column = ChunkColumns[columnPos.Key]; } else { column = new ChunkColumn(columnPos.X, columnPos.Z); ChunkColumns.Add(columnPos.Key, column); column.InitializeStage(); } column.Active = true; return column; }
internal Chunk GetChunk(PositionChunk positionChunk) { if (!cachedChunks.ContainsKey(positionChunk.Key)) return null; return cachedChunks[positionChunk.Key]; }
internal void Update(Vector3 centerPos) { float chunkRadius = (int)((GameSettings.CachingRadius) / 16f); float chunkRadiusSquared = chunkRadius * chunkRadius; Vector3 centerBlockPos = new Vector3( MathLibrary.FloorToWorldGrid(centerPos.X), MathLibrary.FloorToWorldGrid(centerPos.Y), MathLibrary.FloorToWorldGrid(centerPos.Z)); if (centerBlockPos.Y > Chunk.MaxSizeY - 1) centerBlockPos.Y = Chunk.MaxSizeY - 1; else if (centerBlockPos.Y < 0) centerBlockPos.Y = 0; PositionChunk centerChunk = PositionChunk.CreateFrom(centerBlockPos); PositionChunk minChunk = new PositionChunk(centerChunk.X - (int)chunkRadius, 0, centerChunk.Z - (int)chunkRadius); PositionChunk maxChunk = new PositionChunk(centerChunk.X + (int)chunkRadius, Chunk.MaxSizeY / 16 - 1, centerChunk.Z + (int)chunkRadius); // add all chunks within blockradius if (!centerChunk.SameAs(LastCenterChunk)) { // update the cache for (int x = minChunk.X; x <= maxChunk.X; x++) { for (int z = minChunk.Z; z <= maxChunk.Z; z++) { int dx = x - centerChunk.X; int dz = z - centerChunk.Z; double chunkCurrentDistSquared = dx * dx + dz * dz; if (chunkCurrentDistSquared > chunkRadiusSquared) continue; for (int y = minChunk.Y; y <= maxChunk.Y; y++) { Chunk chunk = World.Instance.GetChunk(new PositionChunk(x, y, z)); if (!cachedChunks.ContainsKey(chunk.Position.Key)) { cachedChunks.Add(chunk.Position.Key, chunk); } } } } OrderedChunks = cachedChunks.Values.Where(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return dx * dx + dz * dz <= chunkRadiusSquared; }).OrderBy(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return dx * dx + dz * dz; }).ThenBy(c => { float dy = c.Position.Y - centerChunk.Y; return dy * dy; }).ToList(); IsDirty = true; } // update chunks... bool allowHeavyTask = true; foreach (var column in ChunkColumns.Values) { column.Active = false; } foreach (Chunk chunk in OrderedChunks) { chunk.Column = GetChunkColumn(chunk.Position); chunk.HeavyTaskAllowed = allowHeavyTask; chunk.Update(); if (chunk.HeavyTaskExecuted) allowHeavyTask = false; // relocate entities foreach (EntityStack stack in chunk.StackEntities.ToArray()) { PositionChunk destChunk = PositionChunk.CreateFrom(stack.Position); if (!chunk.Position.SameAs(destChunk)) { // relocate chunk.RemoveEntity(stack); if (cachedChunks.ContainsKey(destChunk.Key)) { cachedChunks[destChunk.Key].AddEntity(stack); } } } } // dispose and remove expired chunks var expiredChunks = cachedChunks.Where(pair => pair.Value.Expired).ToList(); expiredChunks.ForEach(pair => { pair.Value.Dipose(); cachedChunks.Remove(pair.Key); }); // remove unused columnds var columnsToRemove = ChunkColumns.Where(pair => pair.Value.Active == false).ToList(); columnsToRemove.ForEach(pair => { ChunkColumns.Remove(pair.Key); }); LastCenterChunk = centerChunk; }
internal Chunk GetChunk(PositionChunk positionChunk) { Chunk chunk = storage.GetChunk(positionChunk); if (chunk == null) { chunk = new Chunk(); chunk.Position = positionChunk; storage.AddChunk(chunk); } return chunk; }
private void CollectNearbyEntities() { if (throwStackDelay > 0) { throwStackDelay--; return; } AxisAlignedBoundingBox collectArea = AABB; collectArea.Translate(Position); float radius = 0.5f; collectArea.Min -= new Vector3(radius, radius, radius); collectArea.Max += new Vector3(radius, radius, radius); collectArea.CapToWorldBounds(); PositionChunk minChunk = PositionChunk.CreateFrom(collectArea.Min); PositionChunk maxChunk = PositionChunk.CreateFrom(collectArea.Max); PositionChunk chunkPos; for (int x = minChunk.X; x <= maxChunk.X; x++) { for (int y = minChunk.Y; y <= maxChunk.Y; y++) { for (int z = minChunk.Z; z <= maxChunk.Z; z++) { chunkPos = new PositionChunk(x, y, z); Chunk chunk = World.Instance.GetChunk(chunkPos); foreach (EntityStack stack in chunk.EntitiesInArea(collectArea)) { // transfer items Inventory.CollectStack(stack); // if stack is empty remove it if (stack.IsEmpty) { chunk.RemoveEntity(stack); } } } } } }