From 76452c75d10620c5be24c18d1febc7fc379cbfff Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 31 Dec 2015 16:02:49 +1100 Subject: [PATCH] Implement EnvMapAppearance v2 extension. --- .../2D/Screens/Menu/OptionsScreen.cs | 2 +- ClassicalSharp/Game/Game.Properties.cs | 1 + ClassicalSharp/Game/Game.cs | 21 +++++++---- ClassicalSharp/Game/InputHandler.cs | 8 ++--- .../Network/NetworkProcessor.CPE.cs | 35 ++++++++++--------- ClassicalSharp/Rendering/MapRenderer.cs | 3 +- .../Rendering/StandardEnvRenderer.cs | 8 ++--- 7 files changed, 44 insertions(+), 34 deletions(-) diff --git a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs index 427cf2a26..9035c8bc0 100644 --- a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs @@ -40,7 +40,7 @@ namespace ClassicalSharp { Make( -140, 50, "View distance", OnWidgetClick, g => g.ViewDistance.ToString(), - (g, v) => g.SetViewDistance( Int32.Parse( v ) ) ), + (g, v) => g.SetViewDistance( Int32.Parse( v ), true ) ), // Column 2 !network.IsSinglePlayer ? null : diff --git a/ClassicalSharp/Game/Game.Properties.cs b/ClassicalSharp/Game/Game.Properties.cs index c53bf0af0..34c6ccdb1 100644 --- a/ClassicalSharp/Game/Game.Properties.cs +++ b/ClassicalSharp/Game/Game.Properties.cs @@ -98,6 +98,7 @@ namespace ClassicalSharp { /// Radius of the sphere the player can see around the position of the current camera. public int ViewDistance = 512; + internal int MaxViewDistance = 32768, UserViewDistance = 512; /// Field of view for the current camera in degrees. public int FieldOfView = 70; diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index 0f9856d3b..40f825494 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -44,6 +44,7 @@ namespace ClassicalSharp { Options.Load(); AcceptedUrls.Load(); ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 ); + UserViewDistance = ViewDistance; CameraClipping = Options.GetBool( OptionsKey.CameraClipping, true ); InputHandler = new InputHandler( this ); Chat = new ChatLog( this ); @@ -146,10 +147,16 @@ namespace ClassicalSharp { } } - public void SetViewDistance( int distance ) { + public void SetViewDistance( int distance, bool save ) { ViewDistance = distance; - Utils.LogDebug( "setting view distance to: " + distance ); - Options.Set( OptionsKey.ViewDist, distance ); + if( ViewDistance > MaxViewDistance ) + ViewDistance = MaxViewDistance; + Utils.LogDebug( "setting view distance to: {0} ({1})", distance, ViewDistance ); + + if( save ) { + UserViewDistance = distance; + Options.Set( OptionsKey.ViewDist, distance ); + } Events.RaiseViewDistanceChanged(); UpdateProjection(); } @@ -186,12 +193,12 @@ namespace ClassicalSharp { Culling.CalcFrustumEquations( ref Projection, ref modelView ); bool visible = activeScreen == null || !activeScreen.BlocksWorld; - if( visible ) { + if( visible ) { AxisLinesRenderer.Render( e.Time ); Players.RenderModels( Graphics, e.Time, t ); Players.RenderNames( Graphics, e.Time, t ); CurrentCameraPos = Camera.GetCameraPos( LocalPlayer.EyePosition ); - + ParticleManager.Render( e.Time, t ); Camera.GetPickedBlock( SelectedPos ); // TODO: only pick when necessary EnvRenderer.Render( e.Time ); @@ -357,8 +364,8 @@ namespace ClassicalSharp { //else if( Camera == forwardThirdPersonCam ) Camera = firstPersonZoomCam; else Camera = firstPersonCam; - if( !LocalPlayer.CanUseThirdPersonCamera ) - Camera = firstPersonCam; + if( !LocalPlayer.CanUseThirdPersonCamera ) + Camera = firstPersonCam; PerspectiveCamera newCam = (PerspectiveCamera)Camera; newCam.delta = oldCam.delta; newCam.previous = oldCam.previous; diff --git a/ClassicalSharp/Game/InputHandler.cs b/ClassicalSharp/Game/InputHandler.cs index 7dc855d0e..446930ccd 100644 --- a/ClassicalSharp/Game/InputHandler.cs +++ b/ClassicalSharp/Game/InputHandler.cs @@ -362,20 +362,20 @@ namespace ClassicalSharp { for( int i = 0; i < viewDistances.Length; i++ ) { int dist = viewDistances[i]; if( dist > game.ViewDistance ) { - game.SetViewDistance( dist ); return; + game.SetViewDistance( dist, true ); return; } } - game.SetViewDistance( viewDistances[0] ); + game.SetViewDistance( viewDistances[0], true ); } void CycleDistanceBackwards() { for( int i = viewDistances.Length - 1; i >= 0; i-- ) { int dist = viewDistances[i]; if( dist < game.ViewDistance ) { - game.SetViewDistance( dist ); return; + game.SetViewDistance( dist, true ); return; } } - game.SetViewDistance( viewDistances[viewDistances.Length - 1] ); + game.SetViewDistance( viewDistances[viewDistances.Length - 1], true ); } float fovIndex = -1; diff --git a/ClassicalSharp/Network/NetworkProcessor.CPE.cs b/ClassicalSharp/Network/NetworkProcessor.CPE.cs index 4f3eb18cc..8ffcae458 100644 --- a/ClassicalSharp/Network/NetworkProcessor.CPE.cs +++ b/ClassicalSharp/Network/NetworkProcessor.CPE.cs @@ -55,7 +55,7 @@ namespace ClassicalSharp { #region Reading int cpeServerExtensionsCount; - bool sendHeldBlock, useMessageTypes, usingTexturePack; + bool sendHeldBlock, useMessageTypes; static string[] clientExtensions = { "ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList", @@ -91,7 +91,7 @@ namespace ClassicalSharp { } else if( extName == "PlayerClick" ) { UsingPlayerClick = true; } else if( extName == "EnvMapAppearance" && extVersion == 2 ) { - usingTexturePack = true; + handlers[(int)PacketId.CpeEnvSetMapApperance] = HandleCpeEnvSetMapAppearance2; packetSizes[(int)PacketId.CpeEnvSetMapApperance] += 4; } else if( extName == "LongerMessages" ) { ServerSupportsPatialMessages = true; @@ -108,7 +108,7 @@ namespace ClassicalSharp { SendPacket(); for( int i = 0; i < clientExtensions.Length; i++ ) { string name = clientExtensions[i]; - int version = (name == "ExtPlayerList") ? 2 : 1; + int version = (name == "ExtPlayerList" || name == "EnvMapAppearance") ? 2 : 1; MakeExtEntry( name, version ); SendPacket(); } @@ -175,7 +175,7 @@ namespace ClassicalSharp { byte groupRank = reader.ReadUInt8(); // Workaround for some servers that don't cast signed bytes to unsigned, before converting them to shorts. - if( nameId < 0 ) + if( nameId < 0 ) nameId += 256; if( nameId >= 0 && nameId <= 255 ) AddCpeInfo( (byte)nameId, playerName, listName, groupName, groupRank ); @@ -209,7 +209,7 @@ namespace ClassicalSharp { void HandleCpeExtRemovePlayerName() { short nameId = reader.ReadInt16(); // Workaround for some servers that don't cast signed bytes to unsigned, before converting them to shorts. - if( nameId < 0 ) + if( nameId < 0 ) nameId += 256; if( nameId >= 0 && nameId <= 255 ) { @@ -297,11 +297,6 @@ namespace ClassicalSharp { game.Map.SetSidesBlock( (Block)reader.ReadUInt8() ); game.Map.SetEdgeBlock( (Block)reader.ReadUInt8() ); game.Map.SetEdgeLevel( reader.ReadInt16() ); - if( usingTexturePack ) { - // TODO: proper envmapappearance version 2 support - game.Map.SetCloudsLevel( reader.ReadInt16() ); - short maxViewDist = reader.ReadInt16(); // TODO: what to do with this? - } if( url == String.Empty ) { TexturePackExtractor extractor = new TexturePackExtractor(); @@ -321,7 +316,15 @@ namespace ClassicalSharp { Utils.LogDebug( "Image url: " + url ); } - void DownloadTexturePack( WarningScreen screen ) { + void HandleCpeEnvSetMapAppearance2() { + HandleCpeEnvSetMapApperance(); + game.Map.SetCloudsLevel( reader.ReadInt16() ); + short maxViewDist = reader.ReadInt16(); + game.MaxViewDistance = maxViewDist <= 0 ? 32768 : maxViewDist; + game.SetViewDistance( game.UserViewDistance, false ); + } + + void DownloadTexturePack( WarningScreen screen ) { DownloadTexturePack( ((string)screen.Metadata).Substring( 3 ) ); } @@ -330,10 +333,8 @@ namespace ClassicalSharp { DateTime lastModified = TextureCache.GetLastModifiedFromCache( url ); if( !game.AcceptedUrls.HasAccepted( url ) ) game.AcceptedUrls.AddAccepted( url ); - - // NOTE: This is entirely against the original CPE specification, but we - // do it here as a convenience until EnvMapAppearance v2 is more widely adopted. - if( usingTexturePack || url.EndsWith( ".zip" ) ) + + if( url.EndsWith( ".zip" ) ) game.AsyncDownloader.DownloadData( url, true, "texturePack", lastModified ); else game.AsyncDownloader.DownloadImage( url, true, "terrain", lastModified ); @@ -382,7 +383,7 @@ namespace ClassicalSharp { void HandleCpeDefineBlock() { byte block = HandleCpeDefineBlockCommonStart(); - BlockInfo info = game.BlockInfo; + BlockInfo info = game.BlockInfo; byte shape = reader.ReadUInt8(); if( shape == 0 ) { info.IsSprite[block] = true; @@ -502,7 +503,7 @@ namespace ClassicalSharp { } static int ReadInt32( byte[] buffer, int offset ) { - return buffer[offset + 0] << 24 | buffer[offset + 1] << 16 + return buffer[offset + 0] << 24 | buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3]; } diff --git a/ClassicalSharp/Rendering/MapRenderer.cs b/ClassicalSharp/Rendering/MapRenderer.cs index fc3d6582a..21ba584e9 100644 --- a/ClassicalSharp/Rendering/MapRenderer.cs +++ b/ClassicalSharp/Rendering/MapRenderer.cs @@ -261,7 +261,8 @@ namespace ClassicalSharp { const double targetTime = (1.0 / 30) + 0.01; void UpdateChunks( double deltaTime ) { int chunksUpdatedThisFrame = 0; - int adjViewDistSqr = ( game.ViewDistance + 14 ) * ( game.ViewDistance + 14 ); + int viewDist = game.ViewDistance < 16 ? 16 : game.ViewDistance; + int adjViewDistSqr = (viewDist + 24) * (viewDist + 24); chunksTarget += deltaTime < targetTime ? 1 : -1; // build more chunks if 30 FPS or over, otherwise slowdown. Utils.Clamp( ref chunksTarget, 4, 12 ); diff --git a/ClassicalSharp/Rendering/StandardEnvRenderer.cs b/ClassicalSharp/Rendering/StandardEnvRenderer.cs index 6fcc563f5..0701f3351 100644 --- a/ClassicalSharp/Rendering/StandardEnvRenderer.cs +++ b/ClassicalSharp/Rendering/StandardEnvRenderer.cs @@ -219,10 +219,10 @@ namespace ClassicalSharp.Renderers { z2 = z1 + axisSize; if( z2 > endZ ) z2 = endZ; - vertices[i++] = new VertexPos3fTex2fCol4b( x1, y, z1, x1 / 2048f + offset, z1 / 2048f + offset, col ); - vertices[i++] = new VertexPos3fTex2fCol4b( x1, y, z2, x1 / 2048f + offset, z2 / 2048f + offset, col ); - vertices[i++] = new VertexPos3fTex2fCol4b( x2, y, z2, x2 / 2048f + offset, z2 / 2048f + offset, col ); - vertices[i++] = new VertexPos3fTex2fCol4b( x2, y, z1, x2 / 2048f + offset, z1 / 2048f + offset, col ); + vertices[i++] = new VertexPos3fTex2fCol4b( x1, y + 0.1f, z1, x1 / 2048f + offset, z1 / 2048f + offset, col ); + vertices[i++] = new VertexPos3fTex2fCol4b( x1, y + 0.1f, z2, x1 / 2048f + offset, z2 / 2048f + offset, col ); + vertices[i++] = new VertexPos3fTex2fCol4b( x2, y + 0.1f, z2, x2 / 2048f + offset, z2 / 2048f + offset, col ); + vertices[i++] = new VertexPos3fTex2fCol4b( x2, y + 0.1f, z1, x2 / 2048f + offset, z1 / 2048f + offset, col ); } } }