diff --git a/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.TextMC.cs b/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.TextMC.cs
index 56ecc0d8c..c1915cf41 100644
--- a/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.TextMC.cs
+++ b/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.TextMC.cs
@@ -90,7 +90,7 @@ namespace ClassicalSharp {
int fontX = srcX + xx * srcWidth / dstWidth;
int pixel = fontRow[fontX];
- if( (byte)(pixel >> 24) < 127 ) continue;
+ if( (byte)(pixel >> 24) == 0 ) continue;
int col = pixel & ~0xFFFFFF;
col |= ((pixel & 0xFF) * textCol.B / 255);
diff --git a/ClassicalSharp/2D/Screens/Menu/EnvSettingsScreen.cs b/ClassicalSharp/2D/Screens/Menu/EnvSettingsScreen.cs
index 59d01e67d..5642c041b 100644
--- a/ClassicalSharp/2D/Screens/Menu/EnvSettingsScreen.cs
+++ b/ClassicalSharp/2D/Screens/Menu/EnvSettingsScreen.cs
@@ -59,7 +59,7 @@ namespace ClassicalSharp {
new HexColourValidator(),
new HexColourValidator(),
new RealValidator( 0, 1000 ),
- new IntegerValidator( -1000, 1000 ),
+ new IntegerValidator( -10000, 10000 ),
new HexColourValidator(),
new HexColourValidator(),
new IntegerValidator( 0, 2 ),
diff --git a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs
new file mode 100644
index 000000000..f0d136487
--- /dev/null
+++ b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Drawing;
+
+namespace ClassicalSharp {
+
+ public sealed partial class AltTextInputWidget : Widget {
+
+ Element[] elements;
+
+ void InitData() {
+ elements = new Element[] {
+ new Element( "Colours", 8 * 3, 3, "&0█&1█&2█&3█&4█&5█&6█&7█&8█&9█&a█&b█&c█&d█&e█&f█" ),
+ new Element( "Math", 16, 1, "ƒ½¼αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°√ⁿ²" ),
+ new Element( "Line/Box", 17, 1, "░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀■" ),
+ new Element( "Letters", 17, 1, "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜáíóúñÑ" ),
+ new Element( "Other", 16, 1, "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼⌂¢£¥₧ªº¿⌐¬¡«»∙·" ),
+ };
+ }
+
+ struct Element {
+ public string Title;
+ public Size TitleSize;
+ public string Contents;
+ public int ItemsPerRow;
+ public int CharsPerItem;
+
+ public Element( string title, int itemsPerRow, int charsPerItem, string contents ) {
+ Title = title;
+ TitleSize = Size.Empty;
+ Contents = contents;
+ ItemsPerRow = itemsPerRow;
+ CharsPerItem = charsPerItem;
+ }
+ }
+
+ unsafe void MeasureContentSizes( Element e, Font font, Size* sizes ) {
+ string s = new String( '\0', e.CharsPerItem );
+ DrawTextArgs args = new DrawTextArgs( s, font, false );
+ // avoid allocating temporary strings here
+ fixed( char* ptr = s ) {
+ for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem ) {
+ for( int j = 0; j < e.CharsPerItem; j++ )
+ ptr[j] = e.Contents[i + j];
+ sizes[i / e.CharsPerItem] = game.Drawer2D.MeasureChatSize( ref args );
+ }
+ }
+ }
+
+ unsafe Size CalculateContentSize( Element e, Size* sizes, out Size elemSize ) {
+ int wrap = e.ItemsPerRow / e.CharsPerItem;
+ elemSize = Size.Empty;
+ for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem )
+ elemSize.Width = Math.Max( elemSize.Width, sizes[i / e.CharsPerItem].Width );
+
+ elemSize.Width += contentSpacing;
+ elemSize.Height = sizes[0].Height + contentSpacing;
+ int rows = Utils.CeilDiv( e.Contents.Length / e.CharsPerItem, wrap );
+ return new Size( elemSize.Width * wrap, elemSize.Height * rows );
+ }
+
+ const int titleSpacing = 10, contentSpacing = 5;
+ int MeasureTitles( Font font ) {
+ int totalWidth = 0;
+ DrawTextArgs args = new DrawTextArgs( null, font, false );
+ for( int i = 0; i < elements.Length; i++ ) {
+ args.Text = elements[i].Title;
+ elements[i].TitleSize = game.Drawer2D.MeasureChatSize( ref args );
+ elements[i].TitleSize.Width += titleSpacing;
+ totalWidth += elements[i].TitleSize.Width;
+ }
+ return totalWidth;
+ }
+
+ void DrawTitles( IDrawer2D drawer, Font font ) {
+ int x = 0;
+ DrawTextArgs args = new DrawTextArgs( null, font, false );
+ for( int i = 0; i < elements.Length; i++ ) {
+ args.Text = elements[i].Title;
+ FastColour col = i == selectedIndex ? new FastColour( 30, 30, 30, 200 ) :
+ new FastColour( 60, 60, 60, 200 );
+ Size size = elements[i].TitleSize;
+
+ drawer.Clear( col, x, 0, size.Width, size.Height );
+ drawer.DrawChatText( ref args, x + titleSpacing / 2, 0 );
+ x += size.Width;
+ }
+ }
+
+ unsafe void DrawContent( IDrawer2D drawer, Font font, Element e, int yOffset ) {
+ string s = new String( '\0', e.CharsPerItem );
+ int wrap = e.ItemsPerRow;
+ DrawTextArgs args = new DrawTextArgs( s, font, false );
+
+ fixed( char* ptr = s ) {
+ for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem ) {
+ for( int j = 0; j < e.CharsPerItem; j++ )
+ ptr[j] = e.Contents[i + j];
+ int item = i / e.CharsPerItem;
+
+ int x = (item % wrap) * elementSize.Width, y = (item / wrap) * elementSize.Height;
+ y += yOffset;
+ drawer.DrawChatText( ref args, x, y );
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
index b40ba35e3..42b96b50a 100644
--- a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
@@ -1,7 +1,6 @@
using System;
using System.Drawing;
using OpenTK.Input;
-using System.Windows.Forms;
namespace ClassicalSharp {
@@ -9,7 +8,7 @@ namespace ClassicalSharp {
public AltTextInputWidget( Game game, Font font, Font boldFont, TextInputWidget parent ) : base( game ) {
HorizontalAnchor = Anchor.LeftOrTop;
- VerticalAnchor = Anchor.LeftOrTop;
+ VerticalAnchor = Anchor.BottomOrRight;
this.font = font;
this.boldFont = boldFont;
this.parent = parent;
@@ -18,55 +17,91 @@ namespace ClassicalSharp {
Texture chatInputTexture;
readonly Font font, boldFont;
TextInputWidget parent;
- Size partSize;
+ Size elementSize;
+ public int YOffset;
+
+ public bool Active;
+ public void SetActive( bool active ) {
+ Active = active;
+ Height = active ? chatInputTexture.Height : 0;
+ }
public override void Render( double delta ) {
chatInputTexture.Render( graphicsApi );
}
public override void Init() {
- X = 5; Y = 45;
- DrawString();
+ X = 5; Y = YOffset;
+ InitData();
+ Redraw();
+ }
+
+ void Redraw() {
+ Make( elements[selectedIndex], font );
+ Width = chatInputTexture.Width;
+ Height = chatInputTexture.Height;
}
- static FastColour backColour = new FastColour( 60, 60, 60, 200 );
- void DrawString() {
- DrawTextArgs args = new DrawTextArgs( "Text ", font, false );
- partSize = game.Drawer2D.MeasureChatSize( ref args );
- Size size = new Size( partSize.Width * 6, partSize.Height * 3 );
+ unsafe void Make( Element e, Font font ) {
+ Size* sizes = stackalloc Size[e.Contents.Length / e.CharsPerItem];
+ MeasureContentSizes( e, font, sizes );
+ Size bodySize = CalculateContentSize( e, sizes, out elementSize );
+ int titleWidth = MeasureTitles( font ), titleHeight = elements[0].TitleSize.Height;
+ Size size = new Size( Math.Max( bodySize.Width, titleWidth ), bodySize.Height + titleHeight );
using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
using( IDrawer2D drawer = game.Drawer2D ) {
drawer.SetBitmap( bmp );
- drawer.Clear( backColour, 0, 0, size.Width, size.Height );
- for( int code = 0; code <= 15; code++ ) {
- int c = code < 10 ? '0' + code : 'a' + (code - 10);
- args.Text = "&" + (char)c + "Text";
-
- int x = (code % 6);
- int y = (code / 6);
- drawer.DrawChatText( ref args, x * partSize.Width, y * partSize.Height );
- }
+ DrawTitles( drawer, font );
+ drawer.Clear( new FastColour( 30, 30, 30, 200 ), 0, titleHeight,
+ size.Width, bodySize.Height );
+
+ DrawContent( drawer, font, e, titleHeight );
chatInputTexture = drawer.Make2DTexture( bmp, size, X, Y );
}
- }
- Height = size.Height;
- Width = size.Width;
+ }
}
- public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
+ int selectedIndex = 0;
+ public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
mouseX -= X; mouseY -= Y;
- mouseX /= partSize.Width; mouseY /= partSize.Height;
- game.Chat.Add( "CLICKY CLICK" + mouseX + "," + mouseY );
-
- int code = mouseY * 6 + mouseX;
- if( code <= 15 ) {
- int c = code < 10 ? '0' + code : 'a' + (code - 10);
- string text = "&" + (char)c;
- parent.AppendText( text );
+ if( IntersectsHeader( mouseX, mouseY ) ) {
+ Dispose();
+ Redraw();
+ } else {
+ IntersectsBody( mouseX, mouseY );
}
return true;
}
+
+ bool IntersectsHeader( int widgetX, int widgetY ) {
+ Rectangle bounds = new Rectangle( 0, 0, 0, 0 );
+ for( int i = 0; i < elements.Length; i++ ) {
+ Size size = elements[i].TitleSize;
+ bounds.Width = size.Width; bounds.Height = size.Height;
+ if( bounds.Contains( widgetX, widgetY ) ) {
+ selectedIndex = i;
+ return true;
+ }
+ bounds.X += size.Width;
+ }
+ return false;
+ }
+
+ void IntersectsBody( int widgetX, int widgetY ) {
+ widgetY -= elements[0].TitleSize.Height;
+ widgetX /= elementSize.Width; widgetY /= elementSize.Height;
+ Element e = elements[selectedIndex];
+ int index = widgetY * e.ItemsPerRow + widgetX;
+ if( index < e.Contents.Length ) {
+ if( selectedIndex == 0 ) {
+ parent.AppendChar( e.Contents[index * e.CharsPerItem] );
+ parent.AppendChar( e.Contents[index * e.CharsPerItem + 1] );
+ } else {
+ parent.AppendChar( e.Contents[index] );
+ }
+ }
+ }
public override void Dispose() {
graphicsApi.DeleteTexture( ref chatInputTexture );
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
index 7936ecb9a..bed085586 100644
--- a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
@@ -21,6 +21,7 @@ namespace ClassicalSharp {
DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
defaultHeight = game.Drawer2D.MeasureChatSize( ref args ).Height;
Height = defaultHeight;
+ //altText = new AltTextInputWidget( game, font, boldFont, this );
}
Texture chatInputTexture, caretTexture;
@@ -45,7 +46,6 @@ namespace ClassicalSharp {
int maxWidth = 0;
public override void Init() {
- //altText = new AltTextInputWidget( game, font, boldFont, this );
//altText.Init();
X = 5;
DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
@@ -131,13 +131,14 @@ namespace ClassicalSharp {
Y = game.Height - Height - YOffset;
chatInputTexture.Y1 = Y;
caretTexture.Y1 += Y;
- Width = size.Width;
+ Width = size.Width;
}
public override void Dispose() {
graphicsApi.DeleteTexture( ref caretTexture );
graphicsApi.DeleteTexture( ref chatInputTexture );
- //altText.Dispose();
+ //if( altText != null )
+ // altText.Dispose();
}
public override void MoveTo( int newX, int newY ) {
@@ -205,6 +206,7 @@ namespace ClassicalSharp {
if( chatInputText.Length + text.Length > len ) {
text = text.Substring( 0, len - chatInputText.Length );
}
+ if( text == "" ) return;
if( caretPos == -1 ) {
chatInputText.InsertAt( chatInputText.Length, text );
@@ -216,5 +218,19 @@ namespace ClassicalSharp {
Dispose();
Init();
}
+
+ public void AppendChar( char c ) {
+ if( chatInputText.Length == len ) return;
+
+ if( caretPos == -1 ) {
+ chatInputText.InsertAt( chatInputText.Length, c );
+ } else {
+ chatInputText.InsertAt( caretPos, c );
+ caretPos++;
+ if( caretPos >= chatInputText.Length ) caretPos = -1;
+ }
+ Dispose();
+ Init();
+ }
}
}
\ No newline at end of file
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index 8fe8fddbb..6d9eb207f 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -105,6 +105,7 @@
+
diff --git a/ClassicalSharp/Rendering/WeatherRenderer.cs b/ClassicalSharp/Rendering/WeatherRenderer.cs
index 44fa0bd74..1ee0a2a66 100644
--- a/ClassicalSharp/Rendering/WeatherRenderer.cs
+++ b/ClassicalSharp/Rendering/WeatherRenderer.cs
@@ -40,8 +40,8 @@ namespace ClassicalSharp {
FastColour col = FastColour.White;
for( int dx = -extent; dx <= extent; dx++ ) {
for( int dz = -extent; dz <= extent; dz++ ) {
- int rainY = Math.Max( pos.Y, GetRainHeight( pos.X + dx, pos.Z + dz ) + 1 );
- int height = Math.Min( 20 - (rainY - pos.Y), 20 );
+ float rainY = GetRainHeight( pos.X + dx, pos.Z + dz );
+ float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY;
if( height <= 0 ) continue;
col.A = (byte)Math.Max( 0, AlphaAt( dx * dx + dz * dz ) );
@@ -64,9 +64,10 @@ namespace ClassicalSharp {
return 0.05f * x * x - 7 * x + 178;
}
- void MakeRainForSquare( int x, int y, int height, int z, FastColour col, ref int index ) {
- float v1 = vOffset + (z & 0x01) * 0.5f - (x & 0x0F) * 0.0625f;
- float v2 = height / 6f + v1;
+ void MakeRainForSquare( int x, float y, float height, int z, FastColour col, ref int index ) {
+ float worldV = vOffset + (z & 1) / 2f - (x & 0x0F) / 16f;
+ float v1 = y / 6f + worldV;
+ float v2 = (y + height) / 6f + worldV;
vertices[index++] = new VertexPos3fTex2fCol4b( x, y, z, 0, v2, col );
vertices[index++] = new VertexPos3fTex2fCol4b( x, y + height, z, 0, v1, col );
@@ -107,11 +108,12 @@ namespace ClassicalSharp {
graphics.DeleteDynamicVb( weatherVb );
}
- int GetRainHeight( int x, int z ) {
- if( x < 0 || z < 0 || x >= width || z >= length ) return map.EdgeHeight - 1;
- int index = ( x * length ) + z;
+ float GetRainHeight( int x, int z ) {
+ if( x < 0 || z < 0 || x >= width || z >= length ) return map.EdgeHeight;
+ int index = (x * length) + z;
int height = heightmap[index];
- return height == short.MaxValue ? CalcHeightAt( x, maxY, z, index ) : height;
+ int y = height == short.MaxValue ? CalcHeightAt( x, maxY, z, index ) : height;
+ return y + game.BlockInfo.Height[map.GetBlock( x, y, z )];
}
int CalcHeightAt( int x, int maxY, int z, int index ) {
diff --git a/ClassicalSharp/Selections/SelectionBox.cs b/ClassicalSharp/Selections/SelectionBox.cs
index cec000fbe..9c444a566 100644
--- a/ClassicalSharp/Selections/SelectionBox.cs
+++ b/ClassicalSharp/Selections/SelectionBox.cs
@@ -16,10 +16,14 @@ namespace ClassicalSharp.Selections {
Colour = col;
}
- public void Render( double delta, VertexPos3fCol4b[] vertices, VertexPos3fCol4b[] lineVertices,
+ public void Render( double delta, Vector3 cameraPos, VertexPos3fCol4b[] vertices, VertexPos3fCol4b[] lineVertices,
ref int index, ref int lineIndex ) {
- Vector3 p1 = (Vector3)Min + new Vector3( 1/16f, 1/16f, 1/16f );
- Vector3 p2 = (Vector3)Max - new Vector3( 1/16f, 1/16f, 1/16f );
+ float dist = Math.Min( Utils.DistanceSquared( (Vector3)Min, cameraPos ),
+ Utils.DistanceSquared( (Vector3)Max, cameraPos ) );
+ float offset = dist < 32 * 32 ? 1/32f : 1/16f;
+ Vector3 p1 = (Vector3)Min + new Vector3( offset );
+ Vector3 p2 = (Vector3)Max - new Vector3( offset );
+
FastColour col = Colour;
YQuad( vertices, ref index, p1.X, p1.Z, p2.X, p2.Z, p1.Y, col ); // bottom
diff --git a/ClassicalSharp/Selections/SelectionManager.cs b/ClassicalSharp/Selections/SelectionManager.cs
index c906074d2..cb4fcd1e4 100644
--- a/ClassicalSharp/Selections/SelectionManager.cs
+++ b/ClassicalSharp/Selections/SelectionManager.cs
@@ -43,7 +43,7 @@ namespace ClassicalSharp.Selections {
// TODO: Proper selection box sorting. But this is very difficult because
// we can have boxes within boxes, intersecting boxes, etc. Probably not worth it.
- comparer.pos = player.Position;
+ comparer.pos = game.Camera.GetCameraPos( player.EyePosition );
selections.Sort( comparer );
if( vertices == null )
InitData(); // lazy init as most servers don't use this.
@@ -51,7 +51,7 @@ namespace ClassicalSharp.Selections {
int index = 0, lineIndex = 0;
for( int i = 0; i < selections.Count; i++ ) {
SelectionBox box = selections[i];
- box.Render( delta, vertices, lineVertices, ref index, ref lineIndex );
+ box.Render( delta, comparer.pos, vertices, lineVertices, ref index, ref lineIndex );
}
Graphics.SetBatchFormat( VertexFormat.Pos3fCol4b );
diff --git a/OpenTK/Math/Vector3.cs b/OpenTK/Math/Vector3.cs
index 98fc3e748..660cfa281 100644
--- a/OpenTK/Math/Vector3.cs
+++ b/OpenTK/Math/Vector3.cs
@@ -37,27 +37,23 @@ namespace OpenTK {
public float Z;
public Vector3(float x, float y, float z) {
- X = x;
- Y = y;
- Z = z;
+ X = x; Y = y; Z = z;
+ }
+
+ public Vector3(float value) {
+ X = value; Y = value; Z = value;
}
public Vector3(Vector2 v) {
- X = v.X;
- Y = v.Y;
- Z = 0.0f;
+ X = v.X; Y = v.Y; Z = 0.0f;
}
public Vector3(Vector3 v) {
- X = v.X;
- Y = v.Y;
- Z = v.Z;
+ X = v.X; Y = v.Y; Z = v.Z;
}
public Vector3(Vector4 v) {
- X = v.X;
- Y = v.Y;
- Z = v.Z;
+ X = v.X; Y = v.Y; Z = v.Z;
}
public float Length {