From dff4877fd66b716ba2a0cf3e3bcd1aea291215d9 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 21 Nov 2015 17:44:47 +1100 Subject: [PATCH] Start work on rain particles. --- ClassicalSharp/ClassicalSharp.csproj | 2 + .../Entities/Particles/CollidableParticle.cs | 64 ++++++++++++++++++ ClassicalSharp/Entities/Particles/Particle.cs | 4 +- .../Entities/Particles/RainParticle.cs | 31 +++++++++ .../Entities/Particles/TerrainParticle.cs | 66 +++---------------- ClassicalSharp/Game/InputHandler.cs | 6 +- ClassicalSharp/Game/KeyMap.cs | 2 +- ClassicalSharp/Hotkeys/HotkeyList.cs | 2 +- ClassicalSharp/Utils/Options.cs | 14 +++- ClassicalSharp/Utils/Utils.cs | 13 ++-- 10 files changed, 128 insertions(+), 76 deletions(-) create mode 100644 ClassicalSharp/Entities/Particles/CollidableParticle.cs create mode 100644 ClassicalSharp/Entities/Particles/RainParticle.cs diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 5e8713b8c..c31dd718e 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -130,8 +130,10 @@ + + diff --git a/ClassicalSharp/Entities/Particles/CollidableParticle.cs b/ClassicalSharp/Entities/Particles/CollidableParticle.cs new file mode 100644 index 000000000..cd785d2b9 --- /dev/null +++ b/ClassicalSharp/Entities/Particles/CollidableParticle.cs @@ -0,0 +1,64 @@ +using System; +using OpenTK; + +namespace ClassicalSharp.Particles { + + public abstract class CollidableParticle : Particle { + + const float gravity = 3.4f; + + public CollidableParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) + : base( game, pos, velocity, lifetime ) { + } + + public override bool Tick( double delta ) { + lastPos = Position = nextPos; + byte curBlock = game.Map.SafeGetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z ); + if( !CanPassThrough( curBlock ) ) return true; + + Velocity.Y -= gravity * (float)delta; + int startY = (int)Math.Floor( Position.Y ); + Position += Velocity * (float)delta * 3; + int endY = (int)Math.Floor( Position.Y ); + Utils.Clamp( ref Position.X, 0, game.Map.Width - 0.01f ); + Utils.Clamp( ref Position.Z, 0, game.Map.Length - 0.01f ); + + if( Velocity.Y > 0 ) { + for( int y = startY; y <= endY && TestY( y, false ); y++ ); + } else { + for( int y = startY; y >= endY && TestY( y, true ); y-- ); + } + nextPos = Position; + Position = lastPos; + return base.Tick( delta ); + } + + bool TestY( int y, bool topFace ) { + if( y < 0 ) { + Position.Y = nextPos.Y = lastPos.Y = 0 + Entity.Adjustment; + Velocity = Vector3.Zero; + return false; + } + + byte block = game.Map.SafeGetBlock( (int)Position.X, y, (int)Position.Z ); + if( CanPassThrough( block ) ) return true; + + float collideY = y; + if( topFace ) + collideY += game.BlockInfo.Height[block]; + + bool collide = topFace ? (Position.Y < collideY) : (Position.Y > collideY ); + if( collide ) { + float adjust = topFace ? Entity.Adjustment : -Entity.Adjustment; + Position.Y = nextPos.Y = lastPos.Y = collideY + adjust; + Velocity = Vector3.Zero; + return false; + } + return true; + } + + bool CanPassThrough( byte block ) { + return block == 0 || game.BlockInfo.IsSprite[block] || game.BlockInfo.IsLiquid[block]; + } + } +} diff --git a/ClassicalSharp/Entities/Particles/Particle.cs b/ClassicalSharp/Entities/Particles/Particle.cs index 99167dcb5..1a1cc23fe 100644 --- a/ClassicalSharp/Entities/Particles/Particle.cs +++ b/ClassicalSharp/Entities/Particles/Particle.cs @@ -7,7 +7,6 @@ namespace ClassicalSharp.Particles { public Vector3 Position; public Vector3 Velocity; - public TextureRec Rectangle; public float Lifetime; protected Game game; protected Vector3 lastPos, nextPos; @@ -16,12 +15,11 @@ namespace ClassicalSharp.Particles { public abstract void Dispose(); - public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime, TextureRec rec ) { + public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) { this.game = game; Position = lastPos = nextPos = pos; Velocity = velocity; Lifetime = (float)lifetime; - Rectangle = rec; } public virtual bool Tick( double delta ) { diff --git a/ClassicalSharp/Entities/Particles/RainParticle.cs b/ClassicalSharp/Entities/Particles/RainParticle.cs new file mode 100644 index 000000000..f7ea67790 --- /dev/null +++ b/ClassicalSharp/Entities/Particles/RainParticle.cs @@ -0,0 +1,31 @@ +using System; +using OpenTK; + +namespace ClassicalSharp.Particles { + + public sealed class RainParticle : CollidableParticle { + + static Vector2 rainSize = new Vector2( 1/8f, 1/8f ); + static TextureRec rec = new TextureRec( 2/128f, 14/128f, 3/128f, 2/128f ); + public RainParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) + : base( game, pos, velocity, lifetime ) { + } + + public override void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ) { + Position = Vector3.Lerp( lastPos, nextPos, t ); + Vector3 p111, p121, p212, p222; + Utils.CalcBillboardPoints( rainSize, Position, ref game.View, + out p111, out p121, out p212, out p222 ); + Map map = game.Map; + FastColour col = map.IsLit( Vector3I.Floor( Position ) ) ? map.Sunlight : map.Shadowlight; + + vertices[index++] = new VertexPos3fTex2fCol4b( p111, rec.U1, rec.V2, col ); + vertices[index++] = new VertexPos3fTex2fCol4b( p121, rec.U1, rec.V1, col ); + 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 fd813bebe..b1e037359 100644 --- a/ClassicalSharp/Entities/Particles/TerrainParticle.cs +++ b/ClassicalSharp/Entities/Particles/TerrainParticle.cs @@ -3,13 +3,13 @@ using OpenTK; namespace ClassicalSharp.Particles { - public sealed class TerrainParticle : Particle { + public sealed class TerrainParticle : CollidableParticle { - const float gravity = 3.4f; static Vector2 terrainSize = new Vector2( 1/8f, 1/8f ); - + TextureRec rec; public TerrainParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime, TextureRec rec ) - : base( game, pos, velocity, lifetime, rec ) { + : base( game, pos, velocity, lifetime ) { + this.rec = rec; } public override void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ) { @@ -20,60 +20,10 @@ namespace ClassicalSharp.Particles { Map map = game.Map; FastColour col = map.IsLit( Vector3I.Floor( Position ) ) ? map.Sunlight : map.Shadowlight; - vertices[index++] = new VertexPos3fTex2fCol4b( p111, Rectangle.U1, Rectangle.V2, col ); - vertices[index++] = new VertexPos3fTex2fCol4b( p121, Rectangle.U1, Rectangle.V1, col ); - vertices[index++] = new VertexPos3fTex2fCol4b( p222, Rectangle.U2, Rectangle.V1, col ); - vertices[index++] = new VertexPos3fTex2fCol4b( p212, Rectangle.U2, Rectangle.V2, col ); - } - - public override bool Tick( double delta ) { - lastPos = Position = nextPos; - byte curBlock = game.Map.SafeGetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z ); - if( !CanPassThrough( curBlock ) ) return true; - - Velocity.Y -= gravity * (float)delta; - int startY = (int)Math.Floor( Position.Y ); - Position += Velocity * (float)delta * 3; - int endY = (int)Math.Floor( Position.Y ); - Utils.Clamp( ref Position.X, 0, game.Map.Width - 0.01f ); - Utils.Clamp( ref Position.Z, 0, game.Map.Length - 0.01f ); - - if( Velocity.Y > 0 ) { - for( int y = startY; y <= endY && TestY( y, false ); y++ ); - } else { - for( int y = startY; y >= endY && TestY( y, true ); y-- ); - } - nextPos = Position; - Position = lastPos; - return base.Tick( delta ); - } - - bool TestY( int y, bool topFace ) { - if( y < 0 ) { - Position.Y = nextPos.Y = lastPos.Y = 0 + Entity.Adjustment; - Velocity = Vector3.Zero; - return false; - } - - byte block = game.Map.SafeGetBlock( (int)Position.X, y, (int)Position.Z ); - if( CanPassThrough( block ) ) return true; - - float collideY = y; - if( topFace ) - collideY += game.BlockInfo.Height[block]; - - bool collide = topFace ? (Position.Y < collideY) : (Position.Y > collideY ); - if( collide ) { - float adjust = topFace ? Entity.Adjustment : -Entity.Adjustment; - Position.Y = nextPos.Y = lastPos.Y = collideY + adjust; - Velocity = Vector3.Zero; - return false; - } - return true; - } - - bool CanPassThrough( byte block ) { - return block == 0 || game.BlockInfo.IsSprite[block] || game.BlockInfo.IsLiquid[block]; + vertices[index++] = new VertexPos3fTex2fCol4b( p111, rec.U1, rec.V2, col ); + vertices[index++] = new VertexPos3fTex2fCol4b( p121, rec.U1, rec.V1, col ); + 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/InputHandler.cs b/ClassicalSharp/Game/InputHandler.cs index 5ccc88cf5..fd80820da 100644 --- a/ClassicalSharp/Game/InputHandler.cs +++ b/ClassicalSharp/Game/InputHandler.cs @@ -30,9 +30,9 @@ namespace ClassicalSharp { Key mapLeft, mapMiddle, mapRight; void LoadMouseToKeyMappings() { - mapLeft = Options.GetKey( OptionsKey.MouseLeft, Key.Unknown ); - mapMiddle = Options.GetKey( OptionsKey.MouseMiddle, Key.Unknown ); - mapRight = Options.GetKey( OptionsKey.MouseRight, Key.Unknown ); + mapLeft = Options.GetEnum( OptionsKey.MouseLeft, Key.Unknown ); + mapMiddle = Options.GetEnum( OptionsKey.MouseMiddle, Key.Unknown ); + mapRight = Options.GetEnum( OptionsKey.MouseRight, Key.Unknown ); } public KeyMap Keys; diff --git a/ClassicalSharp/Game/KeyMap.cs b/ClassicalSharp/Game/KeyMap.cs index bedbb104f..2844e123c 100644 --- a/ClassicalSharp/Game/KeyMap.cs +++ b/ClassicalSharp/Game/KeyMap.cs @@ -55,7 +55,7 @@ namespace ClassicalSharp { string[] names = KeyBinding.GetNames( typeof( KeyBinding ) ); for( int i = 0; i < names.Length; i++ ) { string key = "key-" + names[i]; - Key mapping = Options.GetKey( key, Keys[i] ); + Key mapping = Options.GetEnum( key, Keys[i] ); if( !IsReservedKey( mapping ) ) Keys[i] = mapping; } diff --git a/ClassicalSharp/Hotkeys/HotkeyList.cs b/ClassicalSharp/Hotkeys/HotkeyList.cs index 273f1bde7..78244faf0 100644 --- a/ClassicalSharp/Hotkeys/HotkeyList.cs +++ b/ClassicalSharp/Hotkeys/HotkeyList.cs @@ -99,7 +99,7 @@ namespace ClassicalSharp.Hotkeys { // Then try to parse the key and value Key key; byte flags; bool moreInput; - if( !Utils.TryParseKey( strKey, Key.Unknown, out key ) || + if( !Utils.TryParseEnum( strKey, Key.Unknown, out key ) || !Byte.TryParse( strFlags, out flags ) || !Boolean.TryParse( strMoreInput, out moreInput ) || strText.Length == 0 ) { diff --git a/ClassicalSharp/Utils/Options.cs b/ClassicalSharp/Utils/Options.cs index edc90d0ae..c679d4b0a 100644 --- a/ClassicalSharp/Utils/Options.cs +++ b/ClassicalSharp/Utils/Options.cs @@ -23,6 +23,14 @@ namespace ClassicalSharp { public const string VSync = "vsync"; } + public enum FpsLimit { + LimitVSync, + Limit30FPS, + Limit60FPS, + Limit120FPS, + LimitNone, + } + public static class Options { public static Dictionary OptionsSet = new Dictionary(); @@ -64,15 +72,15 @@ namespace ClassicalSharp { return valueFloat; } - public static Key GetKey( string key, Key defValue ) { + public static T GetEnum( string key, T defValue ) { string value = Options.Get( key.ToLower() ); if( value == null ) { Set( key, defValue ); return defValue; } - Key mapping; - if( !Utils.TryParseKey( value, defValue, out mapping ) ) + T mapping; + if( !Utils.TryParseEnum( value, defValue, out mapping ) ) Options.Set( key, defValue ); return mapping; } diff --git a/ClassicalSharp/Utils/Utils.cs b/ClassicalSharp/Utils/Utils.cs index b3cecf897..dc43f1d54 100644 --- a/ClassicalSharp/Utils/Utils.cs +++ b/ClassicalSharp/Utils/Utils.cs @@ -128,16 +128,15 @@ namespace ClassicalSharp { /// Attempts to caselessly parse the given string as a Key enum member, /// returning defValue if there was an error parsing. - public static bool TryParseKey( string value, Key defValue, out Key key ) { - Key mapping; + public static bool TryParseEnum( string value, T defValue, out T result ) { + T mapping; try { - mapping = (Key)Enum.Parse( typeof( Key ), value, true ); + mapping = (T)Enum.Parse( typeof( T ), value, true ); } catch( ArgumentException ) { - key = defValue; + result = defValue; return false; - } - - key = mapping; + } + result = mapping; return true; }