Initial work on inventory that supports multiple hotbars.

This commit is contained in:
UnknownShadow200 2017-03-01 15:54:52 +11:00
parent 35fd58f893
commit dd0b497136
15 changed files with 87 additions and 74 deletions

View File

@ -43,7 +43,7 @@ namespace ClassicalSharp.Gui.Screens {
ScrollbarClick(mouseY);
} else if (button == MouseButton.Left) {
if (selIndex != -1) {
game.Inventory.HeldBlock = blocksTable[selIndex];
game.Inventory.Selected = blocksTable[selIndex];
} else if (Contains(TableX, TableY, TableWidth, TableHeight, mouseX, mouseY)) {
return true;
}
@ -60,7 +60,7 @@ namespace ClassicalSharp.Gui.Screens {
key == game.Mapping(KeyBind.Inventory)) {
game.Gui.SetNewScreen(null);
} else if (key == Key.Enter && selIndex != -1) {
game.Inventory.HeldBlock = blocksTable[selIndex];
game.Inventory.Selected = blocksTable[selIndex];
game.Gui.SetNewScreen(null);
} else if ((key == Key.Left || key == Key.Keypad4) && selIndex != -1) {
ArrowKeyMove(-1);
@ -71,7 +71,7 @@ namespace ClassicalSharp.Gui.Screens {
} else if ((key == Key.Down || key == Key.Keypad2) && selIndex != -1) {
ArrowKeyMove(blocksPerRow);
} else if (key >= Key.Number1 && key <= Key.Number9) {
game.Inventory.HeldBlockIndex = (int)key - (int)Key.Number1;
game.Inventory.SelectedIndex = (int)key - (int)Key.Number1;
}
return true;
}

View File

@ -136,7 +136,7 @@ namespace ClassicalSharp.Gui.Screens {
game.Graphics.ContextRecreated += ContextRecreated;
RecreateBlockTable();
SetBlockTo(game.Inventory.HeldBlock);
SetBlockTo(game.Inventory.Selected);
game.Keyboard.KeyRepeat = true;
}

View File

@ -17,10 +17,8 @@ namespace ClassicalSharp.Gui.Widgets {
public HotbarWidget(Game game) : base(game) {
HorizontalAnchor = Anchor.Centre;
VerticalAnchor = Anchor.BottomOrRight;
hotbarCount = game.Inventory.Hotbar.Length;
}
protected int hotbarCount;
Texture selTex, backTex;
protected float barHeight, selBlockSize, elemSize;
protected float barXOffset, borderSize;
@ -61,7 +59,7 @@ namespace ClassicalSharp.Gui.Widgets {
backTex.ID = texId;
backTex.Render(gfx);
int i = game.Inventory.HeldBlockIndex;
int i = game.Inventory.SelectedIndex;
int x = (int)(X + barXOffset + (elemSize + borderSize) * i + elemSize / 2);
selTex.ID = texId;
@ -73,8 +71,8 @@ namespace ClassicalSharp.Gui.Widgets {
Model.ModelCache cache = game.ModelCache;
drawer.BeginBatch(game, cache.vertices, cache.vb);
for (int i = 0; i < hotbarCount; i++) {
BlockID block = game.Inventory.Hotbar[i];
for (int i = 0; i < Inventory.BlocksPerRow; i++) {
BlockID block = game.Inventory[i];
int x = (int)(X + barXOffset + (elemSize + borderSize) * i + elemSize / 2);
int y = (int)(game.Height - barHeight / 2);
@ -103,7 +101,7 @@ namespace ClassicalSharp.Gui.Widgets {
public override bool HandlesKeyDown(Key key) {
if (key >= Key.Number1 && key <= Key.Number9) {
game.Inventory.HeldBlockIndex = (int)key - (int)Key.Number1;
game.Inventory.SelectedIndex = (int)key - (int)Key.Number1;
return true;
}
return false;
@ -115,13 +113,13 @@ namespace ClassicalSharp.Gui.Widgets {
InventoryScreen screen = game.Gui.ActiveScreen as InventoryScreen;
if (screen == null) return false;
for (int i = 0; i < hotbarCount; i++) {
for (int i = 0; i < Inventory.BlocksPerRow; i++) {
int x = (int)(X + (elemSize + borderSize) * i);
int y = (int)(game.Height - barHeight);
Rectangle bounds = new Rectangle(x, y, (int)(elemSize + borderSize), (int)barHeight);
if (bounds.Contains(mouseX, mouseY)) {
game.Inventory.HeldBlockIndex = i;
game.Inventory.SelectedIndex = i;
return true;
}
}

View File

@ -45,11 +45,12 @@ namespace ClassicalSharp.Gui.Widgets {
int index = 0;
posAtlas.tex.Y = (short)(game.Height - barHeight);
for (int i = 0; i < hotbarCount; i++) {
int offset = game.Inventory.Offset;
for (int i = 0; i < Inventory.BlocksPerRow; i++) {
int x = (int)(X + (elemSize + borderSize) * i);
posAtlas.curX = x;
if (surv.invCount[i] > 1)
posAtlas.AddInt(surv.invCount[i], vertices, ref index);
if (surv.invCount[offset + i] > 1)
posAtlas.AddInt(surv.invCount[offset + i], vertices, ref index);
}
gfx.BindTexture(posAtlas.tex.ID);

View File

@ -116,7 +116,7 @@ namespace ClassicalSharp.Commands {
if (!game.World.IsValidPos(min) || !game.World.IsValidPos(max)) return;
BlockID toPlace = block;
if (toPlace == Block.Invalid) toPlace = game.Inventory.HeldBlock;
if (toPlace == Block.Invalid) toPlace = game.Inventory.Selected;
for (int y = min.Y; y <= max.Y; y++)
for (int z = min.Z; z <= max.Z; z++)

View File

@ -150,11 +150,12 @@ namespace ClassicalSharp {
int delta = (int)deltaAcc;
deltaAcc -= delta;
int diff = -delta % inv.Hotbar.Length;
int newIndex = inv.HeldBlockIndex + diff;
if (newIndex < 0) newIndex += inv.Hotbar.Length;
if (newIndex >= inv.Hotbar.Length) newIndex -= inv.Hotbar.Length;
inv.HeldBlockIndex = newIndex;
const int blocksPerRow = Inventory.BlocksPerRow;
int diff = -delta % blocksPerRow;
int newIndex = inv.SelectedIndex + diff;
if (newIndex < 0) newIndex += blocksPerRow;
if (newIndex >= blocksPerRow) newIndex -= blocksPerRow;
inv.SelectedIndex = newIndex;
}
void KeyPressHandler(object sender, KeyPressEventArgs e) {

View File

@ -23,48 +23,59 @@ namespace ClassicalSharp {
public void OnNewMapLoaded(Game game) { }
public void Dispose() { }
int hotbarIndex = 0;
int selectedI = 0;
Game game;
public bool CanChangeHeldBlock = true;
public BlockID[] Hotbar = new BlockID[9];
public const int BlocksPerRow = 9, Rows = 2;
public int Offset = 0;
public BlockID[] Hotbar = new BlockID[BlocksPerRow * Rows];
public InventoryPermissions CanPlace = new InventoryPermissions();
public InventoryPermissions CanDelete = new InventoryPermissions();
/// <summary> Gets or sets the index of the held block.
/// Fails if the server has forbidden user from changing the held block. </summary>
public int HeldBlockIndex {
get { return hotbarIndex; }
/// <summary> Gets or sets the block at the given index within the current row. </summary>
public BlockID this[int index] {
get { return Hotbar[Offset + index]; }
set { Hotbar[Offset + index] = value; }
}
/// <summary> Gets or sets the index of the selected block within the current row. </summary>
/// <remarks> Fails if the server has forbidden user from changing the held block. </remarks>
public int SelectedIndex {
get { return selectedI; }
set {
if (!CanChangeHeldBlock) {
game.Chat.Add("&e/client: &cThe server has forbidden you from changing your held block.");
return;
}
hotbarIndex = value;
selectedI = value;
game.Events.RaiseHeldBlockChanged();
}
}
/// <summary> Gets or sets the block currently held by the player.
/// Fails if the server has forbidden user from changing the held block. </summary>
public BlockID HeldBlock {
get { return Hotbar[hotbarIndex]; }
/// <summary> Gets or sets the block currently selected by the player. </summary>
/// <remarks> Fails if the server has forbidden user from changing the held block. </remarks>
public BlockID Selected {
get { return Hotbar[Offset + selectedI]; }
set {
if (!CanChangeHeldBlock) {
game.Chat.Add("&e/client: &cThe server has forbidden you from changing your held block.");
return;
}
for (int i = 0; i < Hotbar.Length; i++) {
if (Hotbar[i] == value) {
BlockID held = Hotbar[hotbarIndex];
Hotbar[hotbarIndex] = Hotbar[i];
Hotbar[i] = held;
game.Events.RaiseHeldBlockChanged();
return;
}
for (int i = 0; i < BlocksPerRow; i++) {
if (this[i] != value) continue;
BlockID prevSelected = this[selectedI];
this[selectedI] = this[i];
this[i] = prevSelected;
game.Events.RaiseHeldBlockChanged();
return;
}
Hotbar[hotbarIndex] = value;
this[selectedI] = value;
game.Events.RaiseHeldBlockChanged();
}
}

View File

@ -39,7 +39,7 @@ namespace ClassicalSharp {
}
int btns = (left ? 1 : 0) + (right ? 1 : 0) + (middle ? 1 : 0);
if (btns > 1 || game.Gui.ActiveScreen.HandlesAllInput || inv.HeldBlock == Block.Invalid) return;
if (btns > 1 || game.Gui.ActiveScreen.HandlesAllInput || inv.Selected == Block.Invalid) return;
// always play delete animations, even if we aren't picking a block.
if (left) {
@ -67,7 +67,7 @@ namespace ClassicalSharp {
if (!game.World.IsValidPos(pos)) return;
BlockID old = game.World.GetBlock(pos);
BlockID block = inv.HeldBlock;
BlockID block = inv.Selected;
if (game.autoRotate)
block = AutoRotate.RotateBlock(game, block);

View File

@ -33,12 +33,12 @@ namespace ClassicalSharp.Mode {
public void PickMiddle(BlockID old) {
Inventory inv = game.Inventory;
if (game.BlockInfo.Draw[old] != DrawType.Gas && (inv.CanPlace[old] || inv.CanDelete[old])) {
for (int i = 0; i < inv.Hotbar.Length; i++) {
if (inv.Hotbar[i] == old) {
inv.HeldBlockIndex = i; return;
}
for (int i = 0; i < Inventory.BlocksPerRow; i++) {
if (inv[i] != old) continue;
inv.SelectedIndex = i; return;
}
inv.HeldBlock = old;
inv.Selected = old;
}
}
@ -57,9 +57,10 @@ namespace ClassicalSharp.Mode {
public void Init(Game game) {
this.game = game;
game.Inventory.Hotbar = new BlockID[] { Block.Stone,
Block.Cobblestone, Block.Brick, Block.Dirt, Block.Wood,
Block.Log, Block.Leaves, Block.Grass, Block.Slab };
Inventory inv = game.Inventory;
inv[0] = Block.Stone; inv[1] = Block.Cobblestone; inv[2] = Block.Brick;
inv[3] = Block.Dirt; inv[4] = Block.Wood; inv[5] = Block.Log;
inv[6] = Block.Leaves; inv[7] = Block.Grass; inv[8] = Block.Slab;
}

View File

@ -18,9 +18,11 @@ namespace ClassicalSharp.Mode {
Game game;
int score = 0;
internal byte[] invCount = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 10 };
internal byte[] invCount = new byte[Inventory.BlocksPerRow * Inventory.Rows];
Random rnd = new Random();
public SurvivalGameMode() { invCount[8] = 10; } // tnt
public bool HandlesKeyDown(Key key) { return false; }
public void PickLeft(BlockID old) {
@ -34,18 +36,18 @@ namespace ClassicalSharp.Mode {
}
public void PickRight(BlockID old, BlockID block) {
int index = game.Inventory.HeldBlockIndex;
if (invCount[index] == 0) return;
int index = game.Inventory.SelectedIndex, offset = game.Inventory.Offset;
if (invCount[offset + index] == 0) return;
Vector3I pos = game.SelectedPos.TranslatedPos;
game.UpdateBlock(pos.X, pos.Y, pos.Z, block);
game.UserEvents.RaiseBlockChanged(pos, old, block);
invCount[index]--;
if (invCount[index] != 0) return;
invCount[offset + index]--;
if (invCount[offset + index] != 0) return;
// bypass HeldBlock's normal behaviour
game.Inventory.Hotbar[index] = Block.Air;
game.Inventory[index] = Block.Air;
game.Events.RaiseHeldBlockChanged();
}
@ -80,24 +82,23 @@ namespace ClassicalSharp.Mode {
}
void AddToHotbar(BlockID block, int count) {
int index = -1;
BlockID[] hotbar = game.Inventory.Hotbar;
int index = -1, offset = game.Inventory.Offset;
// Try searching for same block, then try invalid block
for (int i = 0; i < hotbar.Length; i++) {
if (hotbar[i] == block) index = i;
for (int i = 0; i < Inventory.BlocksPerRow; i++) {
if (game.Inventory[i] == block) index = i;
}
if (index == -1) {
for (int i = hotbar.Length - 1; i >= 0; i--) {
if (hotbar[i] == Block.Air) index = i;
for (int i = Inventory.BlocksPerRow - 1; i >= 0; i--) {
if (game.Inventory[i] == Block.Air) index = i;
}
}
if (index == -1) return; // no free slots
for (int j = 0; j < count; j++) {
if (invCount[index] >= 99) return; // no more count
hotbar[index] = block;
invCount[index]++; // TODO: do we need to raise an event if changing held block still?
if (invCount[offset + index] >= 99) return; // no more count
game.Inventory[index] = block;
invCount[offset + index]++; // TODO: do we need to raise an event if changing held block still?
// TODO: we need to spawn block models instead
}
}
@ -123,7 +124,7 @@ namespace ClassicalSharp.Mode {
BlockID[] hotbar = game.Inventory.Hotbar;
for (int i = 0; i < hotbar.Length; i++)
hotbar[i] = Block.Air;
hotbar[hotbar.Length - 1] = Block.TNT;
hotbar[Inventory.BlocksPerRow - 1] = Block.TNT;
game.Server.AppName += " (survival)";
}

View File

@ -189,7 +189,7 @@ namespace ClassicalSharp.Network {
void BlockChanged(object sender, BlockChangedEventArgs e) {
Vector3I p = e.Coords;
BlockID block = game.Inventory.HeldBlock;
BlockID block = game.Inventory.Selected;
if (e.Block == 0) {
classic.SendSetBlock(p.X, p.Y, p.Z, false, block);

View File

@ -94,7 +94,7 @@ namespace ClassicalSharp.Network.Protocols {
bool canChange = reader.ReadUInt8() == 0;
game.Inventory.CanChangeHeldBlock = true;
game.Inventory.HeldBlock = block;
game.Inventory.Selected = block;
game.Inventory.CanChangeHeldBlock = canChange;
}

View File

@ -283,7 +283,7 @@ namespace ClassicalSharp.Network.Protocols {
}
internal void SendPosition(Vector3 pos, float rotY, float headX) {
int payload = net.cpeData.sendHeldBlock ? game.Inventory.HeldBlock : 0xFF;
int payload = net.cpeData.sendHeldBlock ? game.Inventory.Selected : 0xFF;
writer.WriteUInt8((byte)Opcode.EntityTeleport);
writer.WriteUInt8((byte)payload); // held block when using HeldBlock, otherwise just 255

View File

@ -26,7 +26,7 @@ namespace ClassicalSharp.Renderers {
internal void Init(Game game, HeldBlockRenderer held) {
this.game = game;
this.held = held;
lastType = game.Inventory.HeldBlock;
lastType = game.Inventory.Selected;
game.Events.HeldBlockChanged += DoSwitchBlockAnim;
game.UserEvents.BlockChanged += BlockChanged;
@ -131,7 +131,7 @@ namespace ClassicalSharp.Renderers {
speed = Math.PI / period;
if (updateLastType)
lastType = game.Inventory.HeldBlock;
lastType = game.Inventory.Selected;
pos = Vector3.Zero;
}
}

View File

@ -45,7 +45,7 @@ namespace ClassicalSharp.Renderers {
Vector3 last = anim.pos;
anim.pos = Vector3.Zero;
type = game.Inventory.HeldBlock;
type = game.Inventory.Selected;
block.CosX = 1; block.SinX = 0;
block.SwitchOrder = false;
if (anim.doAnim) anim.Update(delta, last);