From 0defe3b66c282c8101fc451d1c343a7c14182be4 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 22 Nov 2015 23:58:10 +1100 Subject: [PATCH] Block break particles should account for block height, more work on rain particles. --- ClassicalSharp/2D/Screens/ChatScreen.cs | 8 +- ClassicalSharp/Entities/Particles/Particle.cs | 4 +- .../Entities/Particles/ParticleManager.cs | 117 ++++++++++++------ .../Entities/Particles/RainParticle.cs | 3 - .../Entities/Particles/TerrainParticle.cs | 3 - ClassicalSharp/Game/ChatLog.cs | 2 +- ClassicalSharp/Game/Game.cs | 2 +- ClassicalSharp/Rendering/WeatherRenderer.cs | 6 + .../TexturePack/TexturePackExtractor.cs | 3 + .../Gui/Screens/ClassiCubeServersScreen.cs | 11 ++ Launcher2/Gui/Screens/LauncherInputScreen.cs | 2 +- .../Gui/TableWidget/LauncherTableWidget.cs | 4 +- 12 files changed, 108 insertions(+), 57 deletions(-) diff --git a/ClassicalSharp/2D/Screens/ChatScreen.cs b/ClassicalSharp/2D/Screens/ChatScreen.cs index d63a131a1..5ae9efc3f 100644 --- a/ClassicalSharp/2D/Screens/ChatScreen.cs +++ b/ClassicalSharp/2D/Screens/ChatScreen.cs @@ -80,12 +80,14 @@ namespace ClassicalSharp { Font chatFont, chatInputFont, chatUnderlineFont, announcementFont; public override void Init() { int fontSize = (int)(12 * game.GuiScale() * game.ChatScale); - Utils.Clamp( ref fontSize, 8, 60 ); - + Utils.Clamp( ref fontSize, 8, 60 ); chatFont = new Font( "Arial", fontSize ); chatInputFont = new Font( "Arial", fontSize, FontStyle.Bold ); chatUnderlineFont = new Font( "Arial", fontSize, FontStyle.Underline ); - announcementFont = new Font( "Arial", 14 ); + + fontSize = (int)(14 * game.GuiScale()); + Utils.Clamp( ref fontSize, 8, 60 ); + announcementFont = new Font( "Arial", fontSize ); blockSize = (int)(40 * game.GuiScale()); textInput = new TextInputWidget( game, chatFont, chatInputFont ); diff --git a/ClassicalSharp/Entities/Particles/Particle.cs b/ClassicalSharp/Entities/Particles/Particle.cs index 1a1cc23fe..6ff57d9f9 100644 --- a/ClassicalSharp/Entities/Particles/Particle.cs +++ b/ClassicalSharp/Entities/Particles/Particle.cs @@ -3,7 +3,7 @@ using OpenTK; namespace ClassicalSharp.Particles { - public abstract class Particle : IDisposable { + public abstract class Particle { public Vector3 Position; public Vector3 Velocity; @@ -13,8 +13,6 @@ namespace ClassicalSharp.Particles { public abstract void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ); - public abstract void Dispose(); - public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) { this.game = game; Position = lastPos = nextPos = pos; diff --git a/ClassicalSharp/Entities/Particles/ParticleManager.cs b/ClassicalSharp/Entities/Particles/ParticleManager.cs index 37db3f01b..3139736b8 100644 --- a/ClassicalSharp/Entities/Particles/ParticleManager.cs +++ b/ClassicalSharp/Entities/Particles/ParticleManager.cs @@ -7,54 +7,71 @@ namespace ClassicalSharp.Particles { public class ParticleManager : IDisposable { - List particles = new List(); + public int ParticlesTexId; + List terrainParticles = new List(); + List rainParticles = new List(); Game game; - IGraphicsApi graphics; + Random rnd; int vb; public ParticleManager( Game game ) { this.game = game; - graphics = game.Graphics; - vb = graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 1000 ); + rnd = new Random(); + vb = game.Graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 1000 ); } VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[0]; public void Render( double delta, float t ) { - if( particles.Count == 0 ) return; - - int count = particles.Count * 4; - if( count > vertices.Length ) { - vertices = new VertexPos3fTex2fCol4b[count]; - } - int index = 0; - for( int i = 0; i < particles.Count; i++ ) { - particles[i].Render( delta, t, vertices, ref index ); - } - + if( terrainParticles.Count == 0 && rainParticles.Count == 0 ) return; + IGraphicsApi graphics = game.Graphics; graphics.Texturing = true; - graphics.BindTexture( game.TerrainAtlas.TexId ); graphics.AlphaTest = true; - count = Math.Min( count, 1000 ); - graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b ); - graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 ); + + int count = RenderParticles( terrainParticles, delta, t ); + if( count > 0 ) { + graphics.BindTexture( game.TerrainAtlas.TexId ); + graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 ); + } + count = 0;//RenderParticles( rainParticles, delta, t ); + if( count > 0 ) { + graphics.BindTexture( ParticlesTexId ); + graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 ); + } + graphics.AlphaTest = false; graphics.Texturing = false; } + int RenderParticles( List particles, double delta, float t ) { + int count = particles.Count * 4; + if( count > vertices.Length ) + vertices = new VertexPos3fTex2fCol4b[count]; + + int index = 0; + for( int i = 0; i < particles.Count; i++ ) + particles[i].Render( delta, t, vertices, ref index ); + return Math.Min( count, 1000 ); + } + public void Tick( double delta ) { + TickParticles( terrainParticles, delta ); + //TickParticles( rainParticles, delta ); + } + + void TickParticles( List particles, double delta ) { for( int i = 0; i < particles.Count; i++ ) { Particle particle = particles[i]; - if( particle.Tick( delta ) ) { + if( particle.Tick( delta ) ) { particles.RemoveAt( i ); i--; - particle.Dispose(); } } } public void Dispose() { - graphics.DeleteDynamicVb( vb ); + game.Graphics.DeleteDynamicVb( vb ); + game.Graphics.DeleteTexture( ref ParticlesTexId ); } public void BreakBlockEffect( Vector3I position, byte block ) { @@ -62,30 +79,50 @@ namespace ClassicalSharp.Particles { int texLoc = game.BlockInfo.GetTextureLoc( block, TileSide.Left ); TextureRec rec = game.TerrainAtlas.GetTexRec( texLoc ); - float invSize = TerrainAtlas2D.invElementSize; - int cellsCountX = (int)( 0.25f / invSize ); - int cellsCountY = (int)( 0.25f / invSize ); - float elementXSize = invSize * 0.25f; - float elementYSize = invSize * 0.25f; + const float invSize = TerrainAtlas2D.invElementSize; + const int cellsCount = (int)((1/4f) / invSize); + const float elemSize = invSize / 4f; + float blockHeight = game.BlockInfo.Height[block]; - Random rnd = new Random(); for( int i = 0; i < 25; i++ ) { - double velX = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/; - double velZ = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/; - double velY = ( rnd.NextDouble() + 0.25 ) * game.BlockInfo.Height[block]; + double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4] + double velZ = rnd.NextDouble() * 0.8 - 0.4; + double velY = rnd.NextDouble() + 0.2; Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ ); - double xOffset = rnd.NextDouble() - 0.125; - double yOffset = rnd.NextDouble() - 0.125; - double zOffset = rnd.NextDouble() - 0.125; - Vector3 pos = startPos + new Vector3( (float)xOffset, (float)yOffset, (float)zOffset ); + + double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5] + double yOffset = (rnd.NextDouble() - 0.125) * blockHeight; + double zOffset = rnd.NextDouble() - 0.5; + Vector3 pos = startPos + new Vector3( 0.5f + (float)xOffset, + (float)yOffset, 0.5f + (float)zOffset ); + TextureRec particleRec = rec; - particleRec.U1 = (float)( rec.U1 + rnd.Next( 0, cellsCountX ) * elementXSize ); - particleRec.V1 = (float)( rec.V1 + rnd.Next( 0, cellsCountY ) * elementYSize ); - particleRec.U2 = particleRec.U1 + elementXSize; - particleRec.V2 = particleRec.V1 + elementYSize; + particleRec.U1 = rec.U1 + rnd.Next( 0, cellsCount ) * elemSize; + particleRec.V1 = rec.V1 + rnd.Next( 0, cellsCount ) * elemSize; + particleRec.U2 = particleRec.U1 + elemSize; + particleRec.V2 = particleRec.V1 + elemSize; double life = 1.5 - rnd.NextDouble(); - particles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) ); + terrainParticles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) ); + } + } + + public void AddRainParticle( Vector3 pos ) { + Vector3 startPos = pos; + + for( int i = 0; i < 5; i++ ) { + double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4] + double velZ = rnd.NextDouble() * 0.8 - 0.4; + double velY = rnd.NextDouble() + 0.2; + Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ ); + + double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5] + double yOffset = rnd.NextDouble() - 0.125; + double zOffset = rnd.NextDouble() - 0.5; + pos = startPos + new Vector3( 0.5f + (float)xOffset, + (float)yOffset, 0.5f + (float)zOffset ); + double life = 1.5 - rnd.NextDouble(); + rainParticles.Add( new RainParticle( game, pos, velocity, life ) ); } } } diff --git a/ClassicalSharp/Entities/Particles/RainParticle.cs b/ClassicalSharp/Entities/Particles/RainParticle.cs index f7ea67790..32bc11e9e 100644 --- a/ClassicalSharp/Entities/Particles/RainParticle.cs +++ b/ClassicalSharp/Entities/Particles/RainParticle.cs @@ -24,8 +24,5 @@ namespace ClassicalSharp.Particles { vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col ); } - - public override void Dispose() { - } } } diff --git a/ClassicalSharp/Entities/Particles/TerrainParticle.cs b/ClassicalSharp/Entities/Particles/TerrainParticle.cs index b1e037359..eabe5020b 100644 --- a/ClassicalSharp/Entities/Particles/TerrainParticle.cs +++ b/ClassicalSharp/Entities/Particles/TerrainParticle.cs @@ -25,8 +25,5 @@ namespace ClassicalSharp.Particles { vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col ); vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col ); } - - public override void Dispose() { - } } } diff --git a/ClassicalSharp/Game/ChatLog.cs b/ClassicalSharp/Game/ChatLog.cs index efecafe85..ff377894e 100644 --- a/ClassicalSharp/Game/ChatLog.cs +++ b/ClassicalSharp/Game/ChatLog.cs @@ -82,7 +82,7 @@ namespace ClassicalSharp { last = now; if( writer != null ) { - string data = text;//Utils.StripColours( text ); + string data = Utils.StripColours( text ); string entry = now.ToString( "[yyyy-MM-dd HH:mm:ss] " ) + data; writer.WriteLine( entry ); } diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index d3141a3b6..a2458ea67 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -126,6 +126,7 @@ namespace ClassicalSharp { ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 ); InputHandler = new InputHandler( this ); Chat = new ChatLog( this ); + ParticleManager = new ParticleManager( this ); HudScale = Options.GetFloat( OptionsKey.HudScale, 0.25f, 5f, 1f ); ChatScale = Options.GetFloat( OptionsKey.ChatScale, 0.35f, 5f, 1f ); defaultIb = Graphics.MakeDefaultIb(); @@ -173,7 +174,6 @@ namespace ClassicalSharp { CommandManager = new CommandManager(); CommandManager.Init( this ); SelectionManager = new SelectionManager( this ); - ParticleManager = new ParticleManager( this ); WeatherRenderer = new WeatherRenderer( this ); WeatherRenderer.Init(); BlockHandRenderer = new BlockHandRenderer( this ); diff --git a/ClassicalSharp/Rendering/WeatherRenderer.cs b/ClassicalSharp/Rendering/WeatherRenderer.cs index 49ad3a4fb..2f1e72bbd 100644 --- a/ClassicalSharp/Rendering/WeatherRenderer.cs +++ b/ClassicalSharp/Rendering/WeatherRenderer.cs @@ -23,6 +23,7 @@ namespace ClassicalSharp { float vOffset; const int extent = 4; VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * (extent * 2 + 1) * (extent * 2 + 1)]; + double rainAcc; public void Render( double deltaTime ) { Weather weather = map.Weather; @@ -33,6 +34,7 @@ namespace ClassicalSharp { Vector3I pos = Vector3I.Floor( game.LocalPlayer.Position ); float speed = weather == Weather.Rainy ? 1f : 0.25f; vOffset = -(float)game.accumulator * speed; + rainAcc += deltaTime; int index = 0; graphics.AlphaBlending = true; @@ -44,10 +46,14 @@ namespace ClassicalSharp { float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY; if( height <= 0 ) continue; + //if( rainAcc >= 3 ) + // game.ParticleManager.AddRainParticle( new Vector3( pos.X + dx, rainY, pos.Z + dz ) ); col.A = (byte)Math.Max( 0, AlphaAt( dx * dx + dz * dz ) ); MakeRainForSquare( pos.X + dx, rainY, height, pos.Z + dz, col, ref index ); } } + if( rainAcc >= 3 ) + rainAcc = 0; // fixes crashing on nVidia cards in OpenGL builds. if( index > 0 ) { diff --git a/ClassicalSharp/TexturePack/TexturePackExtractor.cs b/ClassicalSharp/TexturePack/TexturePackExtractor.cs index 816612a72..f082a6d44 100644 --- a/ClassicalSharp/TexturePack/TexturePackExtractor.cs +++ b/ClassicalSharp/TexturePack/TexturePackExtractor.cs @@ -78,6 +78,9 @@ namespace ClassicalSharp.TexturePack { StreamReader reader = new StreamReader( stream ); game.Animations.ReadAnimationsDescription( reader ); break; + case "particles.png": + UpdateTexture( ref game.ParticleManager.ParticlesTexId, + stream, false ); break; case "default.png": SetFontBitmap( game, stream ); break; diff --git a/Launcher2/Gui/Screens/ClassiCubeServersScreen.cs b/Launcher2/Gui/Screens/ClassiCubeServersScreen.cs index d48e90eba..f392fb7bc 100644 --- a/Launcher2/Gui/Screens/ClassiCubeServersScreen.cs +++ b/Launcher2/Gui/Screens/ClassiCubeServersScreen.cs @@ -40,6 +40,17 @@ namespace Launcher2 { protected override void OnRemovedChar() { FilterList(); } + protected override void KeyDown( object sender, KeyboardKeyEventArgs e ) { + if( e.Key == Key.Enter ) { + LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex]; + if( table.Count == 1 ) + widgets[3].Text = table.usedEntries[0].Hash; + ConnectToServer( 0, 0 ); + } else { + base.KeyDown( sender, e ); + } + } + void FilterList() { if( lastInput == widgets[1] ) { LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex]; diff --git a/Launcher2/Gui/Screens/LauncherInputScreen.cs b/Launcher2/Gui/Screens/LauncherInputScreen.cs index ce7899da2..e1f08e394 100644 --- a/Launcher2/Gui/Screens/LauncherInputScreen.cs +++ b/Launcher2/Gui/Screens/LauncherInputScreen.cs @@ -24,7 +24,7 @@ namespace Launcher2 { game.Window.Keyboard.KeyRepeat = true; } - protected void KeyDown( object sender, KeyboardKeyEventArgs e ) { + protected virtual void KeyDown( object sender, KeyboardKeyEventArgs e ) { if( lastInput != null && e.Key == Key.BackSpace ) { if( lastInput.RemoveChar() ) { RedrawLastInput(); diff --git a/Launcher2/Gui/TableWidget/LauncherTableWidget.cs b/Launcher2/Gui/TableWidget/LauncherTableWidget.cs index 7de01235b..2548df081 100644 --- a/Launcher2/Gui/TableWidget/LauncherTableWidget.cs +++ b/Launcher2/Gui/TableWidget/LauncherTableWidget.cs @@ -15,7 +15,7 @@ namespace Launcher2 { public Action SelectedChanged; public string SelectedHash; - TableEntry[] entries, usedEntries; + internal TableEntry[] entries, usedEntries; internal List servers; public void SetEntries( List servers ) { entries = new TableEntry[servers.Count]; @@ -56,7 +56,7 @@ namespace Launcher2 { public int[] ColumnWidths = { 280, 80, 80 }; public int[] DesiredColumnWidths = { 280, 80, 80 }; - struct TableEntry { + internal struct TableEntry { public string Hash, Name, Players, Uptime; public int Y, Height; }