mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-22 20:19:09 -04:00
Initial work on inventory that supports multiple hotbars.
This commit is contained in:
parent
35fd58f893
commit
dd0b497136
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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++)
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)";
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user