mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 02:56:09 -04:00
Redo setting inventory order to make more sense
This commit is contained in:
parent
f83eee14e4
commit
1cf621d9f6
@ -1,7 +1,6 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Gui.Widgets;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using System.Drawing;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace ClassicalSharp.Gui {
|
||||
@ -10,10 +9,7 @@ namespace ClassicalSharp.Gui {
|
||||
public abstract class GuiElement : IDisposable {
|
||||
|
||||
protected Game game;
|
||||
|
||||
public GuiElement(Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
public GuiElement(Game game) { this.game = game; }
|
||||
|
||||
public abstract void Init();
|
||||
|
||||
@ -49,4 +45,38 @@ namespace ClassicalSharp.Gui {
|
||||
return x >= recX && y >= recY && x < recX + width && y < recY + height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Represents a container of widgets and other 2D elements. </summary>
|
||||
/// <remarks> May cover the entire game window. </remarks>
|
||||
public abstract class Screen : GuiElement {
|
||||
|
||||
public Screen(Game game) : base(game) { }
|
||||
|
||||
public bool HandlesAllInput, BlocksWorld, HidesHud, RenderHudOver;
|
||||
|
||||
public abstract void OnResize(int width, int height);
|
||||
|
||||
protected abstract void ContextLost();
|
||||
|
||||
protected abstract void ContextRecreated();
|
||||
}
|
||||
|
||||
/// <summary> Represents an individual 2D gui component. </summary>
|
||||
public abstract class Widget : GuiElement {
|
||||
|
||||
public Widget(Game game) : base(game) { }
|
||||
|
||||
public ClickHandler MenuClick;
|
||||
public bool Active, Disabled;
|
||||
public int X, Y, Width, Height;
|
||||
public Anchor HorizontalAnchor, VerticalAnchor;
|
||||
public int XOffset, YOffset;
|
||||
|
||||
public Rectangle Bounds { get { return new Rectangle(X, Y, Width, Height); } }
|
||||
|
||||
public virtual void Reposition() {
|
||||
X = CalcPos(HorizontalAnchor, XOffset, Width, game.Width);
|
||||
Y = CalcPos(VerticalAnchor, YOffset, Height, game.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
protected ButtonWidget MakeBack(bool toGame, Font font, ClickHandler onClick) {
|
||||
int width = game.UseClassicOptions ? 400 : 200;
|
||||
return MakeBack(width, toGame ? "Back to game" : "Cancel", 25, font, onClick);
|
||||
@ -65,5 +65,30 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
protected static void SwitchOptions(Game g, Widget w) { g.Gui.SetNewScreen(new OptionsGroupScreen(g)); }
|
||||
protected static void SwitchPause(Game g, Widget w) { g.Gui.SetNewScreen(new PauseScreen(g)); }
|
||||
|
||||
|
||||
protected static void DisposeWidgets<T>(T[] widgets) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void RepositionWidgets<T>(T[] widgets) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Reposition();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void RenderWidgets<T>(T[] widgets, double delta) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Render(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
const int keyI = 0, modifyI = 1, actionI = 2;
|
||||
HotkeyList hotkeys;
|
||||
Hotkey curHotkey, origHotkey;
|
||||
Widget focusWidget;
|
||||
int selectedI = -1;
|
||||
static FastColour grey = new FastColour(150, 150, 150);
|
||||
|
||||
public EditHotkeyScreen(Game game, Hotkey original) : base(game) {
|
||||
@ -41,7 +41,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
if (key == Key.Escape) {
|
||||
game.Gui.SetNewScreen(null);
|
||||
return true;
|
||||
} else if (focusWidget != null) {
|
||||
} else if (selectedI >= 0) {
|
||||
FocusKeyDown(key);
|
||||
return true;
|
||||
}
|
||||
@ -84,7 +84,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
public override void Dispose() {
|
||||
game.Keyboard.KeyRepeat = false;
|
||||
focusWidget = null;
|
||||
selectedI = -1;
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
curHotkey.StaysOpen = !curHotkey.StaysOpen;
|
||||
string staysOpen = curHotkey.StaysOpen ? "ON" : "OFF";
|
||||
staysOpen = "Input stays open: " + staysOpen;
|
||||
SetButton(widgets[3], staysOpen);
|
||||
SetButton(3, staysOpen);
|
||||
}
|
||||
|
||||
void SaveChangesClick(Game game, Widget widget) {
|
||||
@ -126,50 +126,50 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
}
|
||||
|
||||
void BaseKeyClick(Game game, Widget widget) {
|
||||
focusWidget = widgets[keyI];
|
||||
SetButton(widgets[keyI], "Key: press a key..");
|
||||
selectedI = keyI;
|
||||
SetButton(keyI, "Key: press a key..");
|
||||
supressNextPress = true;
|
||||
}
|
||||
|
||||
void ModifiersClick(Game game, Widget widget) {
|
||||
focusWidget = widgets[modifyI];
|
||||
SetButton(widgets[modifyI], "Modifiers: press a key..");
|
||||
selectedI = modifyI;
|
||||
SetButton(modifyI, "Modifiers: press a key..");
|
||||
supressNextPress = true;
|
||||
}
|
||||
|
||||
void FocusKeyDown(Key key) {
|
||||
if (focusWidget == widgets[keyI]) {
|
||||
if (selectedI == keyI) {
|
||||
curHotkey.BaseKey = key;
|
||||
SetButton(widgets[keyI], "Key: " + curHotkey.BaseKey);
|
||||
SetButton(keyI, "Key: " + curHotkey.BaseKey);
|
||||
supressNextPress = true;
|
||||
} else if (focusWidget == widgets[modifyI]) {
|
||||
} else if (selectedI == modifyI) {
|
||||
if (key == Key.ControlLeft || key == Key.ControlRight) curHotkey.Flags |= 1;
|
||||
else if (key == Key.ShiftLeft || key == Key.ShiftRight) curHotkey.Flags |= 2;
|
||||
else if (key == Key.AltLeft || key == Key.AltRight) curHotkey.Flags |= 4;
|
||||
else curHotkey.Flags = 0;
|
||||
|
||||
string flags = HotkeyListScreen.MakeFlagsString(curHotkey.Flags);
|
||||
SetButton(widgets[modifyI], "Modifiers:" + flags);
|
||||
SetButton(modifyI, "Modifiers:" + flags);
|
||||
supressNextPress = true;
|
||||
}
|
||||
focusWidget = null;
|
||||
selectedI = -1;
|
||||
}
|
||||
|
||||
void LostFocus() {
|
||||
if (focusWidget == null) return;
|
||||
if (selectedI == -1) return;
|
||||
|
||||
if (focusWidget == widgets[keyI]) {
|
||||
SetButton(widgets[keyI], "Key: " + curHotkey.BaseKey);
|
||||
} else if (focusWidget == widgets[modifyI]) {
|
||||
if (selectedI == keyI) {
|
||||
SetButton(keyI, "Key: " + curHotkey.BaseKey);
|
||||
} else if (selectedI == modifyI) {
|
||||
string flags = HotkeyListScreen.MakeFlagsString(curHotkey.Flags);
|
||||
SetButton(widgets[modifyI], "Modifiers:" + flags);
|
||||
SetButton(modifyI, "Modifiers:" + flags);
|
||||
}
|
||||
focusWidget = null;
|
||||
selectedI = -1;
|
||||
supressNextPress = false;
|
||||
}
|
||||
|
||||
void SetButton(Widget widget, string text) {
|
||||
((ButtonWidget)widget).SetText(text);
|
||||
void SetButton(int i, string text) {
|
||||
((ButtonWidget)widgets[i]).SetText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
}
|
||||
|
||||
protected override void ContextLost() {
|
||||
input.Dispose();
|
||||
DisposeDescWidget();
|
||||
base.ContextLost();
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Gui.Widgets;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace ClassicalSharp.Gui.Screens {
|
||||
/// <summary> Represents a container of widgets and other 2D elements. </summary>
|
||||
/// <remarks> May cover the entire game window. </remarks>
|
||||
public abstract class Screen : GuiElement {
|
||||
|
||||
public Screen(Game game) : base(game) {
|
||||
}
|
||||
|
||||
/// <summary> Whether this screen handles all mouse and keyboard input. </summary>
|
||||
/// <remarks> This prevents the client from interacting with the world. </remarks>
|
||||
public bool HandlesAllInput;
|
||||
|
||||
/// <summary> Whether this screen completely and opaquely covers the game world behind it. </summary>
|
||||
public bool BlocksWorld;
|
||||
|
||||
/// <summary> Whether this screen hides the normal in-game hud. </summary>
|
||||
public bool HidesHud;
|
||||
|
||||
/// <summary> Whether the normal in-game hud should be drawn over the top of this screen. </summary>
|
||||
public bool RenderHudOver;
|
||||
|
||||
/// <summary> Called when the game window is resized. </summary>
|
||||
public abstract void OnResize(int width, int height);
|
||||
|
||||
protected abstract void ContextLost();
|
||||
|
||||
protected abstract void ContextRecreated();
|
||||
|
||||
protected static void DisposeWidgets<T>(T[] widgets) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void RepositionWidgets<T>(T[] widgets) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Reposition();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void RenderWidgets<T>(T[] widgets, double delta) where T : Widget {
|
||||
if (widgets == null) return;
|
||||
|
||||
for (int i = 0; i < widgets.Length; i++) {
|
||||
if (widgets[i] != null) widgets[i].Render(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -206,6 +206,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
|
||||
public void MakeDescTex(BlockID block) {
|
||||
game.Graphics.DeleteTexture(ref descTex);
|
||||
if (block == Block.Air) return;
|
||||
UpdateBlockInfoString(block);
|
||||
string value = buffer.ToString();
|
||||
|
||||
@ -218,8 +219,13 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
int totalElements = 0;
|
||||
BlockID[] map = game.Inventory.Map;
|
||||
|
||||
for (int i = 0; i < map.Length; i++) {
|
||||
for (int i = 0; i < map.Length;) {
|
||||
if ((i % ElementsPerRow) == 0 && RowEmpty(i)) {
|
||||
i += ElementsPerRow; continue;
|
||||
}
|
||||
|
||||
if (Show(map[i])) { totalElements++; }
|
||||
i++;
|
||||
}
|
||||
|
||||
totalRows = Utils.CeilDiv(totalElements, ElementsPerRow);
|
||||
@ -228,13 +234,28 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
|
||||
Elements = new BlockID[totalElements];
|
||||
int index = 0;
|
||||
for (int i = 0; i < map.Length; i++) {
|
||||
for (int i = 0; i < map.Length;) {
|
||||
if ((i % ElementsPerRow) == 0 && RowEmpty(i)) {
|
||||
i += ElementsPerRow; continue;
|
||||
}
|
||||
|
||||
if (Show(map[i])) { Elements[index++] = map[i]; }
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool RowEmpty(int i) {
|
||||
BlockID[] map = game.Inventory.Map;
|
||||
int max = Math.Min(i + ElementsPerRow, map.Length);
|
||||
|
||||
for (int j = i; j < max; j++) {
|
||||
if (map[j] != Block.Air) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Show(BlockID block) {
|
||||
if (block == Block.Air) return false;
|
||||
//if (block == Block.Air) return false;
|
||||
|
||||
if (block < Block.CpeCount) {
|
||||
int count = game.SupportsCPEBlocks ? Block.CpeCount : Block.OriginalCount;
|
||||
@ -271,7 +292,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
|
||||
if (scroll.HandlesMouseDown(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
} else if (SelectedIndex != -1) {
|
||||
} else if (SelectedIndex != -1 && Elements[SelectedIndex] != Block.Air) {
|
||||
game.Inventory.Selected = Elements[SelectedIndex];
|
||||
PendingClose = true;
|
||||
return true;
|
||||
@ -300,6 +321,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
|
||||
void ScrollRelative(int delta) {
|
||||
int startIndex = SelectedIndex;
|
||||
|
||||
SelectedIndex += delta;
|
||||
if (SelectedIndex < 0) SelectedIndex -= delta;
|
||||
if (SelectedIndex >= Elements.Length) SelectedIndex -= delta;
|
||||
|
@ -1,56 +0,0 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace ClassicalSharp.Gui.Widgets {
|
||||
/// <summary> Represents an individual 2D gui component. </summary>
|
||||
public abstract class Widget : GuiElement {
|
||||
|
||||
public Widget(Game game) : base(game) {
|
||||
HorizontalAnchor = Anchor.Min;
|
||||
VerticalAnchor = Anchor.Min;
|
||||
}
|
||||
|
||||
/// <summary> Whether this widget is currently being moused over. </summary>
|
||||
public bool Active;
|
||||
|
||||
/// <summary> Whether this widget is prevented from being interacted with. </summary>
|
||||
public bool Disabled;
|
||||
|
||||
/// <summary> Invoked when this widget is clicked on. Can be null. </summary>
|
||||
public ClickHandler MenuClick;
|
||||
|
||||
/// <summary> Horizontal coordinate of top left corner in pixels. </summary>
|
||||
public int X;
|
||||
|
||||
/// <summary> Vertical coordinate of top left corner in pixels. </summary>
|
||||
public int Y;
|
||||
|
||||
/// <summary> Horizontal length of widget's bounds in pixels. </summary>
|
||||
public int Width;
|
||||
|
||||
/// <summary> Vertical length of widget's bounds in pixels. </summary>
|
||||
public int Height;
|
||||
|
||||
/// <summary> Specifies the horizontal reference point for when the widget is resized. </summary>
|
||||
public Anchor HorizontalAnchor;
|
||||
|
||||
/// <summary> Specifies the vertical reference point for when the widget is resized. </summary>
|
||||
public Anchor VerticalAnchor;
|
||||
|
||||
/// <summary> Horizontal offset from the reference point in pixels. </summary>
|
||||
public int XOffset;
|
||||
|
||||
/// <summary> Vertical offset from the reference point in pixels. </summary>
|
||||
public int YOffset;
|
||||
|
||||
/// <summary> Specifies the boundaries of the widget in pixels. </summary>
|
||||
public Rectangle Bounds { get { return new Rectangle(X, Y, Width, Height); } }
|
||||
|
||||
public virtual void Reposition() {
|
||||
X = CalcPos(HorizontalAnchor, XOffset, Width, game.Width);
|
||||
Y = CalcPos(VerticalAnchor, YOffset, Height, game.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>
|
||||
@ -114,7 +114,6 @@
|
||||
<Compile Include="2D\Screens\Menu\SaveLevelScreen.cs" />
|
||||
<Compile Include="2D\Screens\Menu\TexturePackScreen.cs" />
|
||||
<Compile Include="2D\Screens\HudScreen.cs" />
|
||||
<Compile Include="2D\Screens\Screen.cs" />
|
||||
<Compile Include="2D\Texture.cs" />
|
||||
<Compile Include="2D\Utils\FastBitmap.cs" />
|
||||
<Compile Include="2D\Utils\FastColour.cs" />
|
||||
@ -132,7 +131,6 @@
|
||||
<Compile Include="2D\Widgets\SurvivalHotbarWidget.cs" />
|
||||
<Compile Include="2D\Widgets\TableWidget.cs" />
|
||||
<Compile Include="2D\Widgets\TextWidget.cs" />
|
||||
<Compile Include="2D\Widgets\Widget.cs" />
|
||||
<Compile Include="Audio\AudioPlayer.cs" />
|
||||
<Compile Include="Audio\AudioPlayer.Sounds.cs" />
|
||||
<Compile Include="Audio\Soundboard.cs" />
|
||||
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using ClassicalSharp.Events;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using ClassicalSharp.Gui;
|
||||
using ClassicalSharp.Gui.Screens;
|
||||
using ClassicalSharp.Renderers;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Entities;
|
||||
using ClassicalSharp.Gui;
|
||||
using ClassicalSharp.Gui.Screens;
|
||||
using ClassicalSharp.Hotkeys;
|
||||
using OpenTK;
|
||||
|
@ -92,78 +92,46 @@ namespace ClassicalSharp {
|
||||
|
||||
public BlockID[] Map;
|
||||
public void SetDefaultMapping() {
|
||||
for (int i = 0; i < Map.Length; i++) Map[i] = (BlockID)i;
|
||||
for (int i = 0; i < Map.Length; i++) {
|
||||
BlockID mapping = DefaultMapping(i);
|
||||
if (game.PureClassic && IsHackBlock(mapping)) mapping = Block.Air;
|
||||
if (mapping != i) Map[i] = mapping;
|
||||
Map[i] = DefaultMapping(i);
|
||||
}
|
||||
}
|
||||
|
||||
BlockID DefaultMapping(int i) {
|
||||
if (i >= Block.CpeCount || i == Block.Air) return Block.Air;
|
||||
if (!game.ClassicMode) return (BlockID)i;
|
||||
|
||||
if (i >= 25 && i <= 40) {
|
||||
return (BlockID)(Block.Red + (i - 25));
|
||||
}
|
||||
if (i >= 18 && i <= 21) {
|
||||
return (BlockID)(Block.Dandelion + (i - 18));
|
||||
}
|
||||
|
||||
switch (i) {
|
||||
// First row
|
||||
case 3: return Block.Cobblestone;
|
||||
case 4: return Block.Brick;
|
||||
case 5: return Block.Dirt;
|
||||
case 6: return Block.Wood;
|
||||
|
||||
// Second row
|
||||
case 12: return Block.Log;
|
||||
case 13: return Block.Leaves;
|
||||
case 14: return Block.Glass;
|
||||
case 15: return Block.Slab;
|
||||
case 16: return Block.MossyRocks;
|
||||
case 17: return Block.Sapling;
|
||||
|
||||
// Third row
|
||||
case 22: return Block.Sand;
|
||||
case 23: return Block.Gravel;
|
||||
case 24: return Block.Sponge;
|
||||
|
||||
// Fifth row
|
||||
case 41: return Block.CoalOre;
|
||||
case 42: return Block.IronOre;
|
||||
case 43: return Block.GoldOre;
|
||||
case 44: return Block.DoubleSlab;
|
||||
case 45: return Block.Iron;
|
||||
case 46: return Block.Gold;
|
||||
case 47: return Block.Bookshelf;
|
||||
case 48: return Block.TNT;
|
||||
}
|
||||
return (BlockID)i;
|
||||
}
|
||||
static BlockID[] classicTable = new BlockID[] {
|
||||
Block.Stone, Block.Cobblestone, Block.Brick, Block.Dirt, Block.Wood, Block.Log, Block.Leaves, Block.Glass, Block.Slab,
|
||||
Block.MossyRocks, Block.Sapling, Block.Dandelion, Block.Rose, Block.BrownMushroom, Block.RedMushroom, Block.Sand, Block.Gravel, Block.Sponge,
|
||||
Block.Red, Block.Orange, Block.Yellow, Block.Lime, Block.Green, Block.Teal, Block.Aqua, Block.Cyan, Block.Blue,
|
||||
Block.Indigo, Block.Violet, Block.Magenta, Block.Pink, Block.Black, Block.Gray, Block.White, Block.CoalOre, Block.IronOre,
|
||||
Block.GoldOre, Block.Iron, Block.Gold, Block.Bookshelf, Block.TNT, Block.Obsidian,
|
||||
};
|
||||
static BlockID[] classicHacksTable = new BlockID[] {
|
||||
Block.Stone, Block.Grass, Block.Cobblestone, Block.Brick, Block.Dirt, Block.Wood, Block.Bedrock, Block.Water, Block.StillWater, Block.Lava,
|
||||
Block.StillLava, Block.Log, Block.Leaves, Block.Glass, Block.Slab, Block.MossyRocks, Block.Sapling, Block.Dandelion, Block.Rose, Block.BrownMushroom,
|
||||
Block.RedMushroom, Block.Sand, Block.Gravel, Block.Sponge, Block.Red, Block.Orange, Block.Yellow, Block.Lime, Block.Green, Block.Teal,
|
||||
Block.Aqua, Block.Cyan, Block.Blue, Block.Indigo, Block.Violet, Block.Magenta, Block.Pink, Block.Black, Block.Gray, Block.White,
|
||||
Block.CoalOre, Block.IronOre, Block.GoldOre, Block.DoubleSlab, Block.Iron, Block.Gold, Block.Bookshelf, Block.TNT, Block.Obsidian,
|
||||
};
|
||||
|
||||
static bool IsHackBlock(BlockID b) {
|
||||
return b == Block.DoubleSlab || b == Block.Bedrock ||
|
||||
b == Block.Grass || BlockInfo.IsLiquid[b];
|
||||
BlockID DefaultMapping(int slot) {
|
||||
if (game.PureClassic) {
|
||||
if (slot < 9 * 4 + 6) return classicTable[slot];
|
||||
} else if (game.ClassicMode) {
|
||||
if (slot < 10 * 4 + 9) return classicHacksTable[slot];
|
||||
} else if (slot < Block.MaxCpeBlock) {
|
||||
return (BlockID)(slot + 1);
|
||||
}
|
||||
return Block.Air;
|
||||
}
|
||||
|
||||
public void AddDefault(BlockID block) {
|
||||
if (block >= Block.CpeCount || DefaultMapping(block) == block) {
|
||||
Map[block] = block;
|
||||
return;
|
||||
if (block >= Block.CpeCount) {
|
||||
Map[block - 1] = block; return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Block.CpeCount; i++) {
|
||||
if (DefaultMapping(i) != block) continue;
|
||||
Map[i] = block; return;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset(BlockID block) {
|
||||
for (int i = 0; i < Map.Length; i++) {
|
||||
if (Map[i] == block) Map[i] = DefaultMapping(i);
|
||||
for (int slot = 0; slot < Block.MaxCpeBlock; slot++) {
|
||||
if (DefaultMapping(slot) != block) continue;
|
||||
Map[slot] = block;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,29 +140,5 @@ namespace ClassicalSharp {
|
||||
if (Map[i] == block) Map[i] = Block.Air;
|
||||
}
|
||||
}
|
||||
|
||||
public void Insert(int i, BlockID block) {
|
||||
if (Map[i] == block) return;
|
||||
// Need to push the old block to a different slot if different block
|
||||
if (Map[i] != Block.Air) PushToFreeSlots(i);
|
||||
|
||||
Map[i] = block;
|
||||
}
|
||||
|
||||
void PushToFreeSlots(int i) {
|
||||
BlockID block = Map[i];
|
||||
// The slot was already pushed out in the past
|
||||
// TODO: find a better way of fixing this
|
||||
for (int j = 1; j < Map.Length; j++) {
|
||||
if (j != i && Map[j] == block) return;
|
||||
}
|
||||
|
||||
for (int j = block; j < Map.Length; j++) {
|
||||
if (Map[j] == Block.Air) { Map[j] = block; return; }
|
||||
}
|
||||
for (int j = 1; j < block; j++) {
|
||||
if (Map[j] == Block.Air) { Map[j] = block; return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Gui.Screens;
|
||||
using ClassicalSharp.Gui;
|
||||
using ClassicalSharp.Gui.Widgets;
|
||||
using OpenTK.Input;
|
||||
using BlockID = System.UInt16;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Gui.Widgets;
|
||||
using ClassicalSharp.Gui;
|
||||
using OpenTK.Input;
|
||||
using BlockID = System.UInt16;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using ClassicalSharp.Entities;
|
||||
using ClassicalSharp.Entities.Mobs;
|
||||
using ClassicalSharp.Gui;
|
||||
using ClassicalSharp.Gui.Screens;
|
||||
using ClassicalSharp.Gui.Widgets;
|
||||
using OpenTK;
|
||||
|
@ -43,7 +43,7 @@ namespace ClassicalSharp.Network.Protocols {
|
||||
OnBlockUpdated(block, didBlockLight);
|
||||
BlockInfo.UpdateCulling(block);
|
||||
|
||||
game.Inventory.Reset(block);
|
||||
game.Inventory.Remove(block);
|
||||
if (block < Block.CpeCount) {
|
||||
game.Inventory.AddDefault(block);
|
||||
}
|
||||
|
@ -406,8 +406,8 @@ namespace ClassicalSharp.Network.Protocols {
|
||||
BlockID order = reader.ReadBlock();
|
||||
|
||||
game.Inventory.Remove(block);
|
||||
if (order != 255) {
|
||||
game.Inventory.Insert(order, block);
|
||||
if (order != 255 && order != 0) {
|
||||
game.Inventory.Map[order - 1] = block;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Gui;
|
||||
using ClassicalSharp.Gui.Screens;
|
||||
using ClassicalSharp.Entities;
|
||||
using OpenTK;
|
||||
|
@ -99,6 +99,7 @@ namespace ClassicalSharp {
|
||||
|
||||
internal static void CleanupMainDirectory() {
|
||||
string mapPath = Path.Combine(Program.AppDirectory, "maps");
|
||||
Console.WriteLine(mapPath);
|
||||
if (!Directory.Exists(mapPath))
|
||||
Directory.CreateDirectory(mapPath);
|
||||
|
||||
|
@ -41,130 +41,59 @@ void Inventory_SetSelectedBlock(BlockID block) {
|
||||
Event_RaiseVoid(&UserEvents_HeldBlockChanged);
|
||||
}
|
||||
|
||||
bool Inventory_IsHackBlock(BlockID b) {
|
||||
return b == BLOCK_DOUBLE_SLAB || b == BLOCK_BEDROCK || b == BLOCK_GRASS || Block_IsLiquid[b];
|
||||
}
|
||||
BlockID inv_classicTable[] = {
|
||||
BLOCK_STONE, BLOCK_COBBLE, BLOCK_BRICK, BLOCK_DIRT, BLOCK_WOOD, BLOCK_LOG, BLOCK_LEAVES, BLOCK_GLASS, BLOCK_SLAB,
|
||||
BLOCK_MOSSY_ROCKS, BLOCK_SAPLING, BLOCK_DANDELION, BLOCK_ROSE, BLOCK_BROWN_SHROOM, BLOCK_RED_SHROOM, BLOCK_SAND, BLOCK_GRAVEL, BLOCK_SPONGE,
|
||||
BLOCK_RED, BLOCK_ORANGE, BLOCK_YELLOW, BLOCK_LIME, BLOCK_GREEN, BLOCK_TEAL, BLOCK_AQUA, BLOCK_CYAN, BLOCK_BLUE,
|
||||
BLOCK_INDIGO, BLOCK_VIOLET, BLOCK_MAGENTA, BLOCK_PINK, BLOCK_BLACK, BLOCK_GRAY, BLOCK_WHITE, BLOCK_COAL_ORE, BLOCK_IRON_ORE,
|
||||
BLOCK_GOLD_ORE, BLOCK_IRON, BLOCK_GOLD, BLOCK_BOOKSHELF, BLOCK_TNT, BLOCK_OBSIDIAN,
|
||||
};
|
||||
BlockID inv_classicHacksTable[] = {
|
||||
BLOCK_STONE, BLOCK_GRASS, BLOCK_COBBLE, BLOCK_BRICK, BLOCK_DIRT, BLOCK_WOOD, BLOCK_BEDROCK, BLOCK_WATER, BLOCK_STILL_WATER, BLOCK_LAVA,
|
||||
BLOCK_STILL_LAVA, BLOCK_LOG, BLOCK_LEAVES, BLOCK_GLASS, BLOCK_SLAB, BLOCK_MOSSY_ROCKS, BLOCK_SAPLING, BLOCK_DANDELION, BLOCK_ROSE, BLOCK_BROWN_SHROOM,
|
||||
BLOCK_RED_SHROOM, BLOCK_SAND, BLOCK_GRAVEL, BLOCK_SPONGE, BLOCK_RED, BLOCK_ORANGE, BLOCK_YELLOW, BLOCK_LIME, BLOCK_GREEN, BLOCK_TEAL,
|
||||
BLOCK_AQUA, BLOCK_CYAN, BLOCK_BLUE, BLOCK_INDIGO, BLOCK_VIOLET, BLOCK_MAGENTA, BLOCK_PINK, BLOCK_BLACK, BLOCK_GRAY, BLOCK_WHITE,
|
||||
BLOCK_COAL_ORE, BLOCK_IRON_ORE, BLOCK_GOLD_ORE, BLOCK_DOUBLE_SLAB, BLOCK_IRON, BLOCK_GOLD, BLOCK_BOOKSHELF, BLOCK_TNT, BLOCK_OBSIDIAN,
|
||||
};
|
||||
|
||||
BlockID Inventory_DefaultMapping(Int32 i) {
|
||||
#if USE16_BIT
|
||||
if ((i >= Block_CpeCount && i < 256) || i == BLOCK_AIR) return BLOCK_AIR;
|
||||
#else
|
||||
if (i >= BLOCK_CPE_COUNT || i == BLOCK_AIR) return BLOCK_AIR;
|
||||
#endif
|
||||
if (!Game_ClassicMode) return (BlockID)i;
|
||||
|
||||
if (i >= 25 && i <= 40) {
|
||||
return (BlockID)(BLOCK_RED + (i - 25));
|
||||
BlockID Inventory_DefaultMapping(int slot) {
|
||||
if (Game_PureClassic) {
|
||||
if (slot < 9 * 4 + 6) return inv_classicTable[slot];
|
||||
} else if (Game_ClassicMode) {
|
||||
if (slot < 10 * 4 + 9) return inv_classicHacksTable[slot];
|
||||
} else if (slot < BLOCK_MAX_CPE) {
|
||||
return (BlockID)(slot + 1);
|
||||
}
|
||||
if (i >= 18 && i <= 21) {
|
||||
return (BlockID)(BLOCK_DANDELION + (i - 18));
|
||||
}
|
||||
|
||||
switch (i) {
|
||||
/* First row */
|
||||
case 3: return BLOCK_COBBLE;
|
||||
case 4: return BLOCK_BRICK;
|
||||
case 5: return BLOCK_DIRT;
|
||||
case 6: return BLOCK_WOOD;
|
||||
|
||||
/* Second row */
|
||||
case 12: return BLOCK_LOG;
|
||||
case 13: return BLOCK_LEAVES;
|
||||
case 14: return BLOCK_GLASS;
|
||||
case 15: return BLOCK_SLAB;
|
||||
case 16: return BLOCK_MOSSY_ROCKS;
|
||||
case 17: return BLOCK_SAPLING;
|
||||
|
||||
/* Third row */
|
||||
case 22: return BLOCK_SAND;
|
||||
case 23: return BLOCK_GRAVEL;
|
||||
case 24: return BLOCK_SPONGE;
|
||||
|
||||
/* Fifth row */
|
||||
case 41: return BLOCK_COAL_ORE;
|
||||
case 42: return BLOCK_IRON_ORE;
|
||||
case 43: return BLOCK_GOLD_ORE;
|
||||
case 44: return BLOCK_DOUBLE_SLAB;
|
||||
case 45: return BLOCK_IRON;
|
||||
case 46: return BLOCK_GOLD;
|
||||
case 47: return BLOCK_BOOKSHELF;
|
||||
case 48: return BLOCK_TNT;
|
||||
}
|
||||
return (BlockID)i;
|
||||
return BLOCK_AIR;
|
||||
}
|
||||
|
||||
void Inventory_SetDefaultMapping(void) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_Elems(Inventory_Map); i++) {
|
||||
Inventory_Map[i] = (BlockID)i;
|
||||
}
|
||||
for (i = 0; i < Array_Elems(Inventory_Map); i++) {
|
||||
BlockID mapping = Inventory_DefaultMapping(i);
|
||||
if (Game_PureClassic && Inventory_IsHackBlock(mapping)) {
|
||||
mapping = BLOCK_AIR;
|
||||
}
|
||||
if (mapping != i) Inventory_Map[i] = mapping;
|
||||
Int32 slot;
|
||||
for (slot = 0; slot < Array_Elems(Inventory_Map); slot++) {
|
||||
Inventory_Map[slot] = Inventory_DefaultMapping(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory_AddDefault(BlockID block) {
|
||||
if (block >= BLOCK_CPE_COUNT || Inventory_DefaultMapping(block) == block) {
|
||||
Inventory_Map[block] = block;
|
||||
return;
|
||||
if (block >= BLOCK_CPE_COUNT) {
|
||||
Inventory_Map[block - 1] = block; return;
|
||||
}
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < BLOCK_CPE_COUNT; i++) {
|
||||
if (Inventory_DefaultMapping(i) != block) continue;
|
||||
Inventory_Map[i] = block;
|
||||
Int32 slot;
|
||||
for (slot = 0; slot < BLOCK_MAX_CPE; slot++) {
|
||||
if (Inventory_DefaultMapping(slot) != block) continue;
|
||||
Inventory_Map[slot] = block;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory_Reset(BlockID block) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_Elems(Inventory_Map); i++) {
|
||||
if (Inventory_Map[i] != block) continue;
|
||||
Inventory_Map[i] = Inventory_DefaultMapping(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory_Remove(BlockID block) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_Elems(Inventory_Map); i++) {
|
||||
if (Inventory_Map[i] != block) continue;
|
||||
Inventory_Map[i] = BLOCK_AIR;
|
||||
Int32 slot;
|
||||
for (slot = 0; slot < Array_Elems(Inventory_Map); slot++) {
|
||||
if (Inventory_Map[slot] == block) Inventory_Map[slot] = BLOCK_AIR;
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory_PushToFreeSlots(Int32 i) {
|
||||
BlockID block = Inventory_Map[i];
|
||||
Int32 j;
|
||||
/* The slot was already pushed out in the past
|
||||
TODO: find a better way of fixing this */
|
||||
for (j = 1; j < Array_Elems(Inventory_Map); j++) {
|
||||
if (j != i && Inventory_Map[j] == block) return;
|
||||
}
|
||||
|
||||
for (j = block; j < Array_Elems(Inventory_Map); j++) {
|
||||
if (Inventory_Map[j] == BLOCK_AIR) {
|
||||
Inventory_Map[j] = block; return;
|
||||
}
|
||||
}
|
||||
for (j = 1; j < block; j++) {
|
||||
if (Inventory_Map[j] == BLOCK_AIR) {
|
||||
Inventory_Map[j] = block; return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory_Insert(Int32 i, BlockID block) {
|
||||
if (Inventory_Map[i] == block) return;
|
||||
/* Need to push the old block to a different slot if different block. */
|
||||
if (Inventory_Map[i] != BLOCK_AIR) Inventory_PushToFreeSlots(i);
|
||||
Inventory_Map[i] = block;
|
||||
}
|
||||
|
||||
void Inventory_ResetState(void) {
|
||||
Inventory_SetDefaultMapping();
|
||||
Inventory_CanChangeHeldBlock = true;
|
||||
|
@ -81,10 +81,10 @@ void Menu_MakeDefaultBack(ButtonWidget* widget, bool toGame, FontDesc* font, Wid
|
||||
Int32 width = Game_UseClassicOptions ? 400 : 200;
|
||||
if (toGame) {
|
||||
String msg = String_FromConst("Back to game");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
Menu_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
} else {
|
||||
String msg = String_FromConst("Cancel");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
Menu_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ void ListScreen_ContextRecreated(void* obj) {
|
||||
ListScreen_Make(screen, 5, -220, 0, &lArrow, ListScreen_MoveBackwards);
|
||||
String rArrow = String_FromConst(">");
|
||||
ListScreen_Make(screen, 6, 220, 0, &rArrow, ListScreen_MoveForwards);
|
||||
Screen_MakeDefaultBack(&screen->Buttons[7], false, &screen->Font, Menu_SwitchPause);
|
||||
Menu_MakeDefaultBack(&screen->Buttons[7], false, &screen->Font, Menu_SwitchPause);
|
||||
|
||||
screen->Widgets[0] = (Widget*)(&screen->Title);
|
||||
for (i = 0; i < FILES_SCREEN_BUTTONS; i++) {
|
||||
@ -495,7 +495,7 @@ bool PauseScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
|
||||
Screen* PauseScreen_MakeInstance(void) {
|
||||
PauseScreen* screen = &PauseScreen_Instance;
|
||||
MenuScreen_MakeInstance(&screen->Base, screen->Widgets, Array_Elems(screen->Buttons), PauseScreen_ContextRecreated);
|
||||
MenuScreen_MakeInstance(&screen->Base, screen->Widgets, Array_Elems(screen->Widgets), PauseScreen_ContextRecreated);
|
||||
PauseScreen_VTABLE = *screen->Base.VTABLE;
|
||||
screen->Base.VTABLE = &PauseScreen_VTABLE;
|
||||
|
||||
@ -504,3 +504,108 @@ Screen* PauseScreen_MakeInstance(void) {
|
||||
screen->Base.VTABLE->HandlesKeyDown = PauseScreen_HandlesKeyDown;
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
typedef struct OptionsGroupScreen_ {
|
||||
MenuScreen Base;
|
||||
Widget* Widgets[9];
|
||||
ButtonWidget Buttons[8];
|
||||
TextWidget Desc;
|
||||
Int32 SelectedI;
|
||||
} OptionsGroupScreen;
|
||||
|
||||
GuiElementVTABLE OptionsGroupScreen_VTABLE;
|
||||
OptionsGroupScreen OptionsGroupScreen_Instance;
|
||||
Screen* OptionsGroupScreen_MakeInstance(void) {
|
||||
OptionsGroupScreen* screen = &OptionsGroupScreen_Instance;
|
||||
MenuScreen_MakeInstance(&screen->Base, screen->Widgets, Array_Elems(screen->Widgets), OptionsGroupScreen_ContextRecreated);
|
||||
OptionsGroupScreen_VTABLE = *screen->Base.VTABLE;
|
||||
screen->Base.VTABLE = &OptionsGroupScreen_VTABLE;
|
||||
|
||||
screen->Base.VTABLE->Init = OptionsGroupScreen_Init;
|
||||
screen->Base.VTABLE->Free = OptionsGroupScreen_Free;
|
||||
screen->Base.VTABLE->HandlesMouseMove = OptionsGroupScreen_HandlesMouseMove;
|
||||
/* Pause screen key down behaviour is same for options group screen*/
|
||||
screen->Base.VTABLE->HandlesKeyDown = PauseScreen_HandlesKeyDown;
|
||||
|
||||
screen->SelectedI = -1;
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
void OptionsGroupScreen_Init(GuiElement* elem) {
|
||||
MenuScreen_Init(elem);
|
||||
game.Events.HackPermissionsChanged += CheckHacksAllowed;
|
||||
titleFont = new Font(game.FontName, 16, FontStyle.Bold);
|
||||
regularFont = new Font(game.FontName, 16);
|
||||
ContextRecreated();
|
||||
}
|
||||
|
||||
void OptionsGroupScreen_ContextRecreated(void* obj) {
|
||||
OptionsGroupScreen* screen = (OptionsGroupScreen*)obj;
|
||||
widgets = new Widget[]{
|
||||
Make(-1, -100, "Misc options...", SwitchMiscOptions),
|
||||
Make(-1, -50, "Gui options...", SwitchGuiOptions),
|
||||
Make(-1, 0, "Graphics options...", SwitchGfxOptions),
|
||||
Make(-1, 50, "Controls...", SwitchControls),
|
||||
Make(1, -50, "Hacks settings...", SwitchHacksOptions),
|
||||
Make(1, 0, "Env settings...", SwitchEnvOptions),
|
||||
Make(1, 50, "Nostalgia options...", SwitchNostalgiaOptions),
|
||||
MakeBack(false, titleFont, SwitchPause),
|
||||
null, // description text widget placeholder
|
||||
};
|
||||
|
||||
if (screen->SelectedI >= 0) {
|
||||
MakeDescWidget(descriptions[selectedI]);
|
||||
}
|
||||
CheckHacksAllowed(null, null);
|
||||
}
|
||||
|
||||
static void SwitchMiscOptions(Game g, Widget w) { g.Gui.SetNewScreen(new MiscOptionsScreen(g)); }
|
||||
static void SwitchGuiOptions(Game g, Widget w) { g.Gui.SetNewScreen(new GuiOptionsScreen(g)); }
|
||||
static void SwitchGfxOptions(Game g, Widget w) { g.Gui.SetNewScreen(new GraphicsOptionsScreen(g)); }
|
||||
static void SwitchControls(Game g, Widget w) { g.Gui.SetNewScreen(new NormalKeyBindingsScreen(g)); }
|
||||
static void SwitchHacksOptions(Game g, Widget w) { g.Gui.SetNewScreen(new HacksSettingsScreen(g)); }
|
||||
static void SwitchEnvOptions(Game g, Widget w) { g.Gui.SetNewScreen(new EnvSettingsScreen(g)); }
|
||||
static void SwitchNostalgiaOptions(Game g, Widget w) { g.Gui.SetNewScreen(new NostalgiaScreen(g)); }
|
||||
|
||||
void CheckHacksAllowed(object sender, EventArgs e) {
|
||||
widgets[5].Disabled = !game.LocalPlayer.Hacks.CanAnyHacks; // env settings
|
||||
}
|
||||
|
||||
void MakeDescWidget(string text) {
|
||||
widgets[widgets.Length - 1] = TextWidget.Create(game, text, regularFont)
|
||||
.SetLocation(Anchor.Centre, Anchor.Centre, 0, 100);
|
||||
}
|
||||
|
||||
ButtonWidget Make(int dir, int y, string text, ClickHandler onClick) {
|
||||
return ButtonWidget.Create(game, 300, text, titleFont, onClick)
|
||||
.SetLocation(Anchor.Centre, Anchor.Centre, dir * 160, y);
|
||||
}
|
||||
|
||||
bool OptionsGroupScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
int i = HandleMouseMove(widgets, mouseX, mouseY);
|
||||
if (i == -1 || i == selectedI) return true;
|
||||
if (i >= Array_Elems(OptionsGroupScreen_descs)) return true;
|
||||
|
||||
selectedI = i;
|
||||
Widget desc = widgets[widgets.Length - 1];
|
||||
if (desc != null) desc.Dispose();
|
||||
MakeDescWidget(descriptions[i]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OptionsGroupScreen_Free(GuiElement* elem) {
|
||||
MenuScreen_Free(elem);
|
||||
game.Events.HackPermissionsChanged -= CheckHacksAllowed;
|
||||
}
|
||||
|
||||
const UInt8* OptionsGroupScreen_descs[7] = {
|
||||
"&eMusic/Sound, view bobbing, and more",
|
||||
"&eChat options, gui scale, font settings, and more",
|
||||
"&eFPS limit, view distance, entity names/shadows",
|
||||
"&eSet key bindings, bind keys to act as mouse clicks",
|
||||
"&eHacks allowed, jump settings, and more",
|
||||
"&eEnv colours, water level, weather, and more",
|
||||
"&eSettings for resembling the original classic",
|
||||
};
|
@ -576,6 +576,7 @@ void TableWidget_RecreateDescTex(TableWidget* widget) {
|
||||
|
||||
void TableWidget_MakeDescTex(TableWidget* widget, BlockID block) {
|
||||
Gfx_DeleteTexture(&widget->DescTex.ID);
|
||||
if (block == BLOCK_AIR) return;
|
||||
|
||||
UInt8 descBuffer[String_BufferSize(STRING_SIZE * 2)];
|
||||
String desc = String_InitAndClearArray(descBuffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user