mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-26 19:12:07 -05:00
More comments.
This commit is contained in:
parent
fc4e8c7e56
commit
a6f90acf00
11 changed files with 120 additions and 35 deletions
|
@ -23,29 +23,31 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
public void RecalculateSpriteBB( FastBitmap fastBmp ) {
|
||||
int elemSize = fastBmp.Width / 16;
|
||||
for( int i = 0; i < 256; i++ ) {
|
||||
if( IsSprite[i] ) {
|
||||
int texId = GetTextureLoc( (byte)i, TileSide.Top );
|
||||
float topY = GetSpriteBB_TopY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float bottomY = GetSpriteBB_BottomY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float leftX = GetSpriteBB_LeftX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float rightX = GetSpriteBB_RightX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
|
||||
MinBB[i] = Utils.RotateY( leftX - 0.5f, bottomY, 0, 45f * Utils.Deg2Rad )
|
||||
+ new Vector3( 0.5f, 0, 0.5f );
|
||||
MaxBB[i] = Utils.RotateY( rightX - 0.5f, topY, 0, 45f * Utils.Deg2Rad )
|
||||
+ new Vector3( 0.5f, 0, 0.5f );
|
||||
}
|
||||
if( IsSprite[i] ) RecalculateBB( i, fastBmp );
|
||||
}
|
||||
}
|
||||
|
||||
internal void RecalculateBB( int block, FastBitmap fastBmp ) {
|
||||
int elemSize = fastBmp.Width / 16;
|
||||
int texId = GetTextureLoc( (byte)block, TileSide.Top );
|
||||
float topY = GetSpriteBB_TopY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float bottomY = GetSpriteBB_BottomY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float leftX = GetSpriteBB_LeftX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
float rightX = GetSpriteBB_RightX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
|
||||
|
||||
MinBB[block] = Utils.RotateY( leftX - 0.5f, bottomY, 0, 45f * Utils.Deg2Rad )
|
||||
+ new Vector3( 0.5f, 0, 0.5f );
|
||||
MaxBB[block] = Utils.RotateY( rightX - 0.5f, topY, 0, 45f * Utils.Deg2Rad )
|
||||
+ new Vector3( 0.5f, 0, 0.5f );
|
||||
}
|
||||
|
||||
const int alphaTest = unchecked( (int)0x80000000 );
|
||||
unsafe float GetSpriteBB_TopY( int size, int tileX, int tileY, FastBitmap fastBmp ) {
|
||||
for( int y = 0; y < size; y++ ) {
|
||||
int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
|
||||
for( int x = 0; x < size; x++ ) {
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
return 1 - (float)y / size;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +58,7 @@ namespace ClassicalSharp {
|
|||
for( int y = size - 1; y >= 0; y-- ) {
|
||||
int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
|
||||
for( int x = 0; x < size; x++ ) {
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
return 1 - (float)(y + 1) / size;
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +66,10 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
unsafe float GetSpriteBB_LeftX( int size, int tileX, int tileY, FastBitmap fastBmp ) {
|
||||
for( int x = 0; x < size; x++ ) {
|
||||
for( int x = 0; x < size; x++ ) {
|
||||
for( int y = 0; y < size; y++ ) {
|
||||
int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
return (float)x / size;
|
||||
}
|
||||
}
|
||||
|
@ -75,10 +77,10 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
unsafe float GetSpriteBB_RightX( int size, int tileX, int tileY, FastBitmap fastBmp ) {
|
||||
for( int x = size - 1; x >= 0; x-- ) {
|
||||
for( int x = size - 1; x >= 0; x-- ) {
|
||||
for( int y = 0; y < size; y++ ) {
|
||||
int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
if( (row[x] & alphaTest) != 0 )
|
||||
return (float)(x + 1) / size;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
|
@ -180,6 +181,8 @@ namespace ClassicalSharp {
|
|||
SpeedMultiplier[id] = 1;
|
||||
SetAll( 0, (Block)id );
|
||||
SetupCullingCache();
|
||||
MinBB[id] = Vector3.Zero;
|
||||
MaxBB[id] = Vector3.One;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ using OpenTK;
|
|||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
/// <summary> Contains a model, along with position, velocity, and rotation.
|
||||
/// May also contain other fields and properties. </summary>
|
||||
public abstract class Entity {
|
||||
|
||||
public Entity( Game game ) {
|
||||
|
@ -18,26 +20,31 @@ namespace ClassicalSharp {
|
|||
public Vector3 Position;
|
||||
public Vector3 Velocity;
|
||||
public float YawDegrees, PitchDegrees;
|
||||
protected float StepSize;
|
||||
|
||||
protected Game game;
|
||||
protected BlockInfo info;
|
||||
|
||||
/// <summary> Rotation of the entity horizontally (i.e. looking north or east) </summary>
|
||||
public float YawRadians {
|
||||
get { return YawDegrees * Utils.Deg2Rad; }
|
||||
set { YawDegrees = value * Utils.Rad2Deg; }
|
||||
}
|
||||
|
||||
/// <summary> Rotation of the entity vertically. (i.e. looking up or down) </summary>
|
||||
public float PitchRadians {
|
||||
get { return PitchDegrees * Utils.Deg2Rad; }
|
||||
set { PitchDegrees = value * Utils.Rad2Deg; }
|
||||
}
|
||||
|
||||
/// <summary> Returns the size of the model that is used for collision detection. </summary>
|
||||
public virtual Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f, 28.5f/16f, 8/16f );
|
||||
//Model.CollisionSize; TODO: for non humanoid models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Bounding box of the model that collision detection
|
||||
/// is performed with, in world coordinates. </summary>
|
||||
public virtual BoundingBox CollisionBounds {
|
||||
get {
|
||||
Vector3 pos = Position;
|
||||
|
@ -49,12 +56,17 @@ namespace ClassicalSharp {
|
|||
|
||||
public abstract void Despawn();
|
||||
|
||||
/// <summary> Renders the entity's model, interpolating between the previous and next state. </summary>
|
||||
public abstract void Render( double deltaTime, float t );
|
||||
|
||||
/// <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 );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// given bounding box satisfy the given condition. </summary>
|
||||
public bool TouchesAny( BoundingBox bounds, Predicate<byte> condition ) {
|
||||
Vector3I bbMin = Vector3I.Floor( bounds.Min );
|
||||
Vector3I bbMax = Vector3I.Floor( bounds.Max );
|
||||
|
@ -64,6 +76,7 @@ namespace ClassicalSharp {
|
|||
for( int z = bbMin.Z; z <= bbMax.Z; z++ ) {
|
||||
if( !game.Map.IsValidPos( x, y, z ) ) continue;
|
||||
byte block = game.Map.GetBlock( x, y, z );
|
||||
|
||||
if( condition( block ) ) {
|
||||
float blockHeight = info.Height[block];
|
||||
Vector3 min = new Vector3( x, y, z ) + info.MinBB[block];
|
||||
|
@ -77,19 +90,27 @@ namespace ClassicalSharp {
|
|||
return false;
|
||||
}
|
||||
|
||||
public const float Adjustment = 0.001f;
|
||||
/// <summary> Constant offset used to avoid floating point roundoff errors. </summary>
|
||||
public const float Adjustment = 0.001f;
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are lava or still lava. </summary>
|
||||
protected bool TouchesAnyLava() {
|
||||
return TouchesAny( CollisionBounds,
|
||||
return TouchesAny( CollisionBounds,
|
||||
b => b == (byte)Block.Lava || b == (byte)Block.StillLava );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are rope. </summary>
|
||||
protected bool TouchesAnyRope() {
|
||||
return TouchesAny( CollisionBounds,
|
||||
return TouchesAny( CollisionBounds,
|
||||
b => b == (byte)Block.Rope );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are water or still water. </summary>
|
||||
protected bool TouchesAnyWater() {
|
||||
return TouchesAny( CollisionBounds,
|
||||
return TouchesAny( CollisionBounds,
|
||||
b => b == (byte)Block.Water || b == (byte)Block.StillWater );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace ClassicalSharp {
|
|||
public byte UserType;
|
||||
bool canSpeed = true, canFly = true, canRespawn = true, canNoclip = true;
|
||||
|
||||
/// <summary> Whether the player has permission to increase its speed beyond the normal walking speed. </summary>
|
||||
public bool CanSpeed {
|
||||
get { return canSpeed; }
|
||||
set { canSpeed = value; }
|
||||
|
@ -37,6 +38,8 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
float jumpVel = 0.42f;
|
||||
/// <summary> Returns the height that the client can currently jump up to.<br/>
|
||||
/// Note that when speeding is enabled the client is able to jump much further. </summary>
|
||||
public float JumpHeight {
|
||||
get { return (float)GetMaxHeight( jumpVel ); }
|
||||
}
|
||||
|
@ -200,6 +203,9 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
internal bool jumping, speeding, flying, noClip, flyingDown, flyingUp;
|
||||
|
||||
/// <summary> Parses hack flags specified in the motd and/or name of the server. </summary>
|
||||
/// <remarks> Recognises +/-hax, +/-fly, +/-noclip, +/-speed, +/-respawn, +/-ophax </remarks>
|
||||
public void ParseHackFlags( string name, string motd ) {
|
||||
string joined = name + motd;
|
||||
if( joined.Contains( "-hax" ) ) {
|
||||
|
@ -216,9 +222,8 @@ namespace ClassicalSharp {
|
|||
ParseFlag( b => CanSpeed = b, joined, "speed" );
|
||||
ParseFlag( b => CanRespawn = b, joined, "respawn" );
|
||||
|
||||
if( UserType == 0x64 ) {
|
||||
if( UserType == 0x64 )
|
||||
ParseFlag( b => CanFly = CanNoclip = CanRespawn = CanSpeed = b, joined, "ophax" );
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseFlag( Action<bool> action, string joined, string flag ) {
|
||||
|
@ -229,6 +234,8 @@ namespace ClassicalSharp {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Sets the user type of this user. This is used to control permissions for grass,
|
||||
/// bedrock, water and lava blocks on servers that don't support CPE block permissions. </summary>
|
||||
public void SetUserType( byte value ) {
|
||||
UserType = value;
|
||||
Inventory inv = game.Inventory;
|
||||
|
@ -244,6 +251,8 @@ namespace ClassicalSharp {
|
|||
|
||||
internal Vector3 lastPos, nextPos;
|
||||
internal float lastYaw, nextYaw, lastPitch, nextPitch;
|
||||
|
||||
/// <summary> Linearly interpolates position and rotation between the previous and next state. </summary>
|
||||
public void SetInterpPosition( float t ) {
|
||||
Position = Vector3.Lerp( lastPos, nextPos, t );
|
||||
YawDegrees = Utils.LerpAngle( lastYaw, nextYaw, t );
|
||||
|
@ -278,6 +287,8 @@ namespace ClassicalSharp {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Calculates the jump velocity required such that when a client presses
|
||||
/// the jump binding they will be able to jump up to the given height. </summary>
|
||||
internal void CalculateJumpVelocity( float jumpHeight ) {
|
||||
jumpVel = 0;
|
||||
if( jumpHeight >= 256 ) jumpVel = 10.0f;
|
||||
|
|
|
@ -10,17 +10,25 @@ namespace ClassicalSharp {
|
|||
public Vector3 Pos;
|
||||
public float Yaw, Pitch;
|
||||
|
||||
/// <summary> Whether this update includes an absolute or relative position. </summary>
|
||||
public bool IncludesPosition;
|
||||
|
||||
/// <summary> Whether the positon is specified as absolute (world coordinates),
|
||||
/// or relative to the last position that was received from the server. </summary>
|
||||
public bool RelativePosition;
|
||||
|
||||
/// <summary> Whether this update includes absolute yaw and pitch. </summary>
|
||||
public bool IncludesOrientation;
|
||||
|
||||
public LocationUpdate( float x, float y, float z, float yaw, float pitch,
|
||||
bool incPos, bool relPos, bool incOri ) {
|
||||
Pos = new Vector3( x, y, z );
|
||||
// Make sure yaw and pitch are in [0, 360)
|
||||
Yaw = yaw % 360;
|
||||
if( Yaw < 0 ) Yaw += 360;
|
||||
Pitch = pitch % 360;
|
||||
if( Pitch < 0 ) Pitch += 360;
|
||||
|
||||
IncludesPosition = incPos;
|
||||
RelativePosition = relPos;
|
||||
IncludesOrientation = incOri;
|
||||
|
|
|
@ -6,10 +6,12 @@ namespace ClassicalSharp {
|
|||
|
||||
/// <summary> Entity that performs collision detection. </summary>
|
||||
public abstract class PhysicsEntity : Entity {
|
||||
|
||||
|
||||
public PhysicsEntity( Game game ) : base( game ) {
|
||||
}
|
||||
protected bool onGround, collideX, collideY, collideZ;
|
||||
|
||||
protected bool onGround, collideX, collideY, collideZ;
|
||||
protected float StepSize;
|
||||
|
||||
protected byte GetPhysicsBlockId( int x, int y, int z ) {
|
||||
if( x < 0 || x >= game.Map.Width || z < 0 ||
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace ClassicalSharp {
|
|||
}
|
||||
}
|
||||
|
||||
DateTime last = new DateTime( 1, 1, 1 );
|
||||
DateTime last;
|
||||
StreamWriter writer = null;
|
||||
void LogChatToFile( string text ) {
|
||||
DateTime now = DateTime.Now;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
/// <summary> Contains the hotbar of blocks, as well as the permissions for placing and deleting all blocks. </summary>
|
||||
public sealed class Inventory {
|
||||
|
||||
public Inventory( Game game ) {
|
||||
|
@ -29,6 +30,8 @@ namespace ClassicalSharp {
|
|||
public InventoryPermissions CanPlace = new InventoryPermissions();
|
||||
public InventoryPermissions CanDelete = new InventoryPermissions();
|
||||
|
||||
/// <summary> Gets or sets the index of the held block.
|
||||
/// Fails if the server has forbidden up from changing the held block. </summary>
|
||||
public int HeldBlockIndex {
|
||||
get { return hotbarIndex; }
|
||||
set {
|
||||
|
@ -41,6 +44,8 @@ namespace ClassicalSharp {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets or sets the block currently held by the player.
|
||||
/// Fails if the server has forbidden up from changing the held block. </summary>
|
||||
public Block HeldBlock {
|
||||
get { return Hotbar[hotbarIndex]; }
|
||||
set {
|
||||
|
|
|
@ -336,6 +336,14 @@ namespace ClassicalSharp {
|
|||
info.FogColour[block] = new FastColour(
|
||||
reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
|
||||
info.SetupCullingCache();
|
||||
|
||||
// Update sprite BoundingBox if necessary
|
||||
if( info.IsSprite[block] ) {
|
||||
using( FastBitmap fastBmp =
|
||||
new FastBitmap( game.TerrainAtlas.AtlasBitmap, true ) ) {
|
||||
info.RecalculateBB( block, fastBmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleCpeRemoveBlockDefinition() {
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace ClassicalSharp.Network {
|
|||
worker.Start();
|
||||
}
|
||||
|
||||
/// <summary> Asynchronously downloads a skin. If 'skinName' points to the url then the skin is
|
||||
/// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png </summary>
|
||||
/// <remarks> Identifier is skin_'skinName'.</remarks>
|
||||
public void DownloadSkin( string skinName ) {
|
||||
string strippedSkinName = Utils.StripColours( skinName );
|
||||
string url = Utils.IsUrl( skinName ) ? skinName :
|
||||
|
@ -36,14 +39,17 @@ namespace ClassicalSharp.Network {
|
|||
AddRequest( url, true, "skin_" + strippedSkinName, 0 );
|
||||
}
|
||||
|
||||
/// <summary> Asynchronously downloads a bitmap image from the specified url. </summary>
|
||||
public void DownloadImage( string url, bool priority, string identifier ) {
|
||||
AddRequest( url, priority, identifier, 0 );
|
||||
}
|
||||
|
||||
/// <summary> Asynchronously downloads a string from the specified url. </summary>
|
||||
public void DownloadPage( string url, bool priority, string identifier ) {
|
||||
AddRequest( url, priority, identifier, 1 );
|
||||
}
|
||||
|
||||
/// <summary> Asynchronously downloads a byte array from the specified url. </summary>
|
||||
public void DownloadData( string url, bool priority, string identifier ) {
|
||||
AddRequest( url, priority, identifier, 2 );
|
||||
}
|
||||
|
@ -60,6 +66,10 @@ namespace ClassicalSharp.Network {
|
|||
handle.Set();
|
||||
}
|
||||
|
||||
/// <summary> Informs the asynchronous thread that it should stop processing further requests
|
||||
/// and can consequentially exit the for loop.<br/>
|
||||
/// Note that this will *block** the calling thread as the method waits until the asynchronous
|
||||
/// thread has exited the for loop. </summary>
|
||||
public void Dispose() {
|
||||
lock( requestLocker ) {
|
||||
requests.Insert( 0, null );
|
||||
|
@ -71,6 +81,8 @@ namespace ClassicalSharp.Network {
|
|||
client.Dispose();
|
||||
}
|
||||
|
||||
/// <summary> Removes older entries that were downloaded a certain time ago
|
||||
/// but were never removed from the downloaded queue. </summary>
|
||||
public void PurgeOldEntries( int seconds ) {
|
||||
lock( downloadedLocker ) {
|
||||
DateTime now = DateTime.UtcNow;
|
||||
|
@ -95,6 +107,10 @@ namespace ClassicalSharp.Network {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns whether the requested item exists in the downloaded queue.
|
||||
/// If it does, it removes the item from the queue and outputs it. </summary>
|
||||
/// <remarks> If the asynchronous thread failed to download the item, this method
|
||||
/// will return 'true' and 'item' will be set. However, the contents of the 'item' object will be null.</remarks>
|
||||
public bool TryGetItem( string identifier, out DownloadedItem item ) {
|
||||
bool success = false;
|
||||
lock( downloadedLocker ) {
|
||||
|
@ -167,8 +183,8 @@ namespace ClassicalSharp.Network {
|
|||
downloaded[request.Identifier] = newItem;
|
||||
}
|
||||
}
|
||||
|
||||
class GZipWebClient : WebClient {
|
||||
|
||||
sealed class GZipWebClient : WebClient {
|
||||
|
||||
protected override WebRequest GetWebRequest( Uri address ) {
|
||||
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest( address );
|
||||
|
@ -177,7 +193,7 @@ namespace ClassicalSharp.Network {
|
|||
}
|
||||
}
|
||||
|
||||
class Request {
|
||||
sealed class Request {
|
||||
|
||||
public string Url;
|
||||
public string Identifier;
|
||||
|
@ -193,10 +209,21 @@ namespace ClassicalSharp.Network {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Represents an item that was asynchronously downloaded. </summary>
|
||||
public class DownloadedItem {
|
||||
|
||||
/// <summary> Contents that were downloaded. Can be a bitmap, string or byte array. </summary>
|
||||
public object Data;
|
||||
public DateTime TimeAdded, TimeDownloaded;
|
||||
|
||||
/// <summary> Instant in time the item was originally added to the download queue. </summary>
|
||||
public DateTime TimeAdded;
|
||||
|
||||
/// <summary> Instant in time the item was fully downloaded. </summary>
|
||||
public DateTime TimeDownloaded;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Url;
|
||||
|
||||
public DownloadedItem( object data, DateTime timeAdded, string url ) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using OpenTK;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Renderers {
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue