mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-09 14:03:42 -04:00
202 lines
6.1 KiB
C#
202 lines
6.1 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using ClassicalSharp.GraphicsAPI;
|
|
using OpenTK.Input;
|
|
|
|
namespace ClassicalSharp {
|
|
|
|
public class BlockSelectScreen : Screen {
|
|
|
|
public BlockSelectScreen( Game game ) : base( game ) {
|
|
font = new Font( "Arial", 13 );
|
|
}
|
|
|
|
Block[] blocksTable;
|
|
Texture blockInfoTexture;
|
|
const int blockSize = 48, blocksPerRow = 10;
|
|
int selectedIndex;
|
|
int rows;
|
|
int startX, startY;
|
|
readonly Font font;
|
|
StringBuffer buffer = new StringBuffer( 96 );
|
|
|
|
static FastColour backCol = new FastColour( 30, 30, 30, 200 );
|
|
static FastColour selCol = new FastColour( 213, 200, 223 );
|
|
public override void Render( double delta ) {
|
|
graphicsApi.Draw2DQuad( startX - 5, startY - 30 - 5, blocksPerRow * blockSize + 10,
|
|
rows * blockSize + 30 + 10, backCol );
|
|
graphicsApi.Texturing = true;
|
|
graphicsApi.BindTexture( game.TerrainAtlas.TexId );
|
|
graphicsApi.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
|
|
|
|
for( int i = 0; i < blocksTable.Length; i++ ) {
|
|
int x, y;
|
|
GetCoords( i, out x, out y );
|
|
|
|
// We want to always draw the selected block on top of others
|
|
if( i == selectedIndex ) continue;
|
|
IsometricBlockDrawer.Draw( game, (byte)blocksTable[i], 12,
|
|
x + blockSize / 2, y + 28 );
|
|
}
|
|
|
|
if( selectedIndex != -1 ) {
|
|
int x, y;
|
|
GetCoords( selectedIndex, out x, out y );
|
|
IsometricBlockDrawer.Draw( game, (byte)blocksTable[selectedIndex], 20,
|
|
x + blockSize / 2, y + 28 );
|
|
}
|
|
|
|
if( blockInfoTexture.IsValid )
|
|
blockInfoTexture.Render( graphicsApi );
|
|
graphicsApi.Texturing = false;
|
|
}
|
|
|
|
void GetCoords( int i, out int x, out int y ) {
|
|
int col = i % blocksPerRow;
|
|
int row = i / blocksPerRow;
|
|
x = startX + blockSize * col;
|
|
y = startY + blockSize * row;
|
|
}
|
|
|
|
public override void Dispose() {
|
|
font.Dispose();
|
|
graphicsApi.DeleteTexture( ref blockInfoTexture );
|
|
game.Events.BlockPermissionsChanged -= BlockPermissionsChanged;
|
|
}
|
|
|
|
public override void OnResize( int oldWidth, int oldHeight, int width, int height ) {
|
|
int yDiff = (height - oldHeight) / 2;
|
|
int xDiff = (width - oldWidth) / 2;
|
|
startX += xDiff;
|
|
startY += yDiff;
|
|
blockInfoTexture.X1 += xDiff;
|
|
blockInfoTexture.Y1 += yDiff;
|
|
}
|
|
|
|
public override void Init() {
|
|
game.Events.BlockPermissionsChanged += BlockPermissionsChanged;
|
|
RecreateBlockTextures();
|
|
}
|
|
|
|
void BlockPermissionsChanged( object sender, EventArgs e ) {
|
|
RecreateBlockTextures();
|
|
if( selectedIndex >= blocksTable.Length ) {
|
|
selectedIndex = blocksTable.Length - 1;
|
|
}
|
|
RecreateBlockInfoTexture();
|
|
}
|
|
|
|
void UpdateBlockInfoString( Block block ) {
|
|
int index = 0;
|
|
buffer.Clear();
|
|
buffer.Append( ref index, "&f" );
|
|
if( block == Block.TNT ) {
|
|
buffer.Append( ref index, "TNT" );
|
|
} else {
|
|
string value = game.BlockInfo.Name[(byte)block];
|
|
if( (byte)block < BlockInfo.CpeBlocksCount ) {
|
|
SplitUppercase( value, ref index );
|
|
} else {
|
|
buffer.Append( ref index, value );
|
|
}
|
|
}
|
|
buffer.Append( ref index, " (can place: " );
|
|
buffer.Append( ref index, game.Inventory.CanPlace[(int)block] ? "&aYes" : "&cNo" );
|
|
buffer.Append( ref index, "&f, can delete: " );
|
|
buffer.Append( ref index, game.Inventory.CanDelete[(int)block] ? "&aYes" : "&cNo" );
|
|
buffer.Append( ref index, "&f)" );
|
|
}
|
|
|
|
void SplitUppercase( string value, ref int index ) {
|
|
for( int i = 0; i < value.Length; i++ ) {
|
|
char c = value[i];
|
|
if( Char.IsUpper( c ) && i > 0 ) {
|
|
buffer.Append( ref index, ' ' );
|
|
}
|
|
buffer.Append( ref index, c );
|
|
}
|
|
}
|
|
|
|
int lastCreatedIndex = -1000;
|
|
void RecreateBlockInfoTexture() {
|
|
if( selectedIndex == lastCreatedIndex ) return;
|
|
lastCreatedIndex = selectedIndex;
|
|
|
|
graphicsApi.DeleteTexture( ref blockInfoTexture );
|
|
if( selectedIndex == -1 ) return;
|
|
|
|
Block block = blocksTable[selectedIndex];
|
|
UpdateBlockInfoString( block );
|
|
string value = buffer.GetString();
|
|
|
|
Size size = game.Drawer2D.MeasureSize( value, font, true );
|
|
int x = startX + (blockSize * blocksPerRow) / 2 - size.Width / 2;
|
|
int y = startY - size.Height - 5;
|
|
|
|
DrawTextArgs args = new DrawTextArgs( value, true );
|
|
args.SkipPartsCheck = true;
|
|
blockInfoTexture = game.Drawer2D.MakeTextTexture( font, x, y, ref args );
|
|
}
|
|
|
|
void RecreateBlockTextures() {
|
|
int blocksCount = 0;
|
|
for( int tile = 1; tile < BlockInfo.BlocksCount; tile++ ) {
|
|
if( game.Inventory.CanPlace[tile] || game.Inventory.CanDelete[tile] )
|
|
blocksCount++;
|
|
}
|
|
|
|
rows = Utils.CeilDiv( blocksCount, blocksPerRow );
|
|
startX = game.Width / 2 - (blockSize * blocksPerRow) / 2;
|
|
startY = game.Height / 2 - (rows * blockSize) / 2;
|
|
blocksTable = new Block[blocksCount];
|
|
|
|
int tableIndex = 0;
|
|
for( int tile = 1; tile < BlockInfo.BlocksCount; tile++ ) {
|
|
if( game.Inventory.CanPlace[tile] || game.Inventory.CanDelete[tile] )
|
|
blocksTable[tableIndex++] = (Block)tile;
|
|
}
|
|
}
|
|
|
|
public override bool HandlesAllInput {
|
|
get { return true; }
|
|
}
|
|
|
|
public override bool HandlesMouseMove( int mouseX, int mouseY ) {
|
|
selectedIndex = -1;
|
|
if( Contains( startX, startY, blocksPerRow * blockSize, rows * blockSize, mouseX, mouseY ) ) {
|
|
for( int i = 0; i < blocksTable.Length; i++ ) {
|
|
int x, y;
|
|
GetCoords( i, out x, out y );
|
|
|
|
if( Contains( x, y, blockSize, blockSize, mouseX, mouseY ) ) {
|
|
selectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
RecreateBlockInfoTexture();
|
|
return true;
|
|
}
|
|
|
|
public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
|
|
if( button == MouseButton.Left && selectedIndex != -1 ) {
|
|
game.Inventory.HeldBlock = blocksTable[selectedIndex];
|
|
game.SetNewScreen( new NormalScreen( game ) );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override bool HandlesKeyDown( Key key ) {
|
|
if( key == game.Keys[KeyMapping.PauseOrExit] ||
|
|
key == game.Keys[KeyMapping.OpenInventory] ) {
|
|
game.SetNewScreen( new NormalScreen( game ) );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool Contains( int recX, int recY, int width, int height, int x, int y ) {
|
|
return x >= recX && y >= recY && x < recX + width && y < recY + height;
|
|
}
|
|
}
|
|
}
|