mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 17:12:25 -05:00
Add 'time been playing for' that can be shown by pressing F9 (Thanks BDlikes), finally finish entity shadows.
This commit is contained in:
parent
25a4f792fe
commit
36ff4f7b6e
14 changed files with 285 additions and 209 deletions
|
@ -13,152 +13,173 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
int chatLines;
|
||||
Texture announcementTex;
|
||||
ChatTextWidget announcement, clock;
|
||||
TextInputWidget textInput;
|
||||
TextGroupWidget status, bottomRight, normalChat, clientStatus;
|
||||
bool suppressNextPress = true;
|
||||
int chatIndex;
|
||||
int blockSize;
|
||||
|
||||
public override void Render( double delta ) {
|
||||
if( !game.PureClassicMode ) {
|
||||
status.Render( delta );
|
||||
bottomRight.Render( delta );
|
||||
}
|
||||
|
||||
UpdateChatYOffset( false );
|
||||
RenderClientStatus();
|
||||
DateTime now = DateTime.UtcNow;
|
||||
if( HandlesAllInput )
|
||||
normalChat.Render( delta );
|
||||
else
|
||||
RenderRecentChat( now, delta );
|
||||
|
||||
if( !game.PureClassicMode && announcementTex.IsValid )
|
||||
announcementTex.Render( graphicsApi );
|
||||
if( HandlesAllInput )
|
||||
textInput.Render( delta );
|
||||
|
||||
if( game.Chat.Announcement.Text != null && announcementTex.IsValid &&
|
||||
(now - game.Chat.Announcement.Received).TotalSeconds > 5 ) {
|
||||
graphicsApi.DeleteTexture( ref announcementTex );
|
||||
}
|
||||
}
|
||||
|
||||
void RenderRecentChat( DateTime now, double delta ) {
|
||||
int[] metadata = (int[])Metadata;
|
||||
for( int i = 0; i < normalChat.Textures.Length; i++ ) {
|
||||
Texture texture = normalChat.Textures[i];
|
||||
if( !texture.IsValid ) continue;
|
||||
|
||||
DateTime received = game.Chat.Log[metadata[i]].Received;
|
||||
if( (now - received).TotalSeconds <= 10 )
|
||||
texture.Render( graphicsApi );
|
||||
}
|
||||
}
|
||||
|
||||
void RenderClientStatus() {
|
||||
int y = clientStatus.Y + clientStatus.Height;
|
||||
for( int i = 0; i < clientStatus.Textures.Length; i++ ) {
|
||||
Texture texture = clientStatus.Textures[i];
|
||||
if( !texture.IsValid ) continue;
|
||||
|
||||
y -= texture.Height;
|
||||
texture.Y1 = y;
|
||||
texture.Render( graphicsApi );
|
||||
}
|
||||
}
|
||||
|
||||
static FastColour backColour = new FastColour( 60, 60, 60, 180 );
|
||||
public void RenderBackground() {
|
||||
int height = normalChat.GetUsedHeight();
|
||||
int y = normalChat.Y + normalChat.Height - height - 5;
|
||||
int x = normalChat.X - 5;
|
||||
int width = Math.Max( clientStatus.Width, normalChat.Width ) + 10;
|
||||
|
||||
int boxHeight = height + clientStatus.GetUsedHeight();
|
||||
if( boxHeight > 0 )
|
||||
graphicsApi.Draw2DQuad( x, y, width, boxHeight + 10, backColour );
|
||||
}
|
||||
|
||||
int inputOldHeight = -1;
|
||||
void UpdateChatYOffset( bool force ) {
|
||||
int height = textInput.RealHeight;
|
||||
if( force || height != inputOldHeight ) {
|
||||
clientStatus.YOffset = height + blockSize + 15;
|
||||
int y = game.Height - clientStatus.Height - clientStatus.YOffset;
|
||||
clientStatus.MoveTo( clientStatus.X, y );
|
||||
|
||||
normalChat.YOffset = clientStatus.YOffset + clientStatus.GetUsedHeight();
|
||||
y = game.Height - normalChat.Height - normalChat.YOffset;
|
||||
normalChat.MoveTo( normalChat.X, y );
|
||||
inputOldHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
Font chatFont, chatInputFont, chatUnderlineFont, announcementFont;
|
||||
Font chatFont, chatBoldFont, chatItalicFont, chatUnderlineFont, announcementFont;
|
||||
public override void Init() {
|
||||
int fontSize = (int)(12 * game.GuiChatScale);
|
||||
Utils.Clamp( ref fontSize, 8, 60 );
|
||||
chatFont = new Font( game.FontName, fontSize );
|
||||
chatInputFont = new Font( game.FontName, fontSize, FontStyle.Bold );
|
||||
chatBoldFont = new Font( game.FontName, fontSize, FontStyle.Bold );
|
||||
chatItalicFont = new Font( game.FontName, fontSize, FontStyle.Italic );
|
||||
chatUnderlineFont = new Font( game.FontName, fontSize, FontStyle.Underline );
|
||||
|
||||
fontSize = (int)(14 * game.GuiChatScale);
|
||||
Utils.Clamp( ref fontSize, 8, 60 );
|
||||
announcementFont = new Font( game.FontName, fontSize );
|
||||
blockSize = (int)(23 * 2 * game.GuiHotbarScale);
|
||||
|
||||
textInput = new TextInputWidget( game, chatFont, chatInputFont );
|
||||
textInput.YOffset = blockSize + 5;
|
||||
status = new TextGroupWidget( game, 3, chatFont, chatUnderlineFont );
|
||||
status.VerticalAnchor = Anchor.LeftOrTop;
|
||||
status.HorizontalAnchor = Anchor.BottomOrRight;
|
||||
status.Init();
|
||||
bottomRight = new TextGroupWidget( game, 3, chatFont, chatUnderlineFont );
|
||||
bottomRight.VerticalAnchor = Anchor.BottomOrRight;
|
||||
bottomRight.HorizontalAnchor = Anchor.BottomOrRight;
|
||||
bottomRight.YOffset = blockSize * 3 / 2;
|
||||
bottomRight.Init();
|
||||
normalChat = new TextGroupWidget( game, chatLines, chatFont, chatUnderlineFont );
|
||||
normalChat.XOffset = 10;
|
||||
normalChat.YOffset = blockSize * 2 + 15;
|
||||
normalChat.HorizontalAnchor = Anchor.LeftOrTop;
|
||||
normalChat.VerticalAnchor = Anchor.BottomOrRight;
|
||||
normalChat.Init();
|
||||
clientStatus = new TextGroupWidget( game, chatLines, chatFont, chatUnderlineFont );
|
||||
clientStatus.XOffset = 10;
|
||||
clientStatus.YOffset = blockSize * 2 + 15;
|
||||
clientStatus.HorizontalAnchor = Anchor.LeftOrTop;
|
||||
clientStatus.VerticalAnchor = Anchor.BottomOrRight;
|
||||
clientStatus.Init();
|
||||
ConstructWidgets();
|
||||
|
||||
int[] indices = new int[chatLines];
|
||||
for( int i = 0; i < indices.Length; i++ )
|
||||
indices[i] = -1;
|
||||
Metadata = indices;
|
||||
SetInitialMessages();
|
||||
|
||||
Chat chat = game.Chat;
|
||||
chatIndex = chat.Log.Count - chatLines;
|
||||
ResetChat();
|
||||
status.SetText( 0, chat.Status1.Text );
|
||||
status.SetText( 1, chat.Status2.Text );
|
||||
status.SetText( 2, chat.Status3.Text );
|
||||
bottomRight.SetText( 2, chat.BottomRight1.Text );
|
||||
bottomRight.SetText( 1, chat.BottomRight2.Text );
|
||||
bottomRight.SetText( 0, chat.BottomRight3.Text );
|
||||
UpdateAnnouncement( chat.Announcement.Text );
|
||||
for( int i = 0; i < chat.ClientStatus.Length; i++ )
|
||||
clientStatus.SetText( i, chat.ClientStatus[i].Text );
|
||||
|
||||
if( game.chatInInputBuffer != null ) {
|
||||
OpenTextInputBar( game.chatInInputBuffer );
|
||||
game.chatInInputBuffer = null;
|
||||
}
|
||||
game.Events.ChatReceived += ChatReceived;
|
||||
game.Events.ChatFontChanged += ChatFontChanged;
|
||||
game.Events.ColourCodesChanged += ColourCodesChanged;
|
||||
}
|
||||
|
||||
void ConstructWidgets() {
|
||||
textInput = new TextInputWidget( game, chatFont, chatBoldFont );
|
||||
textInput.YOffset = blockSize + 5;
|
||||
status = new TextGroupWidget( game, 4, chatFont, chatUnderlineFont,
|
||||
Anchor.BottomOrRight, Anchor.LeftOrTop );
|
||||
status.Init();
|
||||
bottomRight = new TextGroupWidget( game, 3, chatFont, chatUnderlineFont,
|
||||
Anchor.BottomOrRight, Anchor.BottomOrRight );
|
||||
bottomRight.YOffset = blockSize * 3 / 2;
|
||||
bottomRight.Init();
|
||||
normalChat = new TextGroupWidget( game, chatLines, chatFont, chatUnderlineFont,
|
||||
Anchor.LeftOrTop, Anchor.BottomOrRight );
|
||||
normalChat.XOffset = 10;
|
||||
normalChat.YOffset = blockSize * 2 + 15;
|
||||
normalChat.Init();
|
||||
clientStatus = new TextGroupWidget( game, chatLines, chatFont, chatUnderlineFont,
|
||||
Anchor.LeftOrTop, Anchor.BottomOrRight );
|
||||
clientStatus.XOffset = 10;
|
||||
clientStatus.YOffset = blockSize * 2 + 15;
|
||||
clientStatus.Init();
|
||||
announcement = ChatTextWidget.Create( game, 0, 0, null,
|
||||
Anchor.Centre, Anchor.Centre, announcementFont );
|
||||
announcement.YOffset = game.Height / 4;
|
||||
clock = ChatTextWidget.Create( game, 0, 0, null,
|
||||
Anchor.BottomOrRight, Anchor.LeftOrTop, chatItalicFont );
|
||||
}
|
||||
|
||||
void SetInitialMessages() {
|
||||
Chat chat = game.Chat;
|
||||
chatIndex = chat.Log.Count - chatLines;
|
||||
ResetChat();
|
||||
status.SetText( 0, chat.Status1.Text );
|
||||
status.SetText( 1, chat.Status2.Text );
|
||||
status.SetText( 2, chat.Status3.Text );
|
||||
if( game.ShowClock ) clock.SetText( chat.ClientClock.Text );
|
||||
|
||||
bottomRight.SetText( 2, chat.BottomRight1.Text );
|
||||
bottomRight.SetText( 1, chat.BottomRight2.Text );
|
||||
bottomRight.SetText( 0, chat.BottomRight3.Text );
|
||||
announcement.SetText( chat.Announcement.Text );
|
||||
for( int i = 0; i < chat.ClientStatus.Length; i++ )
|
||||
clientStatus.SetText( i, chat.ClientStatus[i].Text );
|
||||
|
||||
if( game.chatInInputBuffer != null ) {
|
||||
OpenTextInputBar( game.chatInInputBuffer );
|
||||
game.chatInInputBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Render( double delta ) {
|
||||
if( !game.PureClassicMode ) {
|
||||
status.Render( delta );
|
||||
bottomRight.Render( delta );
|
||||
}
|
||||
|
||||
if( game.ShowClock ) {
|
||||
if( !clock.IsValid ) clock.SetText( game.Chat.ClientClock.Text );
|
||||
clock.Render( delta );
|
||||
} else if( clock.IsValid ) {
|
||||
clock.Dispose();
|
||||
}
|
||||
int statusOffset = clock.IsValid ? clock.Height : 0;
|
||||
if( statusOffset != oldStatusOffset ) {
|
||||
oldStatusOffset = statusOffset;
|
||||
status.MoveTo( status.X, oldStatusOffset );
|
||||
}
|
||||
|
||||
UpdateChatYOffset( false );
|
||||
RenderClientStatus();
|
||||
DateTime now = DateTime.UtcNow;
|
||||
if( HandlesAllInput )
|
||||
normalChat.Render( delta );
|
||||
else
|
||||
RenderRecentChat( now, delta );
|
||||
|
||||
if( !game.PureClassicMode )
|
||||
announcement.Render( delta );
|
||||
if( HandlesAllInput )
|
||||
textInput.Render( delta );
|
||||
|
||||
if( announcement.IsValid && (now - game.Chat.Announcement.Received).TotalSeconds > 5 )
|
||||
announcement.Dispose();
|
||||
}
|
||||
|
||||
void RenderRecentChat( DateTime now, double delta ) {
|
||||
int[] metadata = (int[])Metadata;
|
||||
for( int i = 0; i < normalChat.Textures.Length; i++ ) {
|
||||
Texture texture = normalChat.Textures[i];
|
||||
if( !texture.IsValid ) continue;
|
||||
|
||||
DateTime received = game.Chat.Log[metadata[i]].Received;
|
||||
if( (now - received).TotalSeconds <= 10 )
|
||||
texture.Render( graphicsApi );
|
||||
}
|
||||
}
|
||||
|
||||
void RenderClientStatus() {
|
||||
int y = clientStatus.Y + clientStatus.Height;
|
||||
for( int i = 0; i < clientStatus.Textures.Length; i++ ) {
|
||||
Texture texture = clientStatus.Textures[i];
|
||||
if( !texture.IsValid ) continue;
|
||||
|
||||
y -= texture.Height;
|
||||
texture.Y1 = y;
|
||||
texture.Render( graphicsApi );
|
||||
}
|
||||
}
|
||||
|
||||
static FastColour backColour = new FastColour( 60, 60, 60, 180 );
|
||||
public void RenderBackground() {
|
||||
int height = normalChat.GetUsedHeight();
|
||||
int y = normalChat.Y + normalChat.Height - height - 5;
|
||||
int x = normalChat.X - 5;
|
||||
int width = Math.Max( clientStatus.Width, normalChat.Width ) + 10;
|
||||
|
||||
int boxHeight = height + clientStatus.GetUsedHeight();
|
||||
if( boxHeight > 0 )
|
||||
graphicsApi.Draw2DQuad( x, y, width, boxHeight + 10, backColour );
|
||||
}
|
||||
|
||||
int inputOldHeight = -1, oldStatusOffset = -1;
|
||||
void UpdateChatYOffset( bool force ) {
|
||||
int height = textInput.RealHeight;
|
||||
if( force || height != inputOldHeight ) {
|
||||
clientStatus.YOffset = height + blockSize + 15;
|
||||
int y = game.Height - clientStatus.Height - clientStatus.YOffset;
|
||||
clientStatus.MoveTo( clientStatus.X, y );
|
||||
|
||||
normalChat.YOffset = clientStatus.YOffset + clientStatus.GetUsedHeight();
|
||||
y = game.Height - normalChat.Height - normalChat.YOffset;
|
||||
normalChat.MoveTo( normalChat.X, y );
|
||||
inputOldHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
void ColourCodesChanged( object sender, EventArgs e ) {
|
||||
textInput.altText.UpdateColours();
|
||||
|
@ -182,10 +203,12 @@ namespace ClassicalSharp {
|
|||
} else if( type >= MessageType.BottomRight1 && type <= MessageType.BottomRight3 ) {
|
||||
bottomRight.SetText( 2 - (int)(type - MessageType.BottomRight1), e.Text );
|
||||
} else if( type == MessageType.Announcement ) {
|
||||
UpdateAnnouncement( e.Text );
|
||||
announcement.SetText( e.Text );
|
||||
} else if( type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus6 ) {
|
||||
clientStatus.SetText( (int)(type - MessageType.ClientStatus1), e.Text );
|
||||
UpdateChatYOffset( true );
|
||||
} else if( type == MessageType.ClientClock && game.ShowClock ) {
|
||||
clock.SetText( e.Text );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,7 +221,8 @@ namespace ClassicalSharp {
|
|||
game.chatInInputBuffer = null;
|
||||
}
|
||||
chatFont.Dispose();
|
||||
chatInputFont.Dispose();
|
||||
chatItalicFont.Dispose();
|
||||
chatBoldFont.Dispose();
|
||||
chatUnderlineFont.Dispose();
|
||||
announcementFont.Dispose();
|
||||
|
||||
|
@ -207,8 +231,8 @@ namespace ClassicalSharp {
|
|||
status.Dispose();
|
||||
bottomRight.Dispose();
|
||||
clientStatus.Dispose();
|
||||
announcement.Dispose();
|
||||
|
||||
graphicsApi.DeleteTexture( ref announcementTex );
|
||||
game.Events.ChatReceived -= ChatReceived;
|
||||
game.Events.ChatFontChanged -= ChatFontChanged;
|
||||
game.Events.ColourCodesChanged -= ColourCodesChanged;
|
||||
|
@ -222,8 +246,9 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
public override void OnResize( int oldWidth, int oldHeight, int width, int height ) {
|
||||
announcementTex.X1 += (width - oldWidth) / 2;
|
||||
announcementTex.Y1 += (height - oldHeight) / 2;
|
||||
announcement.OnResize( oldWidth, oldHeight, width, height );
|
||||
announcement.YOffset = height / 4;
|
||||
announcement.MoveTo( announcement.X, announcement.YOffset - announcement.Height / 2 );
|
||||
blockSize = (int)(23 * 2 * game.GuiHotbarScale);
|
||||
textInput.YOffset = blockSize + 5;
|
||||
bottomRight.YOffset = blockSize * 3 / 2;
|
||||
|
@ -234,14 +259,7 @@ namespace ClassicalSharp {
|
|||
bottomRight.OnResize( oldWidth, oldHeight, width, height );
|
||||
UpdateChatYOffset( true );
|
||||
}
|
||||
|
||||
void UpdateAnnouncement( string text ) {
|
||||
DrawTextArgs args = new DrawTextArgs( text, announcementFont, true );
|
||||
announcementTex = game.Drawer2D.MakeChatTextTexture( ref args, 0, 0 );
|
||||
announcementTex.X1 = game.Width / 2 - announcementTex.Width / 2;
|
||||
announcementTex.Y1 = game.Height / 4 - announcementTex.Height / 2;
|
||||
}
|
||||
|
||||
|
||||
void ResetChat() {
|
||||
normalChat.Dispose();
|
||||
List<ChatLine> chat = game.Chat.Log;
|
||||
|
|
|
@ -30,7 +30,9 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
double accumulator, maxDelta;
|
||||
int fpsCount;
|
||||
int fpsCount, totalSeconds;
|
||||
int oldMinutes = -1;
|
||||
|
||||
void UpdateFPS( double delta ) {
|
||||
fpsCount++;
|
||||
maxDelta = Math.Max( maxDelta, delta );
|
||||
|
@ -38,6 +40,7 @@ namespace ClassicalSharp {
|
|||
|
||||
if( accumulator >= 1 ) {
|
||||
int index = 0;
|
||||
totalSeconds++;
|
||||
if( game.PureClassicMode ) {
|
||||
text.Clear()
|
||||
.AppendNum( ref index, (int)(fpsCount / accumulator) ).Append( ref index, " fps, " )
|
||||
|
@ -49,7 +52,21 @@ namespace ClassicalSharp {
|
|||
.Append( ref index, "), chunks/s: " ).AppendNum( ref index, game.ChunkUpdates )
|
||||
.Append( ref index, ", vertices: " ).AppendNum( ref index, game.Vertices );
|
||||
}
|
||||
|
||||
int minutes = totalSeconds / 60;
|
||||
if( minutes != oldMinutes && game.ShowClock ) {
|
||||
oldMinutes = minutes;
|
||||
TimeSpan span = TimeSpan.FromMinutes( minutes );
|
||||
string format = null;
|
||||
|
||||
if( span.TotalDays > 1 )
|
||||
format = "&eBeen playing for {2} day" + Q( span.Days ) + ", {1} hour" + Q( span.Hours ) + ", {0} min" + Q( span.Minutes );
|
||||
else if( span.TotalHours > 1 )
|
||||
format = "&eBeen playing for {1} hour" + Q( span.Hours ) + ", {0} mins" + Q( span.Minutes );
|
||||
else
|
||||
format = "&eBeen playing for {0} min" + Q( span.Minutes );
|
||||
string spanText = String.Format( format, span.Minutes, span.Hours, span.Days );
|
||||
game.Chat.Add( spanText, MessageType.ClientClock );
|
||||
}
|
||||
|
||||
string textString = text.GetString();
|
||||
fpsTextWidget.SetText( textString );
|
||||
|
@ -60,6 +77,8 @@ namespace ClassicalSharp {
|
|||
}
|
||||
}
|
||||
|
||||
string Q( int value ) { return value == 1 ? "" : "s"; }
|
||||
|
||||
public override void Init() {
|
||||
font = new Font( game.FontName, 13 );
|
||||
posFont = new Font( game.FontName, 12, FontStyle.Italic );
|
||||
|
|
|
@ -6,11 +6,13 @@ namespace ClassicalSharp {
|
|||
|
||||
public sealed partial class TextGroupWidget : Widget {
|
||||
|
||||
public TextGroupWidget( Game game, int elementsCount,
|
||||
Font font, Font underlineFont ) : base( game ) {
|
||||
public TextGroupWidget( Game game, int elementsCount, Font font,
|
||||
Font underlineFont, Anchor horAnchor, Anchor verAnchor ) : base( game ) {
|
||||
ElementsCount = elementsCount;
|
||||
this.font = font;
|
||||
this.underlineFont = underlineFont;
|
||||
HorizontalAnchor = horAnchor;
|
||||
VerticalAnchor = verAnchor;
|
||||
}
|
||||
|
||||
public Texture[] Textures;
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace ClassicalSharp {
|
|||
protected int defaultHeight;
|
||||
protected readonly Font font;
|
||||
|
||||
public bool IsValid { get { return texture.IsValid; } }
|
||||
|
||||
public override void Init() {
|
||||
DrawTextArgs args = new DrawTextArgs( "I", font, true );
|
||||
defaultHeight = game.Drawer2D.MeasureSize( ref args ).Height;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<ProjectGuid>{BEB1C785-5CAD-48FF-A886-876BF0A318D4}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>ClassicalSharp</RootNamespace>
|
||||
<AssemblyName>ClassicalSharp</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
|
|
|
@ -47,53 +47,97 @@ namespace ClassicalSharp {
|
|||
api.UpdateDynamicIndexedVb( DrawMode.Triangles, api.texVb, api.texVerts, 4, 6 );
|
||||
}
|
||||
|
||||
internal void DrawShadow( EntityShadow shadow ) {
|
||||
internal unsafe void DrawShadow( EntityShadow shadow ) {
|
||||
if( shadow == EntityShadow.None ) return;
|
||||
float posX = Position.X, posZ = Position.Z;
|
||||
float x1 = 0, x2 = 0, z1, z2 = 0;
|
||||
float posX = Position.X, posZ = Position.Z;
|
||||
int posY = Math.Min( (int)Position.Y, game.Map.Height - 1 );
|
||||
float y; byte rgb;
|
||||
|
||||
int index = 0, vb = 0;
|
||||
VertexPos3fTex2fCol4b[] verts = null;
|
||||
int coordsCount = 0;
|
||||
Vector3I* coords = stackalloc Vector3I[4];
|
||||
for( int i = 0; i < 4; i++ )
|
||||
coords[i] = Vector3I.Zero;
|
||||
|
||||
if( shadow == EntityShadow.SnapToBlock ) {
|
||||
x1 = Utils.Floor( posX ); x2 = x1 + 1;
|
||||
z1 = Utils.Floor( posZ ); z2 = z1 + 1;
|
||||
vb = game.Graphics.texVb; verts = game.Graphics.texVerts;
|
||||
TextureRec rec = new TextureRec( 63/128f, 63/128f, 1/128f, 1/128f );
|
||||
|
||||
if( !CalculateShadow( coords, ref coordsCount, posX, posZ, posY, out y, out rgb ) )
|
||||
return;
|
||||
float x1 = Utils.Floor( posX ), z1 = Utils.Floor( posZ );
|
||||
DrawShadowPart( verts, ref index, y, rgb, x1, z1, x1 + 1, z1 + 1, rec );
|
||||
} else {
|
||||
x1 = posX - 7/16f; x2 = posX + 7/16f;
|
||||
z1 = posZ - 7/16f; z2 = posZ + 7/16f;
|
||||
}
|
||||
|
||||
int blockX = Utils.Floor( Position.X ), blockZ = Utils.Floor( Position.Z );
|
||||
if( !game.Map.IsValidPos( blockX, 0, blockZ ) || Position.Y < 0 ) return;
|
||||
CheckShadowTexture();
|
||||
BlockInfo info = game.BlockInfo;
|
||||
game.Graphics.BindTexture( shadowTex );
|
||||
|
||||
int y = Math.Min( (int)Position.Y, game.Map.Height - 1 );
|
||||
float shadowY = 0;
|
||||
while( y >= 0 ) {
|
||||
byte block = game.Map.GetBlock( blockX, y, blockZ );
|
||||
if( !(info.IsAir[block] || info.IsSprite[block]) ) {
|
||||
shadowY = y + info.MaxBB[block].Y; break;
|
||||
vb = game.ModelCache.vb; verts = game.ModelCache.vertices;
|
||||
TextureRec rec;
|
||||
|
||||
float x1 = posX - 7/16f, x2 = Math.Min( posX + 7/16f, Utils.Floor( x1 ) + 1 );
|
||||
float z1 = posZ - 7/16f, z2 = Math.Min( posZ + 7/16f, Utils.Floor( z1 ) + 1 );
|
||||
if( CalculateShadow( coords, ref coordsCount, x1, z1, posY, out y, out rgb ) ) {
|
||||
rec = TextureRec.FromPoints( 0, 0, (x2 - x1) * 16/14f, (z2 - z1) * 16/14f );
|
||||
DrawShadowPart( verts, ref index, y, rgb, x1, z1, x2, z2, rec );
|
||||
}
|
||||
|
||||
x2 = posX + 7/16f; x1 = Math.Max( posX - 7/16f, Utils.Floor( x2 ) );
|
||||
if( CalculateShadow( coords, ref coordsCount, x1, z1, posY, out y, out rgb ) ) {
|
||||
rec = TextureRec.FromPoints( 1 - (x2 - x1) * 16/14f, 0, 1, (z2 - z1) * 16/14f );
|
||||
DrawShadowPart( verts, ref index, y, rgb, x1, z1, x2, z2, rec );
|
||||
}
|
||||
|
||||
z2 = posZ + 7/16f; z1 = Math.Max( posZ - 7/16f, Utils.Floor( z2 ) );
|
||||
if( CalculateShadow( coords, ref coordsCount, x1, z1, posY, out y, out rgb ) ) {
|
||||
rec = TextureRec.FromPoints( 1 - (x2 - x1) * 16/14f, 1 - (z2 - z1) * 16/14f, 1, 1 );
|
||||
DrawShadowPart( verts, ref index, y, rgb, x1, z1, x2, z2, rec );
|
||||
}
|
||||
|
||||
x1 = posX - 7/16f; x2 = Math.Min( posX + 7/16f, Utils.Floor( x1 ) + 1 );
|
||||
if( CalculateShadow( coords, ref coordsCount, x1, z1, posY, out y, out rgb ) ) {
|
||||
rec = TextureRec.FromPoints( 0, 1 - (z2 - z1) * 16/14f, (x2 - x1) * 16/14f, 1 );
|
||||
DrawShadowPart( verts, ref index, y, rgb, x1, z1, x2, z2, rec );
|
||||
}
|
||||
y--;
|
||||
}
|
||||
|
||||
byte rgb = 80;
|
||||
if( (Position.Y - y) <= 16 ) { shadowY += 1/32f; rgb = (byte)(80 * (Position.Y - y) / 16); }
|
||||
else if( (Position.Y - y) <= 32 ) shadowY += 1/16f;
|
||||
else if( (Position.Y - y) <= 96 ) shadowY += 1/8f;
|
||||
else shadowY += 1/4f;
|
||||
VertexPos3fTex2fCol4b[] verts = game.Graphics.texVerts;
|
||||
int vb = game.Graphics.texVb;
|
||||
game.Graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b );
|
||||
if( index == 0 ) return;
|
||||
CheckShadowTexture();
|
||||
game.Graphics.BindTexture( shadowTex );
|
||||
game.Graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, verts, index, index * 6 / 4 );
|
||||
}
|
||||
|
||||
unsafe bool CalculateShadow( Vector3I* coords, ref int coordsCount, float x, float z, int posY, out float y, out byte rgb ) {
|
||||
y = 0; rgb = 80;
|
||||
int blockX = Utils.Floor( x ), blockZ = Utils.Floor( z );
|
||||
Vector3I p = new Vector3I( blockX, 0, blockZ );
|
||||
BlockInfo info = game.BlockInfo;
|
||||
|
||||
if( !game.Map.IsValidPos( p ) || Position.Y < 0 ) return false;
|
||||
for( int i = 0; i < 4; i++ )
|
||||
if( coords[i] == p ) return false;
|
||||
|
||||
while( posY >= 0 ) {
|
||||
byte block = game.Map.GetBlock( blockX, posY, blockZ );
|
||||
if( !(info.IsAir[block] || info.IsSprite[block] || info.IsLiquid[block]) ) {
|
||||
float blockY = y = posY + info.MaxBB[block].Y;
|
||||
if( blockY < Position.Y + 0.01f ) { y = blockY; break; }
|
||||
}
|
||||
posY--;
|
||||
}
|
||||
|
||||
coords[coordsCount] = p; coordsCount++;
|
||||
if( (Position.Y - posY) <= 16 ) { y += 1/64f; rgb = (byte)(80 * (Position.Y - posY) / 16); }
|
||||
else if( (Position.Y - posY) <= 32 ) y += 1/16f;
|
||||
else if( (Position.Y - posY) <= 96 ) y += 1/8f;
|
||||
else y += 1/4f;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawShadowPart( VertexPos3fTex2fCol4b[] verts, ref int index, float y, byte rgb,
|
||||
float x1, float z1, float x2, float z2, TextureRec rec ) {
|
||||
FastColour col = new FastColour( rgb, rgb, rgb );
|
||||
float u1 = 0, v1 = 0, u2 = 1, v2 = 1;
|
||||
if( shadow == EntityShadow.SnapToBlock ) {
|
||||
u1 = 63/128f; v1 = 63/128f; u2 = 64/128f; v2 = 64/128f;
|
||||
}
|
||||
verts[0] = new VertexPos3fTex2fCol4b( x1, shadowY, z1, u1, v1, col );
|
||||
verts[1] = new VertexPos3fTex2fCol4b( x2, shadowY, z1, u2, v1, col );
|
||||
verts[2] = new VertexPos3fTex2fCol4b( x2, shadowY, z2, u2, v2, col );
|
||||
verts[3] = new VertexPos3fTex2fCol4b( x1, shadowY, z2, u1, v2, col );
|
||||
game.Graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, verts, 4, 6 );
|
||||
verts[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, rec.U1, rec.V1, col );
|
||||
verts[index++] = new VertexPos3fTex2fCol4b( x2, y, z1, rec.U2, rec.V1, col );
|
||||
verts[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, rec.U2, rec.V2, col );
|
||||
verts[index++] = new VertexPos3fTex2fCol4b( x1, y, z2, rec.U1, rec.V2, col );
|
||||
}
|
||||
|
||||
int shadowTex = -1;
|
||||
|
@ -108,13 +152,13 @@ namespace ClassicalSharp {
|
|||
for( int y = 0; y < fastBmp.Height; y++ ) {
|
||||
int* row = fastBmp.GetRowPtr( y );
|
||||
for( int x = 0; x < fastBmp.Width; x++ ) {
|
||||
double dist = (half - (x + 0.5)) * (half - (x + 0.5)) +
|
||||
double dist = (half - (x + 0.5)) * (half - (x + 0.5)) +
|
||||
(half - (y + 0.5)) * (half - (y + 0.5));
|
||||
row[x] = dist < half * half ? inPix : outPix;
|
||||
}
|
||||
}
|
||||
shadowTex = game.Graphics.CreateTexture( fastBmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace ClassicalSharp {
|
|||
public sealed class Chat : IDisposable {
|
||||
|
||||
public ChatLine Status1, Status2, Status3, BottomRight1,
|
||||
BottomRight2, BottomRight3, Announcement;
|
||||
BottomRight2, BottomRight3, Announcement, ClientClock;
|
||||
public ChatLine[] ClientStatus = new ChatLine[6];
|
||||
|
||||
Game game;
|
||||
|
@ -63,6 +63,8 @@ namespace ClassicalSharp {
|
|||
Announcement = text;
|
||||
} else if( type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus6 ) {
|
||||
ClientStatus[(int)(type - MessageType.ClientStatus1)] = text;
|
||||
} else if( type == MessageType.ClientClock ) {
|
||||
ClientClock = text;
|
||||
}
|
||||
game.Events.RaiseChatReceived( text, type );
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ namespace ClassicalSharp {
|
|||
/// <summary> Whether the third person camera should have their camera position clipped so as to not intersect blocks. </summary>
|
||||
public bool CameraClipping = true;
|
||||
|
||||
public bool ShowClock = false;
|
||||
|
||||
public MapRenderer MapRenderer;
|
||||
public MapBordersRenderer MapBordersRenderer;
|
||||
public EnvRenderer EnvRenderer;
|
||||
|
|
|
@ -350,7 +350,9 @@ namespace ClassicalSharp {
|
|||
} else if( key == Key.F8 ) {
|
||||
int newMode = ((int)game.LocalPlayer.Shadow + 1) % 3;
|
||||
game.LocalPlayer.Shadow = (EntityShadow)newMode;
|
||||
}else {
|
||||
} else if( key == Key.F9 ) {
|
||||
game.ShowClock = !game.ShowClock;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -63,16 +63,14 @@ namespace ClassicalSharp {
|
|||
ClientStatus4 = 259,
|
||||
ClientStatus5 = 260,
|
||||
ClientStatus6 = 261, // no LongerMessages warning
|
||||
ClientClock = 262,
|
||||
}
|
||||
|
||||
public enum CpeBlockFace {
|
||||
XMax, XMin, YMax,
|
||||
YMin, ZMax, ZMin,
|
||||
XMax, XMin, YMax, YMin, ZMax, ZMin,
|
||||
}
|
||||
|
||||
public enum Weather {
|
||||
Sunny,
|
||||
Rainy,
|
||||
Snowy,
|
||||
Sunny, Rainy, Snowy,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace ClassicalSharp {
|
|||
U2 = u + uWidth; V2 = v + vHeight;
|
||||
}
|
||||
|
||||
public static TextureRec FromPoints( float u1, float u2, float v1, float v2 ) {
|
||||
public static TextureRec FromPoints( float u1, float v1, float u2, float v2 ) {
|
||||
TextureRec rec;
|
||||
rec.U1 = u1;rec.U2 = u2;
|
||||
rec.V1 = v1; rec.V2 = v2;
|
||||
rec.U1 = u1; rec.V1 = v1;
|
||||
rec.U2 = u2; rec.V2 = v2;
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,7 @@ namespace ClassicalSharp {
|
|||
}
|
||||
|
||||
internal void SwapU() {
|
||||
float u2 = U2;
|
||||
U2 = U1;
|
||||
U1 = u2;
|
||||
float u2 = U2; U2 = U1; U1 = u2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,11 +142,6 @@
|
|||
<Folder Include="SharpDX" />
|
||||
<Folder Include="SharpDX.Direct3D" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="OpenTK.dll.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\InteropPatcher\InteropPatcher.csproj">
|
||||
<Project>{4A4110EE-21CA-4715-AF67-0C8B7CE0642F}</Project>
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<configuration>
|
||||
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
|
||||
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
|
||||
</configuration>
|
|
@ -6,8 +6,6 @@ namespace OpenTK.Platform.Windows {
|
|||
|
||||
internal partial class Wgl : BindingsBase {
|
||||
|
||||
const string Library = "OPENGL32.DLL";
|
||||
|
||||
protected override IntPtr GetAddress( string funcname ) {
|
||||
return Wgl.wglGetProcAddress( funcname );
|
||||
}
|
||||
|
@ -25,22 +23,22 @@ namespace OpenTK.Platform.Windows {
|
|||
internal delegate int GetSwapIntervalEXT();
|
||||
internal static GetSwapIntervalEXT wglGetSwapIntervalEXT;
|
||||
|
||||
[SuppressUnmanagedCodeSecurity,DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity,DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static IntPtr wglCreateContext(IntPtr hDc);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static Boolean wglDeleteContext(IntPtr oldContext);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static IntPtr wglGetCurrentContext();
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static Boolean wglMakeCurrent(IntPtr hDc, IntPtr newContext);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static IntPtr wglGetCurrentDC();
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(Library, SetLastError = true)]
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("OPENGL32.DLL", SetLastError = true)]
|
||||
internal extern static IntPtr wglGetProcAddress(String lpszProc);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue