private void PeerNetwork_LatestBlockReceived(object sender, BlockEventArgs e) { IBlockDefinition lastReceivedBlock = null; IBlockDefinition lastLocalBlock = OnGetLatestBlock(); if (e.Block == null) { return; } else { lastReceivedBlock = e.Block; } if (lastReceivedBlock.Index > lastLocalBlock.Index) { if (lastReceivedBlock.PreviousHash == lastLocalBlock.Hash) { OnAddBlockToChain(lastReceivedBlock); } else { // received a Block with higher index and the previous hash dosent match the current hash from local => our local chain is out of date peerNetwork.FullBlockchainRequest(Chain); } } else { // our local blockchain is longer then the received // longer blockchain wins we do nothing } }
public bool ValidateNewBlock(IBlockDefinition oldBlock, IBlockDefinition newBlock) { if (newBlock.Index == Configuration.CurrentSettings.NullNumberValue || newBlock.Index == oldBlock.Index) { return(false); } if (newBlock.TimeStamp == Configuration.CurrentSettings.NullDatetimeValue || !OnValidateTimeStampOffset(newBlock.TimeStamp, oldBlock.TimeStamp)) { return(false); } if (newBlock.Difficulty == Configuration.CurrentSettings.NullNumberValue) { return(false); } if (newBlock.Nonce == Configuration.CurrentSettings.NullNumberValue) { return(false); } if (CalculateHash(newBlock) != newBlock.Hash) { return(false); } if (!HashMatchesDifficulty(newBlock.Hash, newBlock.Difficulty)) { return(false); } return(true); }
private bool OnAddBlockToChain(IBlockDefinition newBlock) { if (blockValidation.ValidateNewBlock(OnGetLatestBlock(), newBlock)) { Chain.Add(newBlock); return(true); } return(false); }
private int OnGetDifficulty() { IBlockDefinition lastBlock = OnGetLatestBlock(); if (lastBlock.Index % Configuration.CurrentSettings.DifficultyAdjustmentInterval == 0 && lastBlock.Index != 0) { return(OnGetAdjustedDifficulty()); } else { return(lastBlock.Difficulty); } }
public Nothing BlockDefinition(IBlockDefinition codeElement) { var owner = GetOwner(); foreach (var entry in codeElement.Scope.Members.Values.Select(x => x.Value)) { lookup.AddLocal(owner, entry); } var next = Push(codeElement); next.Walk(codeElement.Body); return(new Nothing()); }
public IInterpetedOperation <IInterpetedAnyType> BlockDefinition(IBlockDefinition codeElement) { if (backing.TryGetValue(codeElement, out var res)) { return(res); } else { var op = new InterpetedBlockDefinition(); backing.Add(codeElement, op); op.Init( codeElement.Body.Select(x => x.Convert(this)).ToArray(), new InterpetedScopeTemplate(codeElement.Scope, codeElement.Scope.ToVerifiableType())); return(op); } }
private IBlockDefinition OnFindBlock(IBlockDefinition blockDefinition) { int nonce = 0; while (true) { blockDefinition.Nonce = nonce; string hash = this.blockValidation.CalculateHash(blockDefinition); if (this.blockValidation.HashMatchesDifficulty(hash, blockDefinition.Difficulty)) { blockDefinition.Hash = hash; return(blockDefinition); } nonce++; } }
public IReadOnlyList <IMemberDefinition> BlockDefinition(IBlockDefinition codeElement) { UpdateDefinedBy(codeElement.Scope, OrType.Make <IInternalMethodDefinition, IImplementationDefinition, IEntryPointDefinition, IBlockDefinition, IRootScope, IObjectDefiniton>(codeElement)); var implementationClosure = Walk(codeElement.Body); return(implementationClosure .Except(staticMembers) .Except(codeElement.Scope.Members.Select(x => x.Value.Value)).ToArray()); // TODO BLOCKS DONT NEED CLOSURES //return extensionLookup.blockLookup.GetOrAdd(codeElement,()=> { // var implementationClosure = Walk(codeElement.Body, extensionLookup); // return new ClosureLookup(implementationClosure // .Except(codeElement.Scope.Members.Select(x => x.Value.Value)).ToArray()); //}).closureMember; }
public IChunkColumn GenerateColumn(IDefinitionManager definitionManager, IPlanet planet, Index2 index) { IDefinition[] definitions = definitionManager.GetDefinitions().ToArray(); IBlockDefinition sandDefinition = definitions.OfType <SandBlockDefinition>().First(); ushort sandIndex = (ushort)(Array.IndexOf(definitions.ToArray(), sandDefinition) + 1); IChunk[] result = new IChunk[planet.Size.Z]; ChunkColumn column = new ChunkColumn(result, planet.Id, index); for (int layer = 0; layer < planet.Size.Z; layer++) { result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); } int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = z / Chunk.CHUNKSIZE_Z; result[layer].SetBlock(x, y, block, sandIndex); } } } } column.CalculateHeights(); return(column); }
private int OnGetAdjustedDifficulty() { IBlockDefinition lastBlock = OnGetLatestBlock(); IBlockDefinition prevAdjustmentBlock = Chain[Chain.Count - Configuration.CurrentSettings.DifficultyAdjustmentInterval]; double timeExpected = Configuration.CurrentSettings.BlockGenerationInterval * Configuration.CurrentSettings.DifficultyAdjustmentInterval; double timeTaken = (lastBlock.TimeStamp - prevAdjustmentBlock.TimeStamp).TotalMinutes; if (timeTaken < timeExpected / 2) { return(prevAdjustmentBlock.Difficulty + 1); } else if (timeTaken > timeExpected * 2) { return(prevAdjustmentBlock.Difficulty - 1); } else { return(prevAdjustmentBlock.Difficulty); } }
public IBlockDefinition GenerateBlock(IBlockData blockData = null) { IBlockDefinition previousBlock = OnGetLatestBlock(); IBlockDefinition block = new Block { PreviousHash = previousBlock.Hash, Difficulty = OnGetDifficulty(), Index = previousBlock.Index + 1, TimeStamp = DateTime.UtcNow, Data = blockData }; IBlockDefinition newBlock = OnFindBlock(block); if (OnAddBlockToChain(newBlock)) { peerNetwork.LatestBlockBroadcast(newBlock); return(newBlock); } return(null); }
public IChunk[] GenerateChunk(IEnumerable <IBlockDefinition> blockDefinitions, IPlanet planet, Index2 index) { IBlockDefinition sandDefinition = blockDefinitions.FirstOrDefault(d => typeof(SandBlockDefinition) == d.GetType()); ushort sandIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), sandDefinition) + 1); IChunk[] result = new IChunk[planet.Size.Z]; for (int layer = 0; layer < planet.Size.Z; layer++) { result[layer] = new Chunk(new Index3(index.X, index.Y, layer), planet.Id); } int part = (planet.Size.Z * Chunk.CHUNKSIZE_Z) / 4; for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { float heightY = (float)Math.Sin((float)(y * Math.PI) / 15f); for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { float heightX = (float)Math.Sin((float)(x * Math.PI) / 18f); float height = ((heightX + heightY + 2) / 4) * (2 * part); for (int z = 0; z < planet.Size.Z * Chunk.CHUNKSIZE_Z; z++) { if (z < (int)(height + part)) { int block = z % (Chunk.CHUNKSIZE_Z); int layer = (int)(z / Chunk.CHUNKSIZE_Z); result[layer].SetBlock(x, y, block, sandIndex); } } } } return(result); }
protected override void UpdateEntity(GameTime gameTime, Entity entity, ControllableComponent controller, InventoryComponent inventory) { var toolbar = entity.Components.GetComponent <ToolBarComponent>(); var cache = entity.Components.GetComponent <LocalChunkCacheComponent>().LocalChunkCache; if (controller.InteractBlock.HasValue) { ushort lastBlock = cache.GetBlock(controller.InteractBlock.Value); cache.SetBlock(controller.InteractBlock.Value, 0); if (lastBlock != 0) { var blockDefinition = simulation.ResourceManager.DefinitionManager.GetDefinitionByIndex(lastBlock); if (blockDefinition is IInventoryableDefinition invDef) { inventory.AddUnit(invDef); } } controller.InteractBlock = null; } if (toolbar != null && controller.ApplyBlock.HasValue) { if (toolbar.ActiveTool != null) { Index3 add = new Index3(); switch (controller.ApplySide) { case OrientationFlags.SideWest: add = new Index3(-1, 0, 0); break; case OrientationFlags.SideEast: add = new Index3(1, 0, 0); break; case OrientationFlags.SideSouth: add = new Index3(0, -1, 0); break; case OrientationFlags.SideNorth: add = new Index3(0, 1, 0); break; case OrientationFlags.SideBottom: add = new Index3(0, 0, -1); break; case OrientationFlags.SideTop: add = new Index3(0, 0, 1); break; } if (toolbar.ActiveTool.Definition is IBlockDefinition) { IBlockDefinition definition = toolbar.ActiveTool.Definition as IBlockDefinition; Index3 idx = controller.ApplyBlock.Value + add; var boxes = definition.GetCollisionBoxes(cache, idx.X, idx.Y, idx.Z); bool intersects = false; var positioncomponent = entity.Components.GetComponent <PositionComponent>(); var bodycomponent = entity.Components.GetComponent <BodyComponent>(); if (positioncomponent != null && bodycomponent != null) { float gap = 0.01f; var playerBox = new BoundingBox( new Vector3( positioncomponent.Position.GlobalBlockIndex.X + positioncomponent.Position.BlockPosition.X - bodycomponent.Radius + gap, positioncomponent.Position.GlobalBlockIndex.Y + positioncomponent.Position.BlockPosition.Y - bodycomponent.Radius + gap, positioncomponent.Position.GlobalBlockIndex.Z + positioncomponent.Position.BlockPosition.Z + gap), new Vector3( positioncomponent.Position.GlobalBlockIndex.X + positioncomponent.Position.BlockPosition.X + bodycomponent.Radius - gap, positioncomponent.Position.GlobalBlockIndex.Y + positioncomponent.Position.BlockPosition.Y + bodycomponent.Radius - gap, positioncomponent.Position.GlobalBlockIndex.Z + positioncomponent.Position.BlockPosition.Z + bodycomponent.Height - gap) ); // Nicht in sich selbst reinbauen foreach (var box in boxes) { var newBox = new BoundingBox(idx + box.Min, idx + box.Max); if (newBox.Min.X < playerBox.Max.X && newBox.Max.X > playerBox.Min.X && newBox.Min.Y < playerBox.Max.Y && newBox.Max.X > playerBox.Min.Y && newBox.Min.Z < playerBox.Max.Z && newBox.Max.X > playerBox.Min.Z) { intersects = true; } } } if (!intersects) { if (inventory.RemoveUnit(toolbar.ActiveTool)) { cache.SetBlock(idx, simulation.ResourceManager.DefinitionManager.GetDefinitionIndex(definition)); cache.SetBlockMeta(idx, (int)controller.ApplySide); if (toolbar.ActiveTool.Amount <= 0) { toolbar.RemoveSlot(toolbar.ActiveTool); } } } } } controller.ApplyBlock = null; } }
/// <summary> /// Geplante Methode, mit der der Block auf Interaktion von aussen reagieren kann. /// </summary> /// <param name="block">Der Block-Typ des interagierenden Elements</param> /// <param name="itemProperties">Die physikalischen Parameter des interagierenden Elements</param> public abstract void Hit(IBlockDefinition block, PhysicalProperties itemProperties);
public bool RegenerateVertexBuffer() { if (!ChunkPosition.HasValue) { return(false); } // Chunk nachladen if (this.chunk == null) { this.chunk = _manager.GetChunk(ChunkPosition.Value); if (this.chunk == null) { //Thread.Sleep(10); //RegenerateVertexBuffer(); //NeedsUpdate = false; return(false); } this.chunk.Changed += OnChunkChanged; } var chunk = this.chunk; List <VertexPositionNormalTextureLight> vertices = new List <VertexPositionNormalTextureLight>(); int textureColumns = textures.Width / SceneControl.TEXTURESIZE; float textureWidth = 1f / textureColumns; float texelSize = 1f / SceneControl.TEXTURESIZE; float textureSizeGap = texelSize; float textureGap = texelSize / 2; // BlockTypes sammlen Dictionary <IBlockDefinition, int> textureOffsets = new Dictionary <IBlockDefinition, int>(); // Dictionary<Type, BlockDefinition> definitionMapping = new Dictionary<Type, BlockDefinition>(); int definitionIndex = 0; foreach (var definition in definitionManager.GetBlockDefinitions()) { int textureCount = definition.Textures.Count(); textureOffsets.Add(definition, definitionIndex); // definitionMapping.Add(definition.GetBlockType(), definition); definitionIndex += textureCount; } Vector2[] uvOffsets = new[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) }; for (int z = 0; z < Chunk.CHUNKSIZE_Z; z++) { for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { ushort block = chunk.GetBlock(x, y, z); if (block == 0) { continue; } IBlockDefinition blockDefinition = (IBlockDefinition)definitionManager.GetDefinitionByIndex(block); if (blockDefinition == null) { continue; } int textureIndex; if (!textureOffsets.TryGetValue(blockDefinition, out textureIndex)) { continue; } // Textur-Koordinate "berechnen" Vector2 textureOffset = new Vector2(); //Vector2 textureSize = new Vector2(textureWidth - textureSizeGap, textureWidth - textureSizeGap); ushort topBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z + 1)); IBlockDefinition topBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(topBlock); var globalX = x + chunk.Index.X * Chunk.CHUNKSIZE_X; var globalY = y + chunk.Index.Y * Chunk.CHUNKSIZE_Y; var globalZ = z + chunk.Index.Z * Chunk.CHUNKSIZE_Z; // Top if (topBlock == 0 || (!topBlockDefintion.IsSolidWall(Wall.Bottom) && topBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTextureRotation(Wall.Top, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 0, 1), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 0, 1), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 1), new Vector3(0, 0, 1), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 1), new Vector3(0, 0, 1), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Top, _manager, globalX, globalY, globalZ)), 0)); } ushort bottomBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z - 1)); IBlockDefinition bottomBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(bottomBlock); // Unten if (bottomBlock == 0 || (!bottomBlockDefintion.IsSolidWall(Wall.Top) && bottomBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTextureRotation(Wall.Bottom, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 0, -1), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 0, -1), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 0), new Vector3(0, 0, -1), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 0), new Vector3(0, 0, -1), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Bottom, _manager, globalX, globalY, globalZ)), 0)); } ushort southBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y + 1, z)); IBlockDefinition southBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(southBlock); // South if (southBlock == 0 || (!southBlockDefintion.IsSolidWall(Wall.Front) && southBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTextureRotation(Wall.Front, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 1, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 1, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 1, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 1, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Front, _manager, globalX, globalY, globalZ)), 0)); } ushort northBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y - 1, z)); IBlockDefinition northBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(northBlock); // North if (northBlock == 0 || (!northBlockDefintion.IsSolidWall(Wall.Back) && northBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ) / textureColumns) * textureWidth) + textureGap)); int rotation = -blockDefinition.GetTextureRotation(Wall.Back, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 1), new Vector3(0, -1, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 1), new Vector3(0, -1, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 0), new Vector3(0, -1, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 0), new Vector3(0, -1, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Back, _manager, globalX, globalY, globalZ)), 0)); } ushort westBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x - 1, y, z)); IBlockDefinition westBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(westBlock); // West if (westBlock == 0 || (!westBlockDefintion.IsSolidWall(Wall.Right) && westBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTextureRotation(Wall.Left, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 0), new Vector3(-1, 0, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 1, z + 1), new Vector3(-1, 0, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 0), new Vector3(-1, 0, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 0, y + 0, z + 1), new Vector3(-1, 0, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Left, _manager, globalX, globalY, globalZ)), 0)); } ushort eastBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x + 1, y, z)); IBlockDefinition eastBlockDefintion = (IBlockDefinition)definitionManager.GetDefinitionByIndex(eastBlock); // Ost if (eastBlock == 0 || (!eastBlockDefintion.IsSolidWall(Wall.Left) && eastBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTextureRotation(Wall.Right, _manager, globalX, globalY, globalZ); int localOffset = vertices.Count; vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 1), new Vector3(1, 0, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 1, z + 0), new Vector3(1, 0, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 1), new Vector3(1, 0, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)), 0)); vertices.Add( new VertexPositionNormalTextureLight( new Vector3(x + 1, y + 0, z + 0), new Vector3(1, 0, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTextureIndex(Wall.Right, _manager, globalX, globalY, globalZ)), 0)); } } } } vertexCount = vertices.Count; indexCount = vertices.Count * 6 / 4; if (vertexCount > 0) { Dispatch(() => { if (vb == null || ib == null) { vb = new VertexBuffer(graphicsDevice, VertexPositionNormalTextureLight.VertexDeclaration, vertexCount + 2); } if (vertexCount + 2 > vb.VertexCount) { vb.Resize(vertexCount + 2); } vb.SetData(vertices.ToArray()); }); } lock (this) { if (chunk != null && chunk.Index != ChunkPosition) { return(loaded); } loaded = true; NeedsUpdate |= chunk != this.chunk; return(!NeedsUpdate); } }
/// <summary> /// Liefert den Index der angegebenen BlockDefinition. /// </summary> /// <param name="definition">BlockDefinition</param> /// <returns>Index of Block Definition</returns> public static ushort GetBlockDefinitionIndex(IBlockDefinition definition) { EnsureLoaded(); return((ushort)(Array.IndexOf(blockDefinitions, definition) + 1)); }
public void RegenerateVertexBuffer() { if (!ChunkPosition.HasValue) { return; } // Chunk nachladen if (chunk == null) { chunk = _manager.GetChunk(ChunkPosition.Value); if (chunk == null) { return; } } List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); List <int> index = new List <int>(); int textureColumns = textures.Width / SceneControl.TEXTURESIZE; float textureWidth = 1f / textureColumns; // BlockTypes sammlen Dictionary <IBlockDefinition, int> textureOffsets = new Dictionary <IBlockDefinition, int>(); // Dictionary<Type, BlockDefinition> definitionMapping = new Dictionary<Type, BlockDefinition>(); int definitionIndex = 0; foreach (var definition in DefinitionManager.GetBlockDefinitions()) { int textureCount = definition.Textures.Count(); textureOffsets.Add(definition, definitionIndex); // definitionMapping.Add(definition.GetBlockType(), definition); definitionIndex += textureCount; } for (int z = 0; z < Chunk.CHUNKSIZE_Z; z++) { for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { ushort block = chunk.GetBlock(x, y, z); if (block == 0) { continue; } IBlockDefinition blockDefinition = DefinitionManager.GetBlockDefinitionByIndex(block); if (blockDefinition == null) { continue; } int textureIndex; if (!textureOffsets.TryGetValue(blockDefinition, out textureIndex)) { continue; } // Textur-Koordinate "berechnen" Vector2 textureOffset = new Vector2(); Vector2 textureSize = new Vector2(textureWidth - 0.005f, textureWidth - 0.005f); ushort topBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z + 1)); IBlockDefinition topBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(topBlock); // Top if (topBlock == 0 || (!topBlockDefintion.IsBottomSolidWall(_manager, x, y, z + 1) && topBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetTopTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 0, 1), points[(4 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 0, 1), points[(5 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, 0, 1), points[(7 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, 0, 1), points[(6 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort bottomBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z - 1)); IBlockDefinition bottomBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(bottomBlock); // Unten if (bottomBlock == 0 || (!bottomBlockDefintion.IsTopSolidWall(_manager, x, y, z - 1) && bottomBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetBottomTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 0, -1), points[(6 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 0, -1), points[(7 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, 0, -1), points[(5 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, 0, -1), points[(4 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort southBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y + 1, z)); IBlockDefinition southBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(southBlock); // South if (southBlock == 0 || (!southBlockDefintion.IsNorthSolidWall(_manager, x, y + 1, z) && southBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetSouthTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 1, 0), points[(6 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 1, 0), points[(7 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 1, 0), points[(5 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 1, 0), points[(4 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort northBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y - 1, z)); IBlockDefinition northBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(northBlock); // North if (northBlock == 0 || (!northBlockDefintion.IsSouthSolidWall(_manager, x, y - 1, z) && northBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetNorthTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, -1, 0), points[(4 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, -1, 0), points[(5 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, -1, 0), points[(7 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, -1, 0), points[(6 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort westBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x - 1, y, z)); IBlockDefinition westBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(westBlock); // West if (westBlock == 0 || (!westBlockDefintion.IsEastSolidWall(_manager, x - 1, y, z) && westBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetWestTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 0), new Vector3(-1, 0, 0), points[(7 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 1, z + 1), new Vector3(-1, 0, 0), points[(4 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 0), new Vector3(-1, 0, 0), points[(6 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 0, y + 0, z + 1), new Vector3(-1, 0, 0), points[(5 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort eastBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x + 1, y, z)); IBlockDefinition eastBlockDefintion = DefinitionManager.GetBlockDefinitionByIndex(eastBlock); // Ost if (eastBlock == 0 || (!eastBlockDefintion.IsWestSolidWall(_manager, x + 1, y, z) && eastBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + 0.002f, (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + 0.002f); Vector2[] points = new[] { textureOffset, new Vector2(textureOffset.X + textureSize.X, textureOffset.Y), textureOffset + textureSize, new Vector2(textureOffset.X, textureOffset.Y + textureSize.X) }; int rotation = -blockDefinition.GetEastTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 1), new Vector3(1, 0, 0), points[(5 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 1, z + 0), new Vector3(1, 0, 0), points[(6 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 1), new Vector3(1, 0, 0), points[(4 + rotation) % 4])); vertices.Add(new VertexPositionNormalTexture(new Vector3(x + 1, y + 0, z + 0), new Vector3(1, 0, 0), points[(7 + rotation) % 4])); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } } } } vertexCount = vertices.Count; indexCount = index.Count; VertexBuffer vb2 = null; IndexBuffer ib2 = null; if (vertexCount > 0) { try { vb2 = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertexCount, BufferUsage.WriteOnly); vb2.SetData <VertexPositionNormalTexture>(vertices.ToArray()); ib2 = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, indexCount, BufferUsage.WriteOnly); ib2.SetData <int>(index.ToArray()); } catch (Exception) { } } VertexBuffer vbOld = vb; IndexBuffer ibOld = ib; lock (this) { vb = vb2; ib = ib2; loaded = true; } if (vbOld != null) { vbOld.Dispose(); } if (ibOld != null) { ibOld.Dispose(); } lastReset = chunk.ChangeCounter; }
/// <summary> /// Liefert den Index der angegebenen BlockDefinition. /// </summary> /// <param name="definition">BlockDefinition</param> /// <returns>Index of Block Definition</returns> public static ushort GetBlockDefinitionIndex(IBlockDefinition definition) { EnsureLoaded(); return (ushort)(Array.IndexOf(blockDefinitions, definition) + 1); }
public void RegenerateVertexBuffer() { if (!ChunkPosition.HasValue) { return; } // Chunk nachladen if (chunk == null) { chunk = _manager.GetChunk(ChunkPosition.Value); if (chunk == null) { return; } } List <VertexPositionNormalTextureLight> vertices = new List <VertexPositionNormalTextureLight>(); List <int> index = new List <int>(); int textureColumns = textures.Width / SceneControl.TEXTURESIZE; float textureWidth = 1f / textureColumns; float texelSize = 1f / SceneControl.TEXTURESIZE; float textureSizeGap = texelSize; float textureGap = texelSize / 2; // BlockTypes sammlen Dictionary <IBlockDefinition, int> textureOffsets = new Dictionary <IBlockDefinition, int>(); // Dictionary<Type, BlockDefinition> definitionMapping = new Dictionary<Type, BlockDefinition>(); int definitionIndex = 0; foreach (var definition in DefinitionManager.Instance.GetBlockDefinitions()) { int textureCount = definition.Textures.Count(); textureOffsets.Add(definition, definitionIndex); // definitionMapping.Add(definition.GetBlockType(), definition); definitionIndex += textureCount; } Vector2[] uvOffsets = new[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) }; for (int z = 0; z < Chunk.CHUNKSIZE_Z; z++) { for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { ushort block = chunk.GetBlock(x, y, z); if (block == 0) { continue; } IBlockDefinition blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(block); if (blockDefinition == null) { continue; } int textureIndex; if (!textureOffsets.TryGetValue(blockDefinition, out textureIndex)) { continue; } // Textur-Koordinate "berechnen" Vector2 textureOffset = new Vector2(); Vector2 textureSize = new Vector2(textureWidth - textureSizeGap, textureWidth - textureSizeGap); ushort topBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z + 1)); IBlockDefinition topBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(topBlock); // Top if (topBlock == 0 || (!topBlockDefintion.IsBottomSolidWall(_manager, x, y, z + 1) && topBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetTopTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 0, 1), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 0, 1), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, 0, 1), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, 0, 1), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetTopTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort bottomBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y, z - 1)); IBlockDefinition bottomBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(bottomBlock); // Unten if (bottomBlock == 0 || (!bottomBlockDefintion.IsTopSolidWall(_manager, x, y, z - 1) && bottomBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetBottomTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 0, -1), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 0, -1), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, 0, -1), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, 0, -1), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetBottomTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort southBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y + 1, z)); IBlockDefinition southBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(southBlock); // South if (southBlock == 0 || (!southBlockDefintion.IsNorthSolidWall(_manager, x, y + 1, z) && southBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetSouthTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 0), new Vector3(0, 1, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 0), new Vector3(0, 1, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 1), new Vector3(0, 1, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 1), new Vector3(0, 1, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetSouthTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort northBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x, y - 1, z)); IBlockDefinition northBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(northBlock); // North if (northBlock == 0 || (!northBlockDefintion.IsSouthSolidWall(_manager, x, y - 1, z) && northBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetNorthTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 1), new Vector3(0, -1, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 1), new Vector3(0, -1, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 0), new Vector3(0, -1, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 0), new Vector3(0, -1, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetNorthTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort westBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x - 1, y, z)); IBlockDefinition westBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(westBlock); // West if (westBlock == 0 || (!westBlockDefintion.IsEastSolidWall(_manager, x - 1, y, z) && westBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetWestTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 0), new Vector3(-1, 0, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 1, z + 1), new Vector3(-1, 0, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 0), new Vector3(-1, 0, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 0, y + 0, z + 1), new Vector3(-1, 0, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetWestTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } ushort eastBlock = _manager.GetBlock((ChunkPosition.Value * Chunk.CHUNKSIZE) + new Index3(x + 1, y, z)); IBlockDefinition eastBlockDefintion = DefinitionManager.Instance.GetBlockDefinitionByIndex(eastBlock); // Ost if (eastBlock == 0 || (!eastBlockDefintion.IsWestSolidWall(_manager, x + 1, y, z) && eastBlock != block)) { textureOffset = new Vector2( (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) % textureColumns) * textureWidth) + textureGap, (((textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)) / textureColumns) * textureWidth) + textureGap); int rotation = -blockDefinition.GetEastTextureRotation(_manager, x, y, z); int localOffset = vertices.Count; vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 1), new Vector3(1, 0, 0), uvOffsets[(5 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 1, z + 0), new Vector3(1, 0, 0), uvOffsets[(6 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 1), new Vector3(1, 0, 0), uvOffsets[(4 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)), 0)); vertices.Add(new VertexPositionNormalTextureLight(new Vector3(x + 1, y + 0, z + 0), new Vector3(1, 0, 0), uvOffsets[(7 + rotation) % 4], (byte)(textureIndex + blockDefinition.GetEastTextureIndex(_manager, x, y, z)), 0)); index.Add(localOffset + 0); index.Add(localOffset + 1); index.Add(localOffset + 3); index.Add(localOffset + 0); index.Add(localOffset + 3); index.Add(localOffset + 2); } } } } vertexCount = vertices.Count; indexCount = index.Count; if (vertexCount > 0) { try { if (vb == null || ib == null) { vb = new VertexBuffer(graphicsDevice, VertexPositionNormalTextureLight.VertexDeclaration, vertexCount + 2); //ib = new IndexBuffer(graphicsDevice, DrawElementsType.UnsignedInt, indexCount); } if (vertexCount + 2 > vb.VertexCount) { vb.Resize(vertexCount + 2); } //vb2 = new VertexBuffer(graphicsDevice, VertexPositionNormalTextureLight.VertexDeclaration, vertexCount+2);//TODO: why do I need more vertices? vb.SetData <VertexPositionNormalTextureLight>(vertices.ToArray()); //if (indexCount > ib.IndexCount) // ib.Resize(indexCount); //ib.SetData<int>(index.ToArray()); } catch (Exception) { } } lock (this) { loaded = true; } lastReset = chunk.ChangeCounter; }
public void Serialize(Stream stream, IChunk chunk) { using (BinaryWriter bw = new BinaryWriter(stream)) { List <IBlockDefinition> definitions = new List <IBlockDefinition>(); // Types sammeln for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] != 0) { IBlockDefinition definition = DefinitionManager.GetBlockDefinitionByIndex(chunk.Blocks[i]); if (!definitions.Contains(definition)) { definitions.Add(definition); } } } bool longIndex = definitions.Count > 254; bw.Write((byte)((longIndex) ? 1 : 0)); // Schreibe Phase 1 if (longIndex) { bw.Write((ushort)definitions.Count); } else { bw.Write((byte)definitions.Count); } // Im Falle eines Luft-Chunks... if (definitions.Count == 0) { return; } foreach (var definition in definitions) { bw.Write(definition.GetType().FullName); } // Schreibe Phase 2 for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] == 0) { // Definition Index (Air) if (longIndex) { bw.Write((ushort)0); } else { bw.Write((byte)0); } } else { // Definition Index IBlockDefinition definition = DefinitionManager.GetBlockDefinitionByIndex(chunk.Blocks[i]); if (longIndex) { bw.Write((ushort)(definitions.IndexOf(definition) + 1)); } else { bw.Write((byte)(definitions.IndexOf(definition) + 1)); } // Meta Data if (definition.HasMetaData) { bw.Write(chunk.MetaData[i]); } } } } }
public void Update(GameTime frameTime) { if (!Player.FlyMode) { Player.ExternalForce = new Vector3(0, 0, -20f) * Player.Mass; } else { Player.ExternalForce = Vector3.Zero; } #region Inputverarbeitung Vector3 externalPower = ((Player.ExternalForce * Player.ExternalForce) / (2 * Player.Mass)) * (float)frameTime.ElapsedGameTime.TotalSeconds; externalPower *= new Vector3(Math.Sign(Player.ExternalForce.X), Math.Sign(Player.ExternalForce.Y), Math.Sign(Player.ExternalForce.Z)); // Input verarbeiten Player.Angle += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.X; Player.Tilt += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.Y; Player.Tilt = Math.Min(1.5f, Math.Max(-1.5f, Player.Tilt)); float lookX = (float)Math.Cos(Player.Angle); float lookY = -(float)Math.Sin(Player.Angle); var VelocityDirection = new Vector3(lookX, lookY, 0) * Move.Y; float stafeX = (float)Math.Cos(Player.Angle + MathHelper.PiOver2); float stafeY = -(float)Math.Sin(Player.Angle + MathHelper.PiOver2); VelocityDirection += new Vector3(stafeX, stafeY, 0) * Move.X; Vector3 Friction = new Vector3(1, 1, 0.1f) * Player.FRICTION; Vector3 powerdirection = new Vector3(); if (Player.FlyMode) { VelocityDirection += new Vector3(0, 0, (float)Math.Sin(Player.Tilt) * Move.Y); Friction = Vector3.One * Player.FRICTION; } powerdirection += externalPower; powerdirection += (Player.POWER * VelocityDirection); // if (OnGround && input.JumpTrigger) if (lastJump) { lastJump = false; Vector3 jumpDirection = new Vector3(lookX, lookY, 0f) * Move.Y * 0.1f; jumpDirection.Z = 1f; jumpDirection.Normalize(); powerdirection += jumpDirection * Player.JUMPPOWER; } Vector3 VelocityChange = (2.0f / Player.Mass * (powerdirection - Friction * Player.Velocity)) * (float)frameTime.ElapsedGameTime.TotalSeconds; Player.Velocity += new Vector3( (float)(VelocityChange.X < 0 ? -Math.Sqrt(-VelocityChange.X) : Math.Sqrt(VelocityChange.X)), (float)(VelocityChange.Y < 0 ? -Math.Sqrt(-VelocityChange.Y) : Math.Sqrt(VelocityChange.Y)), (float)(VelocityChange.Z < 0 ? -Math.Sqrt(-VelocityChange.Z) : Math.Sqrt(VelocityChange.Z))); #endregion #region Playerbewegung Vector3 move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds; Player.OnGround = false; bool collision = false; int loop = 0; do { int minx = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.X - Player.Radius, Player.Position.BlockPosition.X - Player.Radius + move.X)); int maxx = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.X + Player.Radius, Player.Position.BlockPosition.X + Player.Radius + move.X)); int miny = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Y - Player.Radius, Player.Position.BlockPosition.Y - Player.Radius + move.Y)); int maxy = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.Y + Player.Radius, Player.Position.BlockPosition.Y + Player.Radius + move.Y)); int minz = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Z, Player.Position.BlockPosition.Z + move.Z)); int maxz = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.Z + Player.Height, Player.Position.BlockPosition.Z + Player.Height + move.Z)); // Relative PlayerBox BoundingBox playerBox = new BoundingBox( new Vector3( Player.Position.BlockPosition.X - Player.Radius, Player.Position.BlockPosition.Y - Player.Radius, Player.Position.BlockPosition.Z), new Vector3( Player.Position.BlockPosition.X + Player.Radius, Player.Position.BlockPosition.Y + Player.Radius, Player.Position.BlockPosition.Z + Player.Height)); collision = false; float min = 1f; Axis minAxis = Axis.None; for (int z = minz; z <= maxz; z++) { for (int y = miny; y <= maxy; y++) { for (int x = minx; x <= maxx; x++) { Index3 pos = new Index3(x, y, z); Index3 blockPos = pos + Player.Position.GlobalBlockIndex; ushort block = _manager.GetBlock(blockPos); if (block == 0) { continue; } Axis? localAxis; IBlockDefinition blockDefinition = DefinitionManager.GetBlockDefinitionByIndex(block); float? moveFactor = Block.Intersect( blockDefinition.GetCollisionBoxes(_manager, blockPos.X, blockPos.Y, blockPos.Z), pos, playerBox, move, out localAxis); if (moveFactor.HasValue && moveFactor.Value < min) { collision = true; min = moveFactor.Value; minAxis = localAxis.Value; } } } } Player.Position += (move * min); move *= (1f - min); switch (minAxis) { case Axis.X: Player.Velocity *= new Vector3(0, 1, 1); Player.Position += new Vector3(move.X > 0 ? -Gap : Gap, 0, 0); move.X = 0f; break; case Axis.Y: Player.Velocity *= new Vector3(1, 0, 1); Player.Position += new Vector3(0, move.Y > 0 ? -Gap : Gap, 0); move.Y = 0f; break; case Axis.Z: Player.OnGround = true; Player.Velocity *= new Vector3(1, 1, 0); Player.Position += new Vector3(0, 0, move.Z > 0 ? -Gap : Gap); move.Z = 0f; break; } // Koordinate normalisieren (Rundwelt) Coordinate position = Player.Position; position.NormalizeChunkIndexXY(planet.Size); Player.Position = position; loop++; }while (collision && loop < 3); if (Player.Position.ChunkIndex != _oldIndex) { //TODO: Planeten rundung beachten :) _chunkLoader.UpdatePosition(Player.Position.ChunkIndex.X - _oldIndex.X, Player.Position.ChunkIndex.Y - _oldIndex.Y, Player.Position.ChunkIndex.Z - _oldIndex.Z); _oldIndex = Player.Position.ChunkIndex; } #endregion #region Block Interaction if (lastInteract.HasValue) { ushort lastBlock = _manager.GetBlock(lastInteract.Value); _manager.SetBlock(lastInteract.Value, 0); if (lastBlock != 0) { var blockDefinition = DefinitionManager.GetBlockDefinitionByIndex(lastBlock); var slot = Player.Inventory.Where(s => s.Definition == blockDefinition && s.Amount < blockDefinition.StackLimit).FirstOrDefault(); // Wenn noch kein Slot da ist oder der vorhandene voll, dann neuen Slot if (slot == null || slot.Amount >= blockDefinition.StackLimit) { slot = new InventorySlot() { Definition = blockDefinition, Amount = 0 }; Player.Inventory.Add(slot); } slot.Amount++; } lastInteract = null; } if (lastApply.HasValue) { if (ActiveTool != null) { Index3 add = new Index3(); switch (lastOrientation) { case OrientationFlags.SideWest: add = new Index3(-1, 0, 0); break; case OrientationFlags.SideEast: add = new Index3(1, 0, 0); break; case OrientationFlags.SideSouth: add = new Index3(0, -1, 0); break; case OrientationFlags.SideNorth: add = new Index3(0, 1, 0); break; case OrientationFlags.SideBottom: add = new Index3(0, 0, -1); break; case OrientationFlags.SideTop: add = new Index3(0, 0, 1); break; } if (ActiveTool.Definition is IBlockDefinition) { IBlockDefinition definition = ActiveTool.Definition as IBlockDefinition; _manager.SetBlock(lastApply.Value + add, DefinitionManager.GetBlockDefinitionIndex(definition)); ActiveTool.Amount--; if (ActiveTool.Amount <= 0) { Player.Inventory.Remove(ActiveTool); ActiveTool = null; } } // TODO: Fix Interaction ;) //ushort block = _manager.GetBlock(lastApply.Value); //IBlockDefinition blockDefinition = BlockDefinitionManager.GetForType(block); //IItemDefinition itemDefinition = ActiveTool.Definition; //blockDefinition.Hit(blockDefinition, itemDefinition.GetProperties(null)); //itemDefinition.Hit(null, blockDefinition.GetProperties(block)); } lastApply = null; } #endregion }
public static ushort GetDefinitionIndex(IBlockDefinition definition) { return (ushort)(Array.IndexOf(_definitions, definition) + 1); }
/// <summary> This method copy's each database field from the <paramref name="source"/> interface to this data row.</summary> public void Copy_From(IBlockDefinition source, bool includePrimaryKey = false) { if (includePrimaryKey) this.Id = source.Id; this.NameId = source.NameId; this.PageId = source.PageId; this.BlockPlayingOrder = source.BlockPlayingOrder; this.MinPositionLeft = source.MinPositionLeft; this.MaxPositionRight = source.MaxPositionRight; this.MinPositionTop = source.MinPositionTop; this.MaxPositionBottom = source.MaxPositionBottom; this.BlockRotation = source.BlockRotation; this.BlockType = source.BlockType; }
/// <summary> /// This method copy's each database field which is in the <paramref name="includedColumns"/> /// from the <paramref name="source"/> interface to this data row. /// </summary> public void Copy_From_But_TakeOnly(IBlockDefinition source, params string[] includedColumns) { if (includedColumns.Contains(BlockDefinitionsTable.IdCol)) this.Id = source.Id; if (includedColumns.Contains(BlockDefinitionsTable.NameIdCol)) this.NameId = source.NameId; if (includedColumns.Contains(BlockDefinitionsTable.PageIdCol)) this.PageId = source.PageId; if (includedColumns.Contains(BlockDefinitionsTable.BlockPlayingOrderCol)) this.BlockPlayingOrder = source.BlockPlayingOrder; if (includedColumns.Contains(BlockDefinitionsTable.MinPositionLeftCol)) this.MinPositionLeft = source.MinPositionLeft; if (includedColumns.Contains(BlockDefinitionsTable.MaxPositionRightCol)) this.MaxPositionRight = source.MaxPositionRight; if (includedColumns.Contains(BlockDefinitionsTable.MinPositionTopCol)) this.MinPositionTop = source.MinPositionTop; if (includedColumns.Contains(BlockDefinitionsTable.MaxPositionBottomCol)) this.MaxPositionBottom = source.MaxPositionBottom; if (includedColumns.Contains(BlockDefinitionsTable.BlockRotationCol)) this.BlockRotation = source.BlockRotation; if (includedColumns.Contains(BlockDefinitionsTable.BlockTypeCol)) this.BlockType = source.BlockType; }
/// <summary> /// Aktualisiert den Spieler (Bewegung, Interaktion) /// </summary> /// <param name="frameTime">Die aktuelle Zeit.</param> public void Update(GameTime frameTime) { #region Inputverarbeitung // Input verarbeiten Player.Angle += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.X; Player.Tilt += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.Y; Player.Tilt = Math.Min(1.5f, Math.Max(-1.5f, Player.Tilt)); #endregion #region Physik float lookX = (float)Math.Cos(Player.Angle); float lookY = -(float)Math.Sin(Player.Angle); var velocitydirection = new Vector3(lookX, lookY, 0) * Move.Y; float stafeX = (float)Math.Cos(Player.Angle + MathHelper.PiOver2); float stafeY = -(float)Math.Sin(Player.Angle + MathHelper.PiOver2); velocitydirection += new Vector3(stafeX, stafeY, 0) * Move.X; Player.Velocity += PhysicalUpdate(velocitydirection, frameTime.ElapsedGameTime, !Player.FlyMode, Player.FlyMode); #endregion #region Playerbewegung /Kollision Vector3 move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds; Player.OnGround = false; //Blocks finden die eine Kollision verursachen könnten int minx = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.X - Player.Radius, Player.Position.BlockPosition.X - Player.Radius + move.X)); int maxx = (int)Math.Ceiling(Math.Max( Player.Position.BlockPosition.X + Player.Radius, Player.Position.BlockPosition.X + Player.Radius + move.X)); int miny = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Y - Player.Radius, Player.Position.BlockPosition.Y - Player.Radius + move.Y)); int maxy = (int)Math.Ceiling(Math.Max( Player.Position.BlockPosition.Y + Player.Radius, Player.Position.BlockPosition.Y + Player.Radius + move.Y)); int minz = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Z, Player.Position.BlockPosition.Z + move.Z)); int maxz = (int)Math.Ceiling(Math.Max( Player.Position.BlockPosition.Z + Player.Height, Player.Position.BlockPosition.Z + Player.Height + move.Z)); //Beteiligte Flächen des Spielers var playerplanes = CollisionPlane.GetPlayerCollisionPlanes(Player).ToList(); bool abort = false; for (int z = minz; z <= maxz && !abort; z++) { for (int y = miny; y <= maxy && !abort; y++) { for (int x = minx; x <= maxx && !abort; x++) { move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds; Index3 pos = new Index3(x, y, z); Index3 blockPos = pos + Player.Position.GlobalBlockIndex; ushort block = localChunkCache.GetBlock(blockPos); if (block == 0) { continue; } var blockplane = CollisionPlane.GetBlockCollisionPlanes(pos, Player.Velocity).ToList(); var planes = from pp in playerplanes from bp in blockplane where CollisionPlane.Intersect(bp, pp) let distance = CollisionPlane.GetDistance(bp, pp) where CollisionPlane.CheckDistance(distance, move) select new { BlockPlane = bp, PlayerPlane = pp, Distance = distance }; foreach (var plane in planes) { var subvelocity = (plane.Distance / (float)frameTime.ElapsedGameTime.TotalSeconds); var diff = Player.Velocity - subvelocity; float vx; float vy; float vz; if (plane.BlockPlane.normal.X != 0 && (Player.Velocity.X > 0 && diff.X >= 0 && subvelocity.X >= 0 || Player.Velocity.X < 0 && diff.X <= 0 && subvelocity.X <= 0)) { vx = subvelocity.X; } else { vx = Player.Velocity.X; } if (plane.BlockPlane.normal.Y != 0 && (Player.Velocity.Y > 0 && diff.Y >= 0 && subvelocity.Y >= 0 || Player.Velocity.Y < 0 && diff.Y <= 0 && subvelocity.Y <= 0)) { vy = subvelocity.Y; } else { vy = Player.Velocity.Y; } if (plane.BlockPlane.normal.Z != 0 && (Player.Velocity.Z > 0 && diff.Z >= 0 && subvelocity.Z >= 0 || Player.Velocity.Z < 0 && diff.Z <= 0 && subvelocity.Z <= 0)) { vz = subvelocity.Z; } else { vz = Player.Velocity.Z; } Player.Velocity = new Vector3(vx, vy, vz); if (vx == 0 && vy == 0 && vz == 0) { abort = true; break; } } } } } // TODO: Was ist für den Fall Gravitation = 0 oder im Scheitelpunkt des Sprungs? Player.OnGround = Player.Velocity.Z == 0f; Coordinate position = Player.Position + Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds; position.NormalizeChunkIndexXY(planet.Size); Player.Position = position; //Beam me up KeyboardState ks = Keyboard.GetState(); if (ks.IsKeyDown(Keys.P)) { Player.Position += new Vector3(0, 0, 10); } if (Player.Position.ChunkIndex != _oldIndex) { _oldIndex = Player.Position.ChunkIndex; ReadyState = false; localChunkCache.SetCenter(planet, new Index2(Player.Position.ChunkIndex), (success) => { ReadyState = success; }); } #endregion #region Block Interaction if (lastInteract.HasValue) { ushort lastBlock = localChunkCache.GetBlock(lastInteract.Value); localChunkCache.SetBlock(lastInteract.Value, 0); if (lastBlock != 0) { var blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(lastBlock); var slot = Player.Inventory.FirstOrDefault(s => s.Definition == blockDefinition); // Wenn noch kein Slot da ist oder der vorhandene voll, dann neuen Slot if (slot == null) { slot = new InventorySlot() { Definition = blockDefinition, Amount = 0 }; Player.Inventory.Add(slot); for (int i = 0; i < Player.Tools.Length; i++) { if (Player.Tools[i] == null) { Player.Tools[i] = slot; break; } } } slot.Amount += 125; } lastInteract = null; } if (lastApply.HasValue) { if (ActiveTool != null) { Index3 add = new Index3(); switch (lastOrientation) { case OrientationFlags.SideWest: add = new Index3(-1, 0, 0); break; case OrientationFlags.SideEast: add = new Index3(1, 0, 0); break; case OrientationFlags.SideSouth: add = new Index3(0, -1, 0); break; case OrientationFlags.SideNorth: add = new Index3(0, 1, 0); break; case OrientationFlags.SideBottom: add = new Index3(0, 0, -1); break; case OrientationFlags.SideTop: add = new Index3(0, 0, 1); break; } if (ActiveTool.Definition is IBlockDefinition) { IBlockDefinition definition = ActiveTool.Definition as IBlockDefinition; Index3 idx = lastApply.Value + add; var boxes = definition.GetCollisionBoxes(localChunkCache, idx.X, idx.Y, idx.Z); float gap = 0.01f; var playerBox = new BoundingBox( new Vector3( Player.Position.GlobalBlockIndex.X + Player.Position.BlockPosition.X - Player.Radius + gap, Player.Position.GlobalBlockIndex.Y + Player.Position.BlockPosition.Y - Player.Radius + gap, Player.Position.GlobalBlockIndex.Z + Player.Position.BlockPosition.Z + gap), new Vector3( Player.Position.GlobalBlockIndex.X + Player.Position.BlockPosition.X + Player.Radius - gap, Player.Position.GlobalBlockIndex.Y + Player.Position.BlockPosition.Y + Player.Radius - gap, Player.Position.GlobalBlockIndex.Z + Player.Position.BlockPosition.Z + Player.Height - gap) ); // Nicht in sich selbst reinbauen bool intersects = false; foreach (var box in boxes) { var newBox = new BoundingBox(idx + box.Min, idx + box.Max); if (newBox.Min.X < playerBox.Max.X && newBox.Max.X > playerBox.Min.X && newBox.Min.Y < playerBox.Max.Y && newBox.Max.X > playerBox.Min.Y && newBox.Min.Z < playerBox.Max.Z && newBox.Max.X > playerBox.Min.Z) { intersects = true; } } if (!intersects) { localChunkCache.SetBlock(idx, DefinitionManager.Instance.GetBlockDefinitionIndex(definition)); ActiveTool.Amount -= 125; if (ActiveTool.Amount <= 0) { Player.Inventory.Remove(ActiveTool); for (int i = 0; i < Player.Tools.Length; i++) { if (Player.Tools[i] == ActiveTool) { Player.Tools[i] = null; } } ActiveTool = null; } } } // TODO: Fix Interaction ;) //ushort block = _manager.GetBlock(lastApply.Value); //IBlockDefinition blockDefinition = BlockDefinitionManager.GetForType(block); //IItemDefinition itemDefinition = ActiveTool.Definition; //blockDefinition.Hit(blockDefinition, itemDefinition.GetProperties(null)); //itemDefinition.Hit(null, blockDefinition.GetProperties(block)); } lastApply = null; } #endregion }
/// <summary> /// Liefert den Index der angegebenen BlockDefinition. /// </summary> /// <typeparam name="T">BlockDefinition Type</typeparam> /// <returns>Index der Block Definition</returns> public ushort GetBlockDefinitionIndex <T>() where T : IBlockDefinition { IBlockDefinition definition = blockDefinitions.SingleOrDefault(d => d.GetType() == typeof(T)); return(GetBlockDefinitionIndex(definition)); }
public IBlockDefinition[] GetBlockChain() { IBlockDefinition[] blockDefinitions = new IBlockDefinition[Chain.Count]; Chain.CopyTo(blockDefinitions); return(blockDefinitions); }
/// <summary> /// Serialisiert die Chunksäule in den angegebenen Stream. /// </summary> /// <param name="stream">Zielstream</param> /// <param name="definitionManager">Der verwendete DefinitionManager</param> public void Serialize(Stream stream, IDefinitionManager definitionManager) { using (BinaryWriter bw = new BinaryWriter(stream)) { // Definitionen sammeln List <IBlockDefinition> definitions = new List <IBlockDefinition>(); for (int c = 0; c < Chunks.Length; c++) { IChunk chunk = Chunks[c]; for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] != 0) { IBlockDefinition definition = definitionManager.GetBlockDefinitionByIndex(chunk.Blocks[i]); if (!definitions.Contains(definition)) { definitions.Add(definition); } } } } bool longIndex = definitions.Count > 254; bw.Write((byte)((longIndex) ? 1 : 0)); // Schreibe Phase 1 (Column Meta: Heightmap, populated, chunkcount) bw.Write((byte)Chunks.Length); // Chunk Count bw.Write(Populated); // Populated for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) // Heightmap { for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { bw.Write((ushort)Heights[x, y]); } } for (int i = 0; i < Chunks.Length; i++) // Change Counter { bw.Write(Chunks[i].ChangeCounter); } // Schreibe Phase 2 (Block Definitionen) if (longIndex) { bw.Write((ushort)definitions.Count); } else { bw.Write((byte)definitions.Count); } foreach (var definition in definitions) { bw.Write(definition.GetType().FullName); } // Schreibe Phase 3 (Chunk Infos) for (int c = 0; c < Chunks.Length; c++) { IChunk chunk = Chunks[c]; for (int i = 0; i < chunk.Blocks.Length; i++) { if (chunk.Blocks[i] == 0) { // Definition Index (Air) if (longIndex) { bw.Write((ushort)0); } else { bw.Write((byte)0); } } else { // Definition Index IBlockDefinition definition = definitionManager.GetBlockDefinitionByIndex(chunk.Blocks[i]); if (longIndex) { bw.Write((ushort)(definitions.IndexOf(definition) + 1)); } else { bw.Write((byte)(definitions.IndexOf(definition) + 1)); } // Meta Data if (definition.HasMetaData) { bw.Write(chunk.MetaData[i]); } } } } } }
public IChunk[] GenerateChunk(IEnumerable <IBlockDefinition> blockDefinitions, IPlanet planet, Index2 index) { IBlockDefinition sandDefinition = blockDefinitions.FirstOrDefault(d => typeof(SandBlockDefinition) == d.GetType()); ushort sandIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), sandDefinition) + 1); IBlockDefinition groundDefinition = blockDefinitions.FirstOrDefault(d => typeof(GroundBlockDefinition) == d.GetType()); ushort groundIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), groundDefinition) + 1); IBlockDefinition stoneDefinition = blockDefinitions.FirstOrDefault(d => typeof(StoneBlockDefinition) == d.GetType()); ushort stoneIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), stoneDefinition) + 1); IBlockDefinition waterDefinition = blockDefinitions.FirstOrDefault(d => typeof(WaterBlockDefinition) == d.GetType()); ushort waterIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), waterDefinition) + 1); IBlockDefinition grassDefinition = blockDefinitions.FirstOrDefault(d => typeof(GrassBlockDefinition) == d.GetType()); ushort grassIndex = (ushort)(Array.IndexOf(blockDefinitions.ToArray(), grassDefinition) + 1); if (!(planet is ComplexPlanet)) { throw new ArgumentException("planet is not a Type of ComplexPlanet"); } ComplexPlanet localPlanet = (ComplexPlanet)planet; float[,] localHeightmap = localPlanet.BiomeGenerator.GetHeightmap(index); IChunk[] chunks = new IChunk[planet.Size.Z]; for (int i = 0; i < planet.Size.Z; i++) { chunks[i] = new Chunk(new Index3(index, i), planet.Id); } int obersteSchicht; bool surfaceBlock; bool ozeanSurface; for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { obersteSchicht = 5; surfaceBlock = true; ozeanSurface = false; for (int i = chunks.Length - 1; i >= 0; i--) { for (int z = Chunk.CHUNKSIZE_Z - 1; z >= 0; z--) { int absoluteZ = (z + (i * Chunk.CHUNKSIZE_Z)); if (absoluteZ <= localHeightmap[x, y] * localPlanet.Size.Z * Chunk.CHUNKSIZE_Z) { if (obersteSchicht > 0) { float temp = localPlanet.ClimateMap.GetTemperature(new Index3(index.X * Chunk.CHUNKSIZE_X + x, index.Y * Chunk.CHUNKSIZE_Y + y, i * Chunk.CHUNKSIZE_Z + z)); if ((ozeanSurface || surfaceBlock) && (absoluteZ <= (localPlanet.BiomeGenerator.SeaLevel + 2)) && (absoluteZ >= (localPlanet.BiomeGenerator.SeaLevel - 2))) { chunks[i].SetBlock(x, y, z, sandIndex); } else if (temp >= 35) { chunks[i].SetBlock(x, y, z, sandIndex); } else if (absoluteZ >= localPlanet.Size.Z * Chunk.CHUNKSIZE_Z * 0.6f) { if (temp > 12) { chunks[i].SetBlock(x, y, z, groundIndex); } else { chunks[i].SetBlock(x, y, z, stoneIndex); } } else if (temp >= 8) { if (surfaceBlock && !ozeanSurface) { chunks[i].SetBlock(x, y, z, grassIndex); surfaceBlock = false; } else { chunks[i].SetBlock(x, y, z, groundIndex); } } else { chunks[i].SetBlock(x, y, z, groundIndex); } obersteSchicht--; } else { chunks[i].SetBlock(x, y, z, stoneIndex); } } else if ((z + (i * Chunk.CHUNKSIZE_Z)) <= localPlanet.BiomeGenerator.SeaLevel) { chunks[i].SetBlock(x, y, z, waterIndex); ozeanSurface = true; } } } } } //float[,] cloudmap = null; ////Biomes.BiomeBlockValue[, ,] blockValues = localPlanet.BiomeGenerator.GetBlockValues(index,heightmap,0f,1f); ////for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) //Parallel.For(0, Chunk.CHUNKSIZE_X, x => //{ // for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) // { // bool grass = true, sand = false; // for (int i = chunks.Length - 1; i >= 0; i--) // { // for (int z = Chunk.CHUNKSIZE_Z - 1; z >= 0; z--) // { // //Biomes.BiomeBlockValue blockValue = blockValues[x, y, z + i * Chunk.CHUNKSIZE_Z]; // int blockHeight = Math.Max(z + Chunk.CHUNKSIZE_Z * (i), 0); // //float density = heightmap[x,y] * (Chunk.CHUNKSIZE_Z * (planet.Size.Z)) - blockHeight; // Index3 blockIndex = new Index3(index.X * Chunk.CHUNKSIZE_X + x, index.Y * Chunk.CHUNKSIZE_Y + y, i * Chunk.CHUNKSIZE_Z + z); // if (blockValue.Density > 0.6f || (z < 3 && i == 0)) // { // if (blockValue.IsDessert || (grass | sand) && (z + (i * Chunk.CHUNKSIZE_Z)) <= localPlanet.BiomeGenerator.SeaLevel && (z + (i * Chunk.CHUNKSIZE_Z)) >= localPlanet.BiomeGenerator.SeaLevel - 2) // { // chunks[i].SetBlock(new Index3(x, y, z), new SandBlock()); // grass = false; // sand = true; // } // else if (grass && planet.ClimateMap.GetTemperature(blockIndex) > 18.0f) // { // chunks[i].SetBlock(new Index3(x, y, z), new GrassBlock()); // grass = false; // } // //else if (z < Chunk.CHUNKSIZE_Z - 1 && noiseplus >= resDensity) // //{ // // chunks[i].SetBlock(new Index3(x, y, z), new StoneBlock()); // //} // else // { // chunks[i].SetBlock(new Index3(x, y, z), new GroundBlock()); // grass = false; // } // } // else if ((z + (i * Chunk.CHUNKSIZE_Z)) <= localPlanet.BiomeGenerator.SeaLevel) // { // grass = false; // sand = true; // chunks[i].SetBlock(new Index3(x, y, z), new WaterBlock()); // } // } // } // } //}); return(chunks); }
protected override void OnUpdate(GameTime gameTime) { if (player.ActorHost == null) { return; } sunPosition += (float)gameTime.ElapsedGameTime.TotalMinutes * MathHelper.TwoPi; Index3 centerblock = player.ActorHost.Position.GlobalBlockIndex; Index3 renderOffset = player.ActorHost.Position.ChunkIndex * Chunk.CHUNKSIZE; Index3? selected = null; Axis? selectedAxis = null; Vector3?selectionPoint = null; float bestDistance = 9999; for (int z = -Player.SELECTIONRANGE; z < Player.SELECTIONRANGE; z++) { for (int y = -Player.SELECTIONRANGE; y < Player.SELECTIONRANGE; y++) { for (int x = -Player.SELECTIONRANGE; x < Player.SELECTIONRANGE; x++) { Index3 range = new Index3(x, y, z); Index3 pos = range + centerblock; ushort block = localChunkCache.GetBlock(pos); if (block == 0) { continue; } IBlockDefinition blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(block); Axis? collisionAxis; float?distance = Block.Intersect(blockDefinition.GetCollisionBoxes(localChunkCache, pos.X, pos.Y, pos.Z), pos - renderOffset, camera.PickRay, out collisionAxis); if (distance.HasValue && distance.Value < bestDistance) { pos.NormalizeXY(planet.Size * Chunk.CHUNKSIZE); selected = pos; selectedAxis = collisionAxis; bestDistance = distance.Value; selectionPoint = (camera.PickRay.Position + (camera.PickRay.Direction * distance)) - (selected - renderOffset); } } } } if (selected.HasValue) { player.SelectedBox = selected; switch (selectedAxis) { case Axis.X: player.SelectedSide = (camera.PickRay.Direction.X > 0 ? OrientationFlags.SideWest : OrientationFlags.SideEast); break; case Axis.Y: player.SelectedSide = (camera.PickRay.Direction.Y > 0 ? OrientationFlags.SideSouth : OrientationFlags.SideNorth); break; case Axis.Z: player.SelectedSide = (camera.PickRay.Direction.Z > 0 ? OrientationFlags.SideBottom : OrientationFlags.SideTop); break; } player.SelectedPoint = new Vector2(); switch (player.SelectedSide) { case OrientationFlags.SideWest: player.SelectedPoint = new Vector2(1f - selectionPoint.Value.Y, 1f - selectionPoint.Value.Z); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner011, OrientationFlags.Corner001, OrientationFlags.Corner010, OrientationFlags.Corner000); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeWestTop, OrientationFlags.EdgeWestBottom, OrientationFlags.EdgeNorthWest, OrientationFlags.EdgeSouthWest); break; case OrientationFlags.SideEast: player.SelectedPoint = new Vector2(selectionPoint.Value.Y, 1f - selectionPoint.Value.Z); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner101, OrientationFlags.Corner111, OrientationFlags.Corner100, OrientationFlags.Corner110); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeEastTop, OrientationFlags.EdgeEastBottom, OrientationFlags.EdgeSouthEast, OrientationFlags.EdgeNorthEast); break; case OrientationFlags.SideTop: player.SelectedPoint = new Vector2(selectionPoint.Value.X, 1f - selectionPoint.Value.Y); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner011, OrientationFlags.Corner111, OrientationFlags.Corner001, OrientationFlags.Corner101); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeNorthTop, OrientationFlags.EdgeSouthTop, OrientationFlags.EdgeWestTop, OrientationFlags.EdgeEastTop); break; case OrientationFlags.SideBottom: player.SelectedPoint = new Vector2(selectionPoint.Value.X, selectionPoint.Value.Y); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner000, OrientationFlags.Corner100, OrientationFlags.Corner010, OrientationFlags.Corner110); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeSouthBottom, OrientationFlags.EdgeNorthBottom, OrientationFlags.EdgeWestBottom, OrientationFlags.EdgeEastBottom); break; case OrientationFlags.SideNorth: player.SelectedPoint = new Vector2(1f - selectionPoint.Value.X, 1f - selectionPoint.Value.Z); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner111, OrientationFlags.Corner011, OrientationFlags.Corner110, OrientationFlags.Corner010); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeNorthTop, OrientationFlags.EdgeNorthBottom, OrientationFlags.EdgeNorthEast, OrientationFlags.EdgeNorthWest); break; case OrientationFlags.SideSouth: player.SelectedPoint = new Vector2(selectionPoint.Value.X, 1f - selectionPoint.Value.Z); player.SelectedCorner = FindCorner(player.SelectedPoint.Value, OrientationFlags.Corner001, OrientationFlags.Corner101, OrientationFlags.Corner000, OrientationFlags.Corner100); player.SelectedEdge = FindEdge(player.SelectedPoint.Value, OrientationFlags.EdgeSouthTop, OrientationFlags.EdgeSouthBottom, OrientationFlags.EdgeSouthWest, OrientationFlags.EdgeSouthEast); break; } player.SelectedPoint = new Vector2( Math.Min(1f, Math.Max(0f, player.SelectedPoint.Value.X)), Math.Min(1f, Math.Max(0f, player.SelectedPoint.Value.Y))); } else { player.SelectedBox = null; player.SelectedPoint = null; player.SelectedSide = OrientationFlags.None; player.SelectedEdge = OrientationFlags.None; player.SelectedCorner = OrientationFlags.None; } base.OnUpdate(gameTime); }
public override void Hit(IBlockDefinition block, PhysicalProperties itemProperties) { throw new NotImplementedException(); }
public IChunkColumn GenerateColumn(IDefinitionManager definitionManager, IPlanet planet, Index2 index) { IDefinition[] definitions = definitionManager.GetDefinitions().ToArray(); //TODO More Generic, überdenken der Planetgeneration im allgemeinen (Heapmap + Highmap + Biome + Modding) IBlockDefinition sandDefinition = definitions.OfType <SandBlockDefinition>().FirstOrDefault(); ushort sandIndex = (ushort)(Array.IndexOf(definitions.ToArray(), sandDefinition) + 1); IBlockDefinition snowDefinition = definitions.OfType <SnowBlockDefinition>().FirstOrDefault(); ushort snowIndex = (ushort)(Array.IndexOf(definitions.ToArray(), snowDefinition) + 1); IBlockDefinition groundDefinition = definitions.OfType <GroundBlockDefinition>().FirstOrDefault(); ushort groundIndex = (ushort)(Array.IndexOf(definitions.ToArray(), groundDefinition) + 1); IBlockDefinition stoneDefinition = definitions.OfType <StoneBlockDefinition>().FirstOrDefault(); ushort stoneIndex = (ushort)(Array.IndexOf(definitions.ToArray(), stoneDefinition) + 1); IBlockDefinition waterDefinition = definitions.OfType <WaterBlockDefinition>().FirstOrDefault(); ushort waterIndex = (ushort)(Array.IndexOf(definitions.ToArray(), waterDefinition) + 1); IBlockDefinition grassDefinition = definitions.OfType <GrassBlockDefinition>().FirstOrDefault(); ushort grassIndex = (ushort)(Array.IndexOf(definitions.ToArray(), grassDefinition) + 1); if (!(planet is ComplexPlanet)) { throw new ArgumentException("planet is not a Type of ComplexPlanet"); } ComplexPlanet localPlanet = (ComplexPlanet)planet; float[,] localHeightmap = localPlanet.BiomeGenerator.GetHeightmap(index); IChunk[] chunks = new IChunk[planet.Size.Z]; for (int i = 0; i < planet.Size.Z; i++) { chunks[i] = new Chunk(new Index3(index, i), planet.Id); } int obersteSchicht; bool surfaceBlock; bool ozeanSurface; for (int x = 0; x < Chunk.CHUNKSIZE_X; x++) { for (int y = 0; y < Chunk.CHUNKSIZE_Y; y++) { obersteSchicht = 5; surfaceBlock = true; ozeanSurface = false; for (int i = chunks.Length - 1; i >= 0; i--) { for (int z = Chunk.CHUNKSIZE_Z - 1; z >= 0; z--) { int absoluteZ = (z + (i * Chunk.CHUNKSIZE_Z)); if (absoluteZ <= localHeightmap[x, y] * localPlanet.Size.Z * Chunk.CHUNKSIZE_Z) { if (obersteSchicht > 0) { float temp = localPlanet.ClimateMap.GetTemperature(new Index3(index.X * Chunk.CHUNKSIZE_X + x, index.Y * Chunk.CHUNKSIZE_Y + y, i * Chunk.CHUNKSIZE_Z + z)); if ((ozeanSurface || surfaceBlock) && (absoluteZ <= (localPlanet.BiomeGenerator.SeaLevel + 2)) && (absoluteZ >= (localPlanet.BiomeGenerator.SeaLevel - 2))) { chunks[i].SetBlock(x, y, z, sandIndex); } else if (temp >= 35) { chunks[i].SetBlock(x, y, z, sandIndex); } else if (absoluteZ >= localPlanet.Size.Z * Chunk.CHUNKSIZE_Z * 0.6f) { if (temp > 12) { chunks[i].SetBlock(x, y, z, groundIndex); } else { chunks[i].SetBlock(x, y, z, stoneIndex); } } else if (temp >= 8) { if (surfaceBlock && !ozeanSurface) { chunks[i].SetBlock(x, y, z, grassIndex); surfaceBlock = false; } else { chunks[i].SetBlock(x, y, z, groundIndex); } } else if (temp <= 0) { if (surfaceBlock && !ozeanSurface) { chunks[i].SetBlock(x, y, z, snowIndex); surfaceBlock = false; } else { chunks[i].SetBlock(x, y, z, groundIndex); } } else { chunks[i].SetBlock(x, y, z, groundIndex); } obersteSchicht--; } else { chunks[i].SetBlock(x, y, z, stoneIndex); } } else if ((z + (i * Chunk.CHUNKSIZE_Z)) <= localPlanet.BiomeGenerator.SeaLevel) { chunks[i].SetBlock(x, y, z, waterIndex); ozeanSurface = true; } } } } } ChunkColumn column = new ChunkColumn(chunks, planet.Id, index); column.CalculateHeights(); return(column); }
/// <summary> /// Aktualisiert den Spieler (Bewegung, Interaktion) /// </summary> /// <param name="frameTime">Die aktuelle Zeit.</param> public void Update(GameTime frameTime) { #region Inputverarbeitung // Input verarbeiten Player.Angle += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.X; Player.Tilt += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.Y; Player.Tilt = Math.Min(1.5f, Math.Max(-1.5f, Player.Tilt)); #endregion #region Physik float lookX = (float)Math.Cos(Player.Angle); float lookY = -(float)Math.Sin(Player.Angle); var velocitydirection = new Vector3(lookX, lookY, 0) * Move.Y; float stafeX = (float)Math.Cos(Player.Angle + MathHelper.PiOver2); float stafeY = -(float)Math.Sin(Player.Angle + MathHelper.PiOver2); velocitydirection += new Vector3(stafeX, stafeY, 0) * Move.X; Player.Velocity += PhysicalUpdate(velocitydirection, frameTime.ElapsedGameTime, !Player.FlyMode, Player.FlyMode); #endregion #region Playerbewegung Vector3 move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds; Player.OnGround = false; bool collision = false; int loop = 0; do { int minx = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.X - Player.Radius, Player.Position.BlockPosition.X - Player.Radius + move.X)); int maxx = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.X + Player.Radius, Player.Position.BlockPosition.X + Player.Radius + move.X)); int miny = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Y - Player.Radius, Player.Position.BlockPosition.Y - Player.Radius + move.Y)); int maxy = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.Y + Player.Radius, Player.Position.BlockPosition.Y + Player.Radius + move.Y)); int minz = (int)Math.Floor(Math.Min( Player.Position.BlockPosition.Z, Player.Position.BlockPosition.Z + move.Z)); int maxz = (int)Math.Floor(Math.Max( Player.Position.BlockPosition.Z + Player.Height, Player.Position.BlockPosition.Z + Player.Height + move.Z)); // Relative PlayerBox BoundingBox playerBox = new BoundingBox( new Vector3( Player.Position.BlockPosition.X - Player.Radius, Player.Position.BlockPosition.Y - Player.Radius, Player.Position.BlockPosition.Z), new Vector3( Player.Position.BlockPosition.X + Player.Radius, Player.Position.BlockPosition.Y + Player.Radius, Player.Position.BlockPosition.Z + Player.Height)); collision = false; float min = 1f; Axis minAxis = Axis.None; for (int z = minz; z <= maxz; z++) { for (int y = miny; y <= maxy; y++) { for (int x = minx; x <= maxx; x++) { Index3 pos = new Index3(x, y, z); Index3 blockPos = pos + Player.Position.GlobalBlockIndex; ushort block = localChunkCache.GetBlock(blockPos); if (block == 0) { continue; } Axis? localAxis; IBlockDefinition blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(block); float? moveFactor = Block.Intersect( blockDefinition.GetCollisionBoxes(localChunkCache, blockPos.X, blockPos.Y, blockPos.Z), pos, playerBox, move, out localAxis); if (moveFactor.HasValue && moveFactor.Value < min) { collision = true; min = moveFactor.Value; minAxis = localAxis.Value; } } } } Player.Position += (move * min); move *= (1f - min); switch (minAxis) { case Axis.X: Player.Velocity *= new Vector3(0, 1, 1); Player.Position += new Vector3(move.X > 0 ? -Gap : Gap, 0, 0); move.X = 0f; break; case Axis.Y: Player.Velocity *= new Vector3(1, 0, 1); Player.Position += new Vector3(0, move.Y > 0 ? -Gap : Gap, 0); move.Y = 0f; break; case Axis.Z: Player.OnGround = true; Player.Velocity *= new Vector3(1, 1, 0); Player.Position += new Vector3(0, 0, move.Z > 0 ? -Gap : Gap); move.Z = 0f; break; } // Koordinate normalisieren (Rundwelt) Coordinate position = Player.Position; position.NormalizeChunkIndexXY(planet.Size); //Beam me up KeyboardState ks = Keyboard.GetState(); if (ks.IsKeyDown(Keys.P)) { position = position + new Vector3(0, 0, 10); } Player.Position = position; loop++; }while (collision && loop < 3); if (Player.Position.ChunkIndex != _oldIndex) { _oldIndex = Player.Position.ChunkIndex; ReadyState = false; localChunkCache.SetCenter(planet, new Index2(Player.Position.ChunkIndex), (success) => { ReadyState = success; }); } #endregion #region Block Interaction if (lastInteract.HasValue) { ushort lastBlock = localChunkCache.GetBlock(lastInteract.Value); localChunkCache.SetBlock(lastInteract.Value, 0); if (lastBlock != 0) { var blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(lastBlock); var slot = Player.Inventory.Where(s => s.Definition == blockDefinition && s.Amount < blockDefinition.StackLimit).FirstOrDefault(); // Wenn noch kein Slot da ist oder der vorhandene voll, dann neuen Slot if (slot == null || slot.Amount >= blockDefinition.StackLimit) { slot = new InventorySlot() { Definition = blockDefinition, Amount = 0 }; Player.Inventory.Add(slot); } slot.Amount++; } lastInteract = null; } if (lastApply.HasValue) { if (ActiveTool != null) { Index3 add = new Index3(); switch (lastOrientation) { case OrientationFlags.SideWest: add = new Index3(-1, 0, 0); break; case OrientationFlags.SideEast: add = new Index3(1, 0, 0); break; case OrientationFlags.SideSouth: add = new Index3(0, -1, 0); break; case OrientationFlags.SideNorth: add = new Index3(0, 1, 0); break; case OrientationFlags.SideBottom: add = new Index3(0, 0, -1); break; case OrientationFlags.SideTop: add = new Index3(0, 0, 1); break; } if (ActiveTool.Definition is IBlockDefinition) { IBlockDefinition definition = ActiveTool.Definition as IBlockDefinition; localChunkCache.SetBlock(lastApply.Value + add, DefinitionManager.Instance.GetBlockDefinitionIndex(definition)); ActiveTool.Amount--; if (ActiveTool.Amount <= 0) { Player.Inventory.Remove(ActiveTool); ActiveTool = null; } } // TODO: Fix Interaction ;) //ushort block = _manager.GetBlock(lastApply.Value); //IBlockDefinition blockDefinition = BlockDefinitionManager.GetForType(block); //IItemDefinition itemDefinition = ActiveTool.Definition; //blockDefinition.Hit(blockDefinition, itemDefinition.GetProperties(null)); //itemDefinition.Hit(null, blockDefinition.GetProperties(block)); } lastApply = null; } #endregion }
/// <summary> This method copy's each database field into the <paramref name="target"/> interface. </summary> public void Copy_To(IBlockDefinition target, bool includePrimaryKey = false) { if (includePrimaryKey) target.Id = this.Id; target.NameId = this.NameId; target.PageId = this.PageId; target.BlockPlayingOrder = this.BlockPlayingOrder; target.MinPositionLeft = this.MinPositionLeft; target.MaxPositionRight = this.MaxPositionRight; target.MinPositionTop = this.MinPositionTop; target.MaxPositionBottom = this.MaxPositionBottom; target.BlockRotation = this.BlockRotation; target.BlockType = this.BlockType; }
public void LatestBlockBroadcast(IBlockDefinition latestblock) { System.Diagnostics.Debug.Print("LatestBlockBroadcast"); }