Start on (non-working) player push.

This commit is contained in:
UnknownShadow200 2016-07-25 13:03:29 +10:00
parent cc92a2794e
commit 4ffa029fa9
10 changed files with 52 additions and 29 deletions

View file

@ -36,7 +36,7 @@ namespace ClassicalSharp.Entities {
// TODO: test for corner cases, and refactor this.
internal void MoveAndWallSlide() {
if( entity.Velocity == Vector3.Zero ) return;
Vector3 size = entity.CollisionSize;
Vector3 size = entity.Size;
AABB entityBB, entityExtentBB;
int count = 0;
FindReachableBlocks( ref count, out entityBB, out entityExtentBB );
@ -46,7 +46,7 @@ namespace ClassicalSharp.Entities {
void FindReachableBlocks( ref int count, out AABB entityBB,
out AABB entityExtentBB ) {
Vector3 vel = entity.Velocity;
entityBB = entity.CollisionBounds;
entityBB = entity.Bounds;
// Exact maximum extent the entity can reach, and the equivalent map coordinates.
entityExtentBB = new AABB(

View file

@ -63,14 +63,14 @@ namespace ClassicalSharp.Entities {
entity.Velocity = Vector3.Zero;
// Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before
AABB bb = entity.CollisionBounds;
AABB bb = entity.Bounds;
bb.Min.Y -= 0.01f; bb.Max.Y = bb.Min.Y;
entity.onGround = entity.TouchesAny( bb, b => game.BlockInfo.Collide[b] == CollideType.Solid );
}
void FindHighestFree( ref Vector3 spawn ) {
BlockInfo info = game.BlockInfo;
Vector3 size = entity.CollisionSize;
Vector3 size = entity.Size;
AABB bb = AABB.Make( spawn, size );
Vector3I P = Vector3I.Floor( spawn );

View file

@ -34,7 +34,7 @@ namespace ClassicalSharp.Entities {
minX[i] = int.MaxValue; minY[i] = int.MaxValue;
maxX[i] = int.MinValue; maxY[i] = int.MinValue;
}
bb = entity.CollisionBounds;
bb = entity.Bounds;
int count = 0;
// First raytrace out from the origin to find approximate blocks

View file

@ -25,7 +25,7 @@ namespace ClassicalSharp.Entities {
public void UpdateVelocityState( float xMoving, float zMoving ) {
if( !hacks.NoclipSlide && (hacks.Noclip && xMoving == 0 && zMoving == 0) )
entity.Velocity = Vector3.Zero;
entity.Velocity = Vector3.Zero;
if( hacks.Flying || hacks.Noclip ) {
entity.Velocity.Y = 0; // eliminate the effect of gravity
int dir = (hacks.FlyingUp || jumping) ? 1 : (hacks.FlyingDown ? -1 : 0);
@ -44,7 +44,7 @@ namespace ClassicalSharp.Entities {
bool touchWater = entity.TouchesAnyWater();
bool touchLava = entity.TouchesAnyLava();
if( touchWater || touchLava ) {
AABB bounds = entity.CollisionBounds;
AABB bounds = entity.Bounds;
int feetY = Utils.Floor( bounds.Min.Y ), bodyY = feetY + 1;
int headY = Utils.Floor( bounds.Max.Y );
if( bodyY > headY ) bodyY = headY;
@ -183,21 +183,18 @@ namespace ClassicalSharp.Entities {
float GetBaseMultiply( bool canSpeed ) {
float multiply = 0;
if( hacks.Flying || hacks.Noclip ) {
if( hacks.Speeding && canSpeed ) multiply += hacks.SpeedMultiplier * 8;
if( hacks.HalfSpeeding && canSpeed ) multiply += hacks.SpeedMultiplier * 8 / 2;
if( multiply == 0 ) multiply = 8f;
} else {
if( hacks.Speeding && canSpeed ) multiply += hacks.SpeedMultiplier;
if( hacks.HalfSpeeding && canSpeed ) multiply += hacks.SpeedMultiplier / 2;
if( multiply == 0 ) multiply = 1;
}
float speed = (hacks.Flying || hacks.Noclip) ? 8 : 1;
if( hacks.Speeding && canSpeed ) multiply += speed * hacks.SpeedMultiplier;
if( hacks.HalfSpeeding && canSpeed ) multiply += speed * hacks.SpeedMultiplier / 2;
if( multiply == 0 ) multiply = speed;
return hacks.CanSpeed ? multiply : Math.Min( multiply, hacks.MaxSpeedMultiplier );
}
const float inf = float.PositiveInfinity;
float LowestSpeedModifier() {
AABB bounds = entity.CollisionBounds;
AABB bounds = entity.Bounds;
useLiquidGravity = false;
float baseModifier = LowestModifier( bounds, false );
bounds.Min.Y -= 0.5f/16f; // also check block standing on
@ -261,5 +258,30 @@ namespace ClassicalSharp.Entities {
double a = Math.Exp( -0.0202027 * t ); //~0.98^t
return a * ( -49 * u - 196 ) - 4 * t + 50 * u + 196;
}
public void DoEntityPush( ref float xMoving, ref float zMoving ) {
if( !game.ClassicMode || hacks.Flying || hacks.Noclip ) return;
return;
// TODO: Fix
for( int id = 0; id < 255; id++ ) {
Entity other = game.Entities[id];
if( other == null ) continue;
float dx = other.Position.X - entity.Position.X;
float dy = other.Position.Y - entity.Position.Y;
float dz = other.Position.Z - entity.Position.Z;
float dist = dx * dx + dy * dy + dz * dz;
if( dist < 0.0001f || dist > 0.5f ) continue;
double yaw = Math.Atan2( dz, dx ) - Math.PI / 2;
Vector3 dir = Utils.GetDirVector( yaw, 0 );
Console.WriteLine( "Yaw: " + yaw * Utils.Rad2Deg );
Console.WriteLine( dir );
Console.WriteLine( entity.Position );
xMoving = -dir.X;
zMoving = -dir.Z;
}
}
}
}

View file

@ -47,7 +47,7 @@ namespace ClassicalSharp.Entities {
SoundType sndType = SoundType.None;
void GetSound() {
Vector3 pos = p.nextPos;
AABB bounds = p.CollisionBounds;
AABB bounds = p.Bounds;
sndType = SoundType.None;
anyNonAir = false;

View file

@ -18,14 +18,14 @@ namespace ClassicalSharp.Entities {
/// <summary> Bounding box of the model that collision detection
/// is performed with, in world coordinates. </summary>
public virtual AABB CollisionBounds {
get { return AABB.Make( Position, CollisionSize ); }
public virtual AABB Bounds {
get { return AABB.Make( Position, Size ); }
}
/// <summary> Determines whether any of the blocks that intersect the
/// bounding box of this entity satisfy the given condition. </summary>
public bool TouchesAny( Predicate<byte> condition ) {
return TouchesAny( CollisionBounds, condition );
return TouchesAny( Bounds, condition );
}
/// <summary> Determines whether any of the blocks that intersect the
@ -55,7 +55,7 @@ namespace ClassicalSharp.Entities {
/// <summary> Determines whether any of the blocks that intersect the
/// bounding box of this entity are rope. </summary>
public bool TouchesAnyRope() {
AABB bounds = CollisionBounds;
AABB bounds = Bounds;
bounds.Max.Y += 0.5f/16f;
return TouchesAny( bounds, b => b == Block.Rope );
}
@ -104,14 +104,14 @@ namespace ClassicalSharp.Entities {
public bool TouchesAnyLava() {
// NOTE: Original classic client uses offset (so you can only climb up
// alternating liquid-solid elevators on two sides)
AABB bounds = CollisionBounds.Offset( liqExpand );
AABB bounds = Bounds.Offset( liqExpand );
return TouchesAnyLiquid( bounds, Block.Lava, Block.StillLava );
}
/// <summary> Determines whether any of the blocks that intersect the
/// bounding box of this entity are water or still water. </summary>
public bool TouchesAnyWater() {
AABB bounds = CollisionBounds.Offset( liqExpand );
AABB bounds = Bounds.Offset( liqExpand );
return TouchesAnyLiquid( bounds, Block.Water, Block.StillWater );
}
}

View file

@ -47,7 +47,7 @@ namespace ClassicalSharp.Entities {
}
/// <summary> Returns the size of the model that is used for collision detection. </summary>
public Vector3 CollisionSize {
public Vector3 Size {
get { UpdateModel(); return Model.CollisionSize * ModelScale; }
}

View file

@ -59,6 +59,7 @@ namespace ClassicalSharp.Entities {
bool wasOnGround = onGround;
HandleInput( ref xMoving, ref zMoving );
physics.DoEntityPush( ref xMoving, ref zMoving );
physics.UpdateVelocityState( xMoving, zMoving );
physics.PhysicsTick( xMoving, zMoving );

View file

@ -63,7 +63,7 @@ namespace ClassicalSharp.Entities {
using( Font font = new Font( game.FontName, 24 ) ) {
DrawTextArgs args = new DrawTextArgs( DisplayName, font, false );
Size size = game.Drawer2D.MeasureBitmappedSize( ref args );
if( size == Size.Empty ) { nameTex = new Texture( -1, 0, 0, 0, 0, 1, 1 ); return; }
if( size.Width == 0 ) { nameTex = new Texture( -1, 0, 0, 0, 0, 1, 1 ); return; }
size.Width += 3; size.Height += 3;
using( IDrawer2D drawer = game.Drawer2D )

View file

@ -86,7 +86,7 @@ namespace ClassicalSharp {
AABB blockBB = new AABB( pos + info.MinBB[block], pos + info.MaxBB[block] );
// NOTE: We need to also test against nextPos here, because otherwise
// we can fall through the block as collision is performed against nextPos
AABB localBB = AABB.Make( p.Position, p.CollisionSize );
AABB localBB = AABB.Make( p.Position, p.Size );
localBB.Min.Y = Math.Min( p.nextPos.Y, localBB.Min.Y );
if( p.Hacks.Noclip || !localBB.Intersects( blockBB ) ) return true;
@ -120,7 +120,7 @@ namespace ClassicalSharp {
else if( selected.BlockFace == CpeBlockFace.YMax )
newP.Y = blockBB.Min.Y + 1 + Entity.Adjustment;
else if( selected.BlockFace == CpeBlockFace.YMin )
newP.Y = blockBB.Min.Y - game.LocalPlayer.CollisionSize.Y - Entity.Adjustment;
newP.Y = blockBB.Min.Y - game.LocalPlayer.Size.Y - Entity.Adjustment;
Vector3I newLoc = Vector3I.Floor( newP );
bool validPos = newLoc.X >= 0 && newLoc.Y >= 0 && newLoc.Z >= 0 &&
@ -151,7 +151,7 @@ namespace ClassicalSharp {
for( int id = 0; id < 255; id++ ) {
Player player = game.Entities[id];
if( player == null ) continue;
AABB bounds = player.CollisionBounds;
AABB bounds = player.Bounds;
bounds.Min.Y += 1/32f; // when player is exactly standing on top of ground
if( bounds.Intersects( blockBB ) ) return true;
}