Move step sound handling into a separate entity component.

This commit is contained in:
UnknownShadow200 2016-04-22 17:42:09 +10:00
parent 0b1e9af081
commit 5e13187892
5 changed files with 97 additions and 69 deletions

View file

@ -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 );

View file

@ -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++ ) {

View file

@ -155,6 +155,7 @@
<Compile Include="Entities\Components\CollisionsComponent.cs" />
<Compile Include="Entities\Components\PhysicsComponent.cs" />
<Compile Include="Entities\Components\ShadowComponent.cs" />
<Compile Include="Entities\Components\SoundComponent.cs" />
<Compile Include="Entities\Entity.Bounds.cs" />
<Compile Include="Entities\Entity.cs" />
<Compile Include="Entities\EntityList.cs" />

View file

@ -0,0 +1,87 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using OpenTK;
namespace ClassicalSharp.Entities {
/// <summary> Entity component that plays block step sounds. </summary>
public sealed class SoundComponent {
LocalPlayer p;
Game game;
Predicate<byte> 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;
}
}
}

View file

@ -29,16 +29,19 @@ namespace ClassicalSharp.Entities {
public HacksComponent Hacks;
internal PhysicsComponent physics;
internal InputComponent input;
Predicate<byte> 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 );