Fix respawning. (Thanks goodlyay)

This commit is contained in:
UnknownShadow200 2016-06-02 15:57:11 +10:00
parent 9e17292a6b
commit 97ff48e153
3 changed files with 28 additions and 24 deletions

View File

@ -33,6 +33,8 @@ namespace ClassicalSharp.Entities {
entity.SetLocation( update, false );
} else if( key == keys[KeyBinding.SetSpawn] && Hacks.CanRespawn ) {
p.Spawn = entity.Position;
p.Spawn.X = Utils.Floor( p.Spawn.X ) + 0.5f;
p.Spawn.Z = Utils.Floor( p.Spawn.Z ) + 0.5f;
p.SpawnYaw = entity.YawDegrees;
p.SpawnPitch = entity.PitchDegrees;
@ -61,33 +63,35 @@ namespace ClassicalSharp.Entities {
void FindHighestFree( ref Vector3 spawn ) {
BlockInfo info = game.BlockInfo;
Vector3 size = entity.CollisionSize;
AABB bb = entity.CollisionBounds;
AABB bb = AABB.Make( spawn, size );
Vector3I P = Vector3I.Floor( spawn );
int bbMax = Utils.Floor( size.Y );
int minX = Utils.Floor( -size.X / 2 ), maxX = Utils.Floor( size.X / 2 );
int minZ = Utils.Floor( -size.Z / 2 ), maxZ = Utils.Floor( size.Z / 2 );
int minX = Utils.Floor( P.X - size.X / 2 ), maxX = Utils.Floor( P.X + size.X / 2 );
int minZ = Utils.Floor( P.Z - size.Z / 2 ), maxZ = Utils.Floor( P.Z + size.Z / 2 );
// Spawn player at highest valid position.
for( int y = P.Y; y <= game.World.Height; y++ ) {
bool anyHit = false;
bool intersectAny = false;
for( int yy = 0; yy <= bbMax; yy++ )
for( int zz = minZ; zz <= maxZ; zz++ )
for ( int xx = minX; xx <= maxX; xx++ )
for( int z = minZ; z <= maxZ; z++ )
for ( int x = minX; x <= maxX; x++ )
{
Vector3I coords = new Vector3I( P.X + xx, y + yy, P.Z + zz );
Vector3I coords = new Vector3I( x, y + yy, z );
byte block = collisions.GetPhysicsBlockId( coords.X, coords.Y, coords.Z );
Vector3 min = info.MinBB[block] + (Vector3)coords;
Vector3 max = info.MaxBB[block] + (Vector3)coords;
if( !bb.Intersects( new AABB( min, max ) ) ) continue;
anyHit |= info.Collide[block] == CollideType.Solid;
intersectAny |= info.Collide[block] == CollideType.Solid;
}
if( !anyHit ) {
if( !intersectAny ) {
byte block = collisions.GetPhysicsBlockId( P.X, y, P.Z );
float height = info.Collide[block] == CollideType.Solid ? info.MaxBB[block].Y : 0;
spawn.Y = y + height + Entity.Adjustment;
return;
}
bb.Min.Y += 1; bb.Max.Y += 1;
}
}
}

View File

@ -19,12 +19,7 @@ namespace ClassicalSharp.Entities {
/// <summary> Bounding box of the model that collision detection
/// is performed with, in world coordinates. </summary>
public virtual AABB CollisionBounds {
get {
Vector3 pos = Position;
Vector3 size = CollisionSize;
return new AABB( pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2,
pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 );
}
get { return AABB.Make( Position, CollisionSize ); }
}
/// <summary> Determines whether any of the blocks that intersect the

View File

@ -23,25 +23,30 @@ namespace ClassicalSharp {
Max = max;
}
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
public static AABB Make( Vector3 pos, Vector3 size ) {
return new AABB( pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2,
pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 );
}
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
/// of the original bounding box translated by the given vector. </summary>
public AABB Offset( Vector3 amount ) {
return new AABB( Min + amount, Max + amount );
}
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
/// of the original bounding box expanded away from origin the given vector. </summary>
public AABB Expand( Vector3 amount ) {
return new AABB( Min - amount, Max + amount );
}
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
/// <summary> Returns a new bounding box, with the minimum and maximum coordinates
/// of the original bounding box scaled away from origin the given value. </summary>
public AABB Scale( float scale ) {
return new AABB( Min * scale, Max * scale );
}
/// <summary> Determines whether this bounding box intersects
/// <summary> Determines whether this bounding box intersects
/// the given bounding box on any axes. </summary>
public bool Intersects( AABB other ) {
if( Max.X >= other.Min.X && Min.X <= other.Max.X ) {
@ -53,33 +58,33 @@ namespace ClassicalSharp {
return false;
}
/// <summary> Determines whether this bounding box entirely contains
/// <summary> Determines whether this bounding box entirely contains
/// the given bounding box on all axes. </summary>
public bool Contains( AABB other ) {
return other.Min.X >= Min.X && other.Min.Y >= Min.Y && other.Min.Z >= Min.Z &&
other.Max.X <= Max.X && other.Max.Y <= Max.Y && other.Max.Z <= Max.Z;
}
/// <summary> Determines whether this bounding box entirely contains
/// <summary> Determines whether this bounding box entirely contains
/// the coordinates on all axes. </summary>
public bool Contains( Vector3 P ) {
return P.X >= Min.X && P.Y >= Min.Y && P.Z >= Min.Z &&
P.X <= Max.X && P.Y <= Max.Y && P.Z <= Max.Z;
}
/// <summary> Determines whether this bounding box intersects
/// <summary> Determines whether this bounding box intersects
/// the given bounding box on the X axis. </summary>
public bool XIntersects( AABB box ) {
return Max.X >= box.Min.X && Min.X <= box.Max.X;
}
/// <summary> Determines whether this bounding box intersects
/// <summary> Determines whether this bounding box intersects
/// the given bounding box on the Y axis. </summary>
public bool YIntersects( AABB box ) {
return Max.Y >= box.Min.Y && Min.Y <= box.Max.Y;
}
/// <summary> Determines whether this bounding box intersects
/// <summary> Determines whether this bounding box intersects
/// the given bounding box on the Z axis. </summary>
public bool ZIntersects( AABB box ) {
return Max.Z >= box.Min.Z && Min.Z <= box.Max.Z;