From 5e131878920d6fd516c0614dca88c5dcb6eaea69 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 22 Apr 2016 17:42:09 +1000 Subject: [PATCH] Move step sound handling into a separate entity component. --- .../Widgets/Chat/TextGroupWidget.Formatter.cs | 2 +- .../2D/Widgets/Chat/TextGroupWidget.cs | 2 +- ClassicalSharp/ClassicalSharp.csproj | 1 + .../Entities/Components/SoundComponent.cs | 87 +++++++++++++++++++ ClassicalSharp/Entities/LocalPlayer.cs | 74 ++-------------- 5 files changed, 97 insertions(+), 69 deletions(-) create mode 100644 ClassicalSharp/Entities/Components/SoundComponent.cs diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs index cc9891d62..c9ce872a7 100644 --- a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs +++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs @@ -16,7 +16,7 @@ namespace ClassicalSharp.Gui { if( !String.IsNullOrEmpty( text ) ) { Texture tex = NextToken( text, 0, ref prevFlags ) == -1 ? DrawSimple( ref args ) : DrawAdvanced( ref args, index, text ); - game.Drawer2D.ReducePadding( ref tex, Utils.Floor( args.Font.Size ) ); + game.Drawer2D.ReducePadding( ref tex, Utils.Floor( args.Font.Size ), 3 ); tex.X1 = CalcOffset( game.Width, tex.Width, XOffset, HorizontalAnchor ); tex.Y1 = CalcY( index, tex.Height ); diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs index 513685833..cb9c2c6ad 100644 --- a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs +++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs @@ -32,7 +32,7 @@ namespace ClassicalSharp.Gui { DrawTextArgs args = new DrawTextArgs( "I", font, true ); int height = game.Drawer2D.MeasureChatSize( ref args ).Height; - game.Drawer2D.ReducePadding( ref height, Utils.Floor( font.Size ) ); + game.Drawer2D.ReducePadding( ref height, Utils.Floor( font.Size ), 3 ); defaultHeight = height; for( int i = 0; i < Textures.Length; i++ ) { diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 1db610088..b4e409999 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -155,6 +155,7 @@ + diff --git a/ClassicalSharp/Entities/Components/SoundComponent.cs b/ClassicalSharp/Entities/Components/SoundComponent.cs new file mode 100644 index 000000000..8b3be906b --- /dev/null +++ b/ClassicalSharp/Entities/Components/SoundComponent.cs @@ -0,0 +1,87 @@ +// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT +using System; +using OpenTK; + +namespace ClassicalSharp.Entities { + + /// Entity component that plays block step sounds. + public sealed class SoundComponent { + + LocalPlayer p; + Game game; + Predicate checkSoundNonSolid, checkSoundSolid; + + public SoundComponent( Game game, Entity entity ) { + this.game = game; + p = (LocalPlayer)entity; + checkSoundNonSolid = CheckSoundNonSolid; + checkSoundSolid = CheckSoundSolid; + } + + Vector3 lastSoundPos = new Vector3( float.PositiveInfinity ); + public void Tick( bool wasOnGround ) { + Vector3 soundPos = p.nextPos; + GetSound(); + if( !anyNonAir ) soundPos = new Vector3( -100000 ); + + if( p.onGround && (DoPlaySound( soundPos ) || !wasOnGround) ) { + game.AudioPlayer.PlayStepSound( sndType ); + lastSoundPos = soundPos; + } + } + + bool DoPlaySound( Vector3 soundPos ) { + float distSq = (lastSoundPos - soundPos).LengthSquared; + bool enoughDist = distSq > 1.75f * 1.75f; + // just play every certain block interval when not animating + if( p.curSwing < 0.999f ) return enoughDist; + + // have our legs just crossed over the '0' point? + float oldLegRot = (float)Math.Sin( p.anim.walkTimeO ); + float newLegRot = (float)Math.Sin( p.anim.walkTimeN ); + return Math.Sign( oldLegRot ) != Math.Sign( newLegRot ); + } + + bool anyNonAir = false; + SoundType sndType = SoundType.None; + void GetSound() { + Vector3 pos = p.nextPos, size = p.CollisionSize; + BoundingBox bounds = new BoundingBox( pos - size / 2, pos + size / 2 ); + sndType = SoundType.None; + anyNonAir = false; + + // first check surrounding liquids/gas for sounds + p.TouchesAny( bounds, checkSoundNonSolid ); + if( sndType != SoundType.None ) return; + + // then check block standing on + byte blockUnder = (byte)p.BlockUnderFeet; + SoundType typeUnder = game.BlockInfo.StepSounds[blockUnder]; + CollideType collideType = game.BlockInfo.Collide[blockUnder]; + if( collideType == CollideType.Solid && typeUnder != SoundType.None ) { + anyNonAir = true; sndType = typeUnder; return; + } + + // then check all solid blocks at feet + pos.Y -= 0.01f; + bounds.Max.Y = bounds.Min.Y = pos.Y; + p.TouchesAny( bounds, checkSoundSolid ); + } + + bool CheckSoundNonSolid( byte b ) { + SoundType newType = game.BlockInfo.StepSounds[b]; + CollideType collide = game.BlockInfo.Collide[b]; + if( newType != SoundType.None && collide != CollideType.Solid ) + sndType = newType; + if( b != 0 ) anyNonAir = true; + return false; + } + + bool CheckSoundSolid( byte b ) { + SoundType newType = game.BlockInfo.StepSounds[b]; + if( newType != SoundType.None ) sndType = newType; + if( b != 0 ) anyNonAir = true; + return false; + } + } +} \ No newline at end of file diff --git a/ClassicalSharp/Entities/LocalPlayer.cs b/ClassicalSharp/Entities/LocalPlayer.cs index a1224111c..227046494 100644 --- a/ClassicalSharp/Entities/LocalPlayer.cs +++ b/ClassicalSharp/Entities/LocalPlayer.cs @@ -29,16 +29,19 @@ namespace ClassicalSharp.Entities { public HacksComponent Hacks; internal PhysicsComponent physics; internal InputComponent input; - Predicate checkSoundNonSolid, checkSoundSolid; + internal SoundComponent sound; public LocalPlayer( Game game ) : base( game ) { DisplayName = game.Username; SkinName = game.Username; SkinIdentifier = "skin_255"; + collisions = new CollisionsComponent( game, this ); Hacks = new HacksComponent( game, this ); physics = new PhysicsComponent( game, this ); input = new InputComponent( game, this ); + sound = new SoundComponent( game, this ); + physics.hacks = Hacks; input.Hacks = Hacks; physics.collisions = collisions; input.collisions = collisions; input.physics = physics; @@ -51,8 +54,6 @@ namespace ClassicalSharp.Entities { if( game.ClassicMode && game.ClassicHacks ) Hacks.Enabled = true; InitRenderingData(); - checkSoundNonSolid = CheckSoundNonSolid; - checkSoundSolid = CheckSoundSolid; } Vector3 lastSoundPos = new Vector3( float.PositiveInfinity ); @@ -72,73 +73,12 @@ namespace ClassicalSharp.Entities { nextPos = Position; Position = lastPos; anim.UpdateAnimState( lastPos, nextPos, delta ); - CheckSkin(); - Vector3 soundPos = nextPos; - GetSound(); - if( !anyNonAir ) soundPos = new Vector3( -100000 ); - - if( onGround && (DoPlaySound( soundPos ) || !wasOnGround) ) { - game.AudioPlayer.PlayStepSound( sndType ); - lastSoundPos = soundPos; - } + CheckSkin(); + sound.Tick( wasOnGround ); UpdateCurrentBodyYaw(); } - - bool DoPlaySound( Vector3 soundPos ) { - float distSq = (lastSoundPos - soundPos).LengthSquared; - bool enoughDist = distSq > 1.75f * 1.75f; - // just play every certain block interval when not animating - if( curSwing < 0.999f ) return enoughDist; - - // have our legs just crossed over the '0' point? - float oldLegRot = (float)Math.Sin( anim.walkTimeO ); - float newLegRot = (float)Math.Sin( anim.walkTimeN ); - return Math.Sign( oldLegRot ) != Math.Sign( newLegRot ); - } - - bool anyNonAir = false; - SoundType sndType = SoundType.None; - void GetSound() { - Vector3 pos = nextPos, size = CollisionSize; - BoundingBox bounds = new BoundingBox( pos - size / 2, pos + size / 2 ); - sndType = SoundType.None; - anyNonAir = false; - - // first check surrounding liquids/gas for sounds - TouchesAny( bounds, checkSoundNonSolid ); - if( sndType != SoundType.None ) return; - - // then check block standing on - byte blockUnder = (byte)BlockUnderFeet; - SoundType typeUnder = game.BlockInfo.StepSounds[blockUnder]; - CollideType collideType = game.BlockInfo.Collide[blockUnder]; - if( collideType == CollideType.Solid && typeUnder != SoundType.None ) { - anyNonAir = true; sndType = typeUnder; return; - } - - // then check all solid blocks at feet - pos.Y -= 0.01f; - bounds.Max.Y = bounds.Min.Y = pos.Y; - TouchesAny( bounds, checkSoundSolid ); - } - - bool CheckSoundNonSolid( byte b ) { - SoundType newType = game.BlockInfo.StepSounds[b]; - CollideType collide = game.BlockInfo.Collide[b]; - if( newType != SoundType.None && collide != CollideType.Solid ) - sndType = newType; - if( b != 0 ) anyNonAir = true; - return false; - } - - bool CheckSoundSolid( byte b ) { - SoundType newType = game.BlockInfo.StepSounds[b]; - if( newType != SoundType.None ) sndType = newType; - if( b != 0 ) anyNonAir = true; - return false; - } - + public override void RenderModel( double deltaTime, float t ) { anim.GetCurrentAnimState( t ); curSwing = Utils.Lerp( anim.swingO, anim.swingN, t );