diff --git a/2D/Screens/BlockSelectScreen.cs b/2D/Screens/BlockSelectScreen.cs index 1781f166a..86eec357d 100644 --- a/2D/Screens/BlockSelectScreen.cs +++ b/2D/Screens/BlockSelectScreen.cs @@ -247,7 +247,7 @@ namespace ClassicalSharp { } public override bool HandlesKeyDown( Key key ) { - if( key == Key.Escape || key == Key.Q ) { + if( key == Window.Keys[KeyMapping.PauseOrExit] ) { Window.SetNewScreen( new NormalScreen( Window ) ); } else if( key == Key.Left ) { MovePointerLeft(); diff --git a/2D/Screens/ChatScreen.cs b/2D/Screens/ChatScreen.cs index dd4dec997..ea3e1caa1 100644 --- a/2D/Screens/ChatScreen.cs +++ b/2D/Screens/ChatScreen.cs @@ -178,7 +178,7 @@ namespace ClassicalSharp { suppressNextPress = false; if( HandlesAllInput ) { // text input bar - if( key == Key.Enter ) { + if( key == Window.Keys[KeyMapping.SendChat] ) { HandlesAllInput = false; Window.Camera.RegrabMouse(); textInput.SendTextInBufferAndReset(); @@ -188,11 +188,11 @@ namespace ClassicalSharp { return true; } - if( key == Key.T ) { + if( key == Window.Keys[KeyMapping.OpenChat] ) { OpenTextInputBar( "" ); } else if( key == Key.Slash ) { OpenTextInputBar( "/" ); - } else if( key == Key.H ) { + } else if( key == Window.Keys[KeyMapping.ChatHistoryMode] ) { HistoryMode = !HistoryMode; normalChat.Dispose(); InitChat(); diff --git a/2D/Screens/NormalScreen.cs b/2D/Screens/NormalScreen.cs index 7c44efc60..6f1e1dd42 100644 --- a/2D/Screens/NormalScreen.cs +++ b/2D/Screens/NormalScreen.cs @@ -18,7 +18,7 @@ namespace ClassicalSharp { if( playerList != null ) { playerList.Render( delta ); // NOTE: Should usually be caught by KeyUp, but just in case. - if( !Window.IsKeyDown( Key.Tab ) ) { + if( !Window.IsKeyDown( KeyMapping.PlayerList ) ) { playerList.Dispose(); playerList = null; } @@ -61,7 +61,7 @@ namespace ClassicalSharp { } public override bool HandlesKeyDown( Key key ) { - if( key == Key.Tab ) { + if( key == Window.Keys[KeyMapping.PlayerList] ) { if( playerList == null ) { if( Window.Network.UsingExtPlayerList ) { playerList = new ExtPlayerListWidget( Window ); @@ -78,7 +78,7 @@ namespace ClassicalSharp { } public override bool HandlesKeyUp( Key key ) { - if( key == Key.Tab ) { + if( key == Window.Keys[KeyMapping.PlayerList] ) { if( playerList != null ) { playerList.Dispose(); playerList = null; diff --git a/2D/Screens/PauseScreen.cs b/2D/Screens/PauseScreen.cs index 30ad54840..9c53be4ae 100644 --- a/2D/Screens/PauseScreen.cs +++ b/2D/Screens/PauseScreen.cs @@ -29,18 +29,28 @@ namespace ClassicalSharp { controlsWidget = CreateTextWidget( 0, 30, "&eControls list", Docking.LeftOrTop, 16, FontStyle.Bold ); gameWidget = CreateTextWidget( 0, -60, "&eBack to game", Docking.BottomOrRight, 16, FontStyle.Bold ); exitWidget = CreateTextWidget( 0, -10, "&eExit", Docking.BottomOrRight, 16, FontStyle.Bold ); - MakeKeysLeft( "Forward: W", "Back: S", "Left: A", "Right: D", "Jump: Space", "Respawn: R", "Set spawn: Y", - "Open chat: T", "Send chat: Enter", "Pause: Escape", "Open inventory: B" ); - MakeKeysRight( "Take screenshot: F12", "Toggle fullscreen: F11", "Toggle 3rd person camera: F5", - "Toggle VSync: F7", "Change view distance: F6", "Toggle fly: Z", "Speed: Shift", - "Toggle noclip: X", "Fly up: Q", "Fly down: E", "Display player list: Tab" ); + + KeyMapping[] mappingsLeft = { KeyMapping.Forward, KeyMapping.Back, KeyMapping.Left, KeyMapping.Right, + KeyMapping.Jump, KeyMapping.Respawn, KeyMapping.SetSpawn, KeyMapping.OpenChat, KeyMapping.SendChat, + KeyMapping.PauseOrExit, KeyMapping.OpenInventory }; + string[] descriptionsLeft = { "Forward", "Back", "Left", "Right", "Jump", "Respawn", "Set spawn", + "Open chat", "Send chat", "Pause", "Open inventory" }; + MakeKeysLeft( mappingsLeft, descriptionsLeft ); + + KeyMapping[] mappingsRight = { KeyMapping.Screenshot, KeyMapping.Fullscreen, KeyMapping.ThirdPersonCamera, + KeyMapping.VSync, KeyMapping.ViewDistance, KeyMapping.Fly, KeyMapping.Speed, KeyMapping.NoClip, + KeyMapping.FlyUp, KeyMapping.FlyDown, KeyMapping.PlayerList }; + string[] descriptionsRight = { "Take screenshot", "Toggle fullscreen", "Toggle 3rd person camera", "Toggle VSync", + "Change view distance", "Toggle fly", "Speed", "Toggle noclip", "Fly up", "Fly down", "Display player list" }; + MakeKeysRight( mappingsRight, descriptionsRight ); } - void MakeKeysLeft( params string[] keyBindings ) { + void MakeKeysLeft( KeyMapping[] mappings, string[] descriptions ) { int startY = controlsWidget.BottomRight.Y + 10; - keysLeft = new TextWidget[keyBindings.Length]; + keysLeft = new TextWidget[mappings.Length]; for( int i = 0; i < keysLeft.Length; i++ ) { - TextWidget widget = CreateTextWidget( 0, startY, keyBindings[i], Docking.LeftOrTop, 14, FontStyle.Bold ); + string text = descriptions[i] + ": " + Window.Keys[mappings[i]]; + TextWidget widget = CreateTextWidget( 0, startY, text, Docking.LeftOrTop, 14, FontStyle.Bold ); widget.XOffset = -widget.Width / 2 - 20; widget.MoveTo( widget.X + widget.XOffset, widget.Y ); keysLeft[i] = widget; @@ -48,11 +58,12 @@ namespace ClassicalSharp { } } - void MakeKeysRight( params string[] keyBindings ) { + void MakeKeysRight( KeyMapping[] mappings, string[] descriptions ) { int startY = controlsWidget.BottomRight.Y + 10; - keysRight = new TextWidget[keyBindings.Length]; + keysRight = new TextWidget[mappings.Length]; for( int i = 0; i < keysRight.Length; i++ ) { - TextWidget widget = CreateTextWidget( 0, startY, keyBindings[i], Docking.LeftOrTop, 14, FontStyle.Bold ); + string text = descriptions[i] + ": " + Window.Keys[mappings[i]]; + TextWidget widget = CreateTextWidget( 0, startY, text, Docking.LeftOrTop, 14, FontStyle.Bold ); widget.XOffset = widget.Width / 2 + 20; widget.MoveTo( widget.X + widget.XOffset, widget.Y ); keysRight[i] = widget; diff --git a/Entities/LocalPlayer.cs b/Entities/LocalPlayer.cs index b261657d5..fe6df83e7 100644 --- a/Entities/LocalPlayer.cs +++ b/Entities/LocalPlayer.cs @@ -121,16 +121,15 @@ namespace ClassicalSharp { if( Window.ScreenLockedInput ) { jumping = speeding = flyingUp = flyingDown = false; } else { - if( Window.IsKeyDown( Key.W ) ) xMoving -= 0.98f; - if( Window.IsKeyDown( Key.S ) ) xMoving += 0.98f; - if( Window.IsKeyDown( Key.A ) ) zMoving -= 0.98f; - if( Window.IsKeyDown( Key.D ) ) zMoving += 0.98f; + if( Window.IsKeyDown( KeyMapping.Forward ) ) xMoving -= 0.98f; + if( Window.IsKeyDown( KeyMapping.Back ) ) xMoving += 0.98f; + if( Window.IsKeyDown( KeyMapping.Left ) ) zMoving -= 0.98f; + if( Window.IsKeyDown( KeyMapping.Right ) ) zMoving += 0.98f; - jumping = Window.IsKeyDown( Key.Space ); - bool shiftDown = Window.IsKeyDown( Key.ShiftLeft ) || Window.IsKeyDown( Key.ShiftRight ); - speeding = CanSpeed && shiftDown; - flyingUp = Window.IsKeyDown( Key.Q ); - flyingDown = Window.IsKeyDown( Key.E ); + jumping = Window.IsKeyDown( KeyMapping.Jump ); + speeding = CanSpeed && Window.IsKeyDown( KeyMapping.Speed ); + flyingUp = Window.IsKeyDown( KeyMapping.FlyUp ); + flyingDown = Window.IsKeyDown( KeyMapping.FlyDown ); } } @@ -347,14 +346,14 @@ namespace ClassicalSharp { } public bool HandleKeyDown( Key key ) { - if( key == Key.R && canRespawn ) { + if( key == Window.Keys[KeyMapping.Respawn] && canRespawn ) { LocationUpdate update = LocationUpdate.MakePos( SpawnPoint, false ); SetLocation( update, false ); - } else if( key == Key.Y && canRespawn ) { + } else if( key == Window.Keys[KeyMapping.SetSpawn] && canRespawn ) { SpawnPoint = Position; - } else if( key == Key.Z && canFly ) { + } else if( key == Window.Keys[KeyMapping.Fly] && canFly ) { flying = !flying; - } else if( key == Key.X && canNoclip ) { + } else if( key == Window.Keys[KeyMapping.NoClip] && canNoclip ) { noClip = !noClip; } else { return false; diff --git a/Game/Game.InputHandling.cs b/Game/Game.InputHandling.cs index c5040485e..cb958aa67 100644 --- a/Game/Game.InputHandling.cs +++ b/Game/Game.InputHandling.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using ClassicalSharp.Particles; using OpenTK; using OpenTK.Input; @@ -11,6 +12,11 @@ namespace ClassicalSharp { return Keyboard[key]; } + public bool IsKeyDown( KeyMapping mapping ) { + Key key = Keys[mapping]; + return Keyboard[key]; + } + public bool IsMousePressed( MouseButton button ) { return Mouse[button]; } @@ -69,21 +75,20 @@ namespace ClassicalSharp { static int[] viewDistances = { 16, 32, 64, 128, 256, 512 }; void KeyDownHandler( object sender, KeyboardKeyEventArgs e ) { Key key = e.Key; - if( key == Key.F12 ) { + if( key == Keys[KeyMapping.Screenshot] ) { screenshotRequested = true; - } else if( key == Key.F11 ) { + } else if( key == Keys[KeyMapping.Fullscreen] ) { WindowState state = WindowState; - if( state == WindowState.Fullscreen ) { - WindowState = WindowState.Normal; - } else if( state == WindowState.Normal || state == WindowState.Maximized ) { - WindowState = WindowState.Fullscreen; + if( state != WindowState.Minimized ) { + WindowState = state == WindowState.Fullscreen ? + WindowState.Normal : WindowState.Fullscreen; } - } else if( key == Key.F5 ) { + } else if( key == Keys[KeyMapping.ThirdPersonCamera] ) { bool useThirdPerson = Camera is FirstPersonCamera; SetCamera( useThirdPerson ); - } else if( key == Key.F7 ) { + } else if( key == Keys[KeyMapping.VSync] ) { VSync = VSync == VSyncMode.Off ? VSyncMode.On : VSyncMode.Off; - } else if( key == Key.F6 ) { + } else if( key == Keys[KeyMapping.ViewDistance] ) { if( ViewDistance >= viewDistances[viewDistances.Length - 1] ) { SetViewDistance( viewDistances[0] ); } else { @@ -95,12 +100,12 @@ namespace ClassicalSharp { } } } - } else if( key == Key.Escape && !Map.IsNotLoaded ) { + } else if( key == Keys[KeyMapping.PauseOrExit] && !Map.IsNotLoaded ) { if( !( activeScreen is PauseScreen ) ) { SetNewScreen( new PauseScreen( this ) ); } } else if( activeScreen == null || !activeScreen.HandlesKeyDown( key ) ) { - if( key == Key.B ) { + if( key == Keys[KeyMapping.OpenInventory] ) { SetNewScreen( new BlockSelectScreen( this ) ); } else { LocalPlayer.HandleKeyDown( key ); @@ -142,5 +147,71 @@ namespace ClassicalSharp { bool CanReplace( byte block ) { return block == 0 || ( !CanPlace[block] && !CanDelete[block] && BlockInfo.IsLiquid( block ) ); } + + public KeyMap Keys = new KeyMap(); } + + public class KeyMap { + + public Key this[KeyMapping key] { + get { return Keys[(int)key]; } + set { Keys[(int)key] = value; } + } + + [Obsolete( "It's better to use the KeyMapping indexer")] + public Key this[string key] { + get { + KeyMapping mapping = (KeyMapping)KeyMapping.Parse( typeof( KeyMapping ), key, true ); + return Keys[(int)mapping]; + } + set { + KeyMapping mapping = (KeyMapping)KeyMapping.Parse( typeof( KeyMapping ), key, true ); + Keys[(int)mapping] = value; + } + } + + Key[] Keys = new Key[] { + Key.W, Key.S, Key.A, Key.D, Key.Space, Key.R, Key.Y, Key.T, + Key.Enter, Key.Escape, Key.B, Key.F12, Key.F11, Key.F7, + Key.F5, Key.F6, Key.Z, Key.LShift, Key.X, Key.Q, Key.E, + Key.Tab, Key.H, + }; + + bool IsLockedKey( Key key ) { + return key == Key.Escape || ( key >= Key.F1 && key <= Key.F35 ); + } + + bool IsReservedKey( Key key ) { + return key == Key.Slash || key == Key.BackSpace || + ( key >= Key.Insert && key <= Key.End ) || + ( key >= Key.Up && key <= Key.Right ) || // chat screen movement + ( key >= Key.Number0 && key <= Key.Number9 ); // block hotbar + } + + public bool IsKeyOkay( Key key, out string reason ) { + if( IsLockedKey( key ) ) { + reason = "Given key mapping cannot be changed."; + return false; + } + if( IsReservedKey( key ) ) { + reason = "Given key is reserved for gui."; + return false; + } + for( int i = 0; i < Keys.Length; i++ ) { + if( Keys[i] == key ) { + reason = "Key is already assigned."; + return false; + } + } + reason = null; + return true; + } + } + + public enum KeyMapping { + Forward, Back, Left, Right, Jump, Respawn, SetSpawn, OpenChat, + SendChat, PauseOrExit, OpenInventory, Screenshot, Fullscreen, VSync, + ThirdPersonCamera, ViewDistance, Fly, Speed, NoClip, FlyUp, FlyDown, + PlayerList, ChatHistoryMode, + } } \ No newline at end of file diff --git a/MeshBuilders/ChunkMeshBuilderTex2Col4.cs b/MeshBuilders/ChunkMeshBuilderTex2Col4.cs index f761815a8..a7cf9b652 100644 --- a/MeshBuilders/ChunkMeshBuilderTex2Col4.cs +++ b/MeshBuilders/ChunkMeshBuilderTex2Col4.cs @@ -140,7 +140,7 @@ namespace ClassicalSharp { for( int i = 0; i < drawInfoBuffer.Length; i++ ) { DrawInfo1D info = drawInfoBuffer[i]; if( info.totalVertices > info.vertices.Length ) { - Array.Resize( ref info.vertices, info.totalVertices ); + info.vertices = new VertexPos3fTex2fCol4b[info.totalVertices]; } } }