Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
7a91563
added button
Crepestrom Jun 8, 2026
1bc6472
Update Inventory.zig
Crepestrom Jun 8, 2026
bb2ff56
hmm baseitems dont work
Crepestrom Jun 8, 2026
96e1ccd
Basic Sorting works
Crepestrom Jun 9, 2026
9cc3310
Sorting Finish
Crepestrom Jun 9, 2026
befe81c
formatting
Crepestrom Jun 9, 2026
cc53269
sort icon
Crepestrom Jun 9, 2026
88510ea
Update sort_icon.png
Crepestrom Jun 9, 2026
2c6e489
updated
Crepestrom Jun 11, 2026
d505cba
formatting
Crepestrom Jun 11, 2026
4721852
formatting 2
Crepestrom Jun 11, 2026
d5f8e9a
formatting 3
Crepestrom Jun 11, 2026
1fa83ee
durability procedural tool check
Crepestrom Jun 12, 2026
8e5d0e1
formatting
Crepestrom Jun 12, 2026
fe8e1bb
Update sort_icon.png
Crepestrom Jun 13, 2026
7e399ef
new ui
Crepestrom Jun 13, 2026
b2dd74d
Update sort_icon.png
Crepestrom Jun 13, 2026
398bfed
Update sort_icon.png
Crepestrom Jun 13, 2026
1484c50
Update sort_icon.png
Crepestrom Jun 13, 2026
d8823ff
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jun 13, 2026
2d56b5a
fixed for master and updated ui
Crepestrom Jun 13, 2026
61c286e
ui
Crepestrom Jun 13, 2026
44a6365
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jun 15, 2026
f4adb1e
sort button moved to titlebar
Crepestrom Jun 15, 2026
6884130
Update inventory.zig
Crepestrom Jun 15, 2026
cc384fb
steps to hiding button
Crepestrom Jul 11, 2026
01a642d
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jul 11, 2026
3abcf85
button finished
Crepestrom Jul 11, 2026
4f76eb3
formatting 1
Crepestrom Jul 11, 2026
3b8fa4a
added to chests
Crepestrom Jul 12, 2026
49e245e
moved gettags to the item struct
Crepestrom Jul 12, 2026
7e27205
oops child renders twice
Crepestrom Jul 12, 2026
0bced26
Update Button.zig
Crepestrom Jul 12, 2026
811ac0e
simple fixes
Crepestrom Jul 13, 2026
b7f1276
modified callbacks
Crepestrom Jul 13, 2026
74e5194
Update src/gui/components/Button.zig
Crepestrom Jul 13, 2026
f442b94
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jul 13, 2026
62b9b4f
Merge branch 'Sort-Button-2' of https://github.com/Crepestrom/Cubyz i…
Crepestrom Jul 13, 2026
ecb2c74
renamed function
Crepestrom Jul 13, 2026
74c2151
swapped allocator
Crepestrom Jul 13, 2026
3fecc12
now with less server calls
Crepestrom Jul 14, 2026
9aed687
remove debug messages
Crepestrom Jul 14, 2026
630e8bf
rename hidden to hidebackground
Crepestrom Jul 14, 2026
4bce480
privating functions
Crepestrom Jul 14, 2026
9ad4fd9
quick changes
Crepestrom Jul 14, 2026
bd5c668
Update Inventory.zig
Crepestrom Jul 14, 2026
e6d33b4
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jul 14, 2026
76c498a
stack allocator
Crepestrom Jul 14, 2026
f6e5436
Delete src/server/command/clear copy.zig
Crepestrom Jul 14, 2026
f7cd137
oops missed some of these
Crepestrom Jul 14, 2026
a8fdebc
oh this wasnt needed after all
Crepestrom Jul 14, 2026
b24203a
i think i deinit this then
Crepestrom Jul 14, 2026
bdeabc0
swapped context insertion with insertion
Crepestrom Jul 14, 2026
da78f3e
options struct
Crepestrom Jul 14, 2026
e029e9e
rename to intermidiaryList
Crepestrom Jul 14, 2026
6d1b790
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jul 16, 2026
f7cbc5e
Update Inventory.zig
Crepestrom Jul 19, 2026
2545f15
added functionality
Crepestrom Jul 20, 2026
a3f31ee
use this version for testing
Crepestrom Jul 20, 2026
537b888
Revert "use this version for testing"
Crepestrom Jul 20, 2026
6061c15
Revert "added functionality"
Crepestrom Jul 20, 2026
71250e0
Update Inventory.zig
Crepestrom Jul 20, 2026
f7eb5b5
chest sorts chest now
Crepestrom Jul 22, 2026
4393805
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Jul 22, 2026
0811db1
oops this isnt seen
Crepestrom Jul 22, 2026
7dd1ff0
fixed the leak and the item compression
Crepestrom Jul 25, 2026
822fed3
use stack size instead of magic number
Crepestrom Jul 25, 2026
7dcd839
changes size during intialization rather than other
Crepestrom Jul 25, 2026
a2dec0f
simple changes
Crepestrom Aug 4, 2026
1375702
Update Inventory.zig
Crepestrom Aug 4, 2026
6dbdb36
Merge remote-tracking branch 'upstream/master' into Sort-Button-2
Crepestrom Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/cubyz/ui/inventory/sort_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions src/Inventory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Item = main.items.Item;
const ItemStack = main.items.ItemStack;
const ProceduralItem = main.items.ProceduralItem;
const utils = main.utils;
const Tag = main.Tag;
const BinaryWriter = utils.BinaryWriter;
const BinaryReader = utils.BinaryReader;
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
Expand Down Expand Up @@ -538,6 +539,71 @@ pub const ClientInventory = struct { // MARK: ClientInventory
main.sync.client.executeCommand(.{.craftProceduralItem = .init(destinations, workbenchInv)});
}

pub const SortOptions = struct {
ignoredSlotCount: usize,
};

pub fn sortItems(source: ClientInventory, options: SortOptions) void {
compressItems(source, options);
const InventorySize: usize = source.super.size() - options.ignoredSlotCount;
var sortList = main.ListManaged(usize).init(main.stackAllocator);
defer sortList.deinit();
var intermediaryList = main.ListManaged(usize).init(main.stackAllocator);
defer intermediaryList.deinit();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defer should always be directly after the line that does the init

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved

for (0..InventorySize) |i| {
sortList.append(i + options.ignoredSlotCount);
intermediaryList.append(i + options.ignoredSlotCount);
}
const ctx: SortContext = .{.inv = source, .sortlist = sortList};
std.sort.insertion(usize, sortList.items, ctx, SortContext.lessThan);
for (0..InventorySize) |i| {
if (sortList.items[i] == intermediaryList.items[i]) continue;
var previousIndex: usize = i;
var checkedIndex = sortList.items[i] - options.ignoredSlotCount;
while (checkedIndex != i) {
main.sync.client.executeCommand(.{.depositOrSwap = .{
.dest = .{.inv = source.super, .slot = @intCast(previousIndex + options.ignoredSlotCount)},
.source = .{.inv = source.super, .slot = @intCast(checkedIndex + options.ignoredSlotCount)},
}});
std.mem.swap(usize, &intermediaryList.items[previousIndex], &intermediaryList.items[checkedIndex]);
previousIndex = checkedIndex;
checkedIndex = sortList.items[checkedIndex] - options.ignoredSlotCount;
}
}
}

pub fn compressItems(source: ClientInventory, options: SortOptions) void {
for (source.super._items, 0..) |invStack, slot| {
if (invStack.item == .null) continue;
if (slot < options.ignoredSlotCount) continue;
for (source.super._items, 0..) |checkedInvStack, checkedSlot| {
if (checkedInvStack.item == .null) continue;
if (checkedSlot < slot) continue;
if (checkedSlot < options.ignoredSlotCount) continue;
if (std.meta.eql(invStack.item, checkedInvStack.item)) {
main.sync.client.executeCommand(.{.deposit = .{.dest = .{.inv = source.super, .slot = @intCast(checkedSlot)}, .source = .{.inv = source.super, .slot = @intCast(slot)}, .amount = checkedInvStack.item.stackSize()}});
}
}
}
}

const SortContext = struct {
inv: ClientInventory,
sortlist: main.ListManaged(usize),

pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
const itemA: Item = ctx.inv.getItem(a);
const itemB: Item = ctx.inv.getItem(b);

if (itemA == .null) return false;
if (itemB == .null) return true;
if ((itemA != .proceduralItem) and (itemB == .proceduralItem)) return false;
if ((itemA == .proceduralItem) and (itemB != .proceduralItem)) return true;

return std.mem.lessThan(u8, itemA.id().?, itemB.id().?);
Comment thread
Crepestrom marked this conversation as resolved.
}
};

pub fn placeBlock(self: ClientInventory, slot: u32) void {
std.debug.assert(self.type == .serverShared);
main.renderer.MeshSelection.placeBlock(self, slot);
Expand Down
1 change: 1 addition & 0 deletions src/assets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const NeverFailingArenaAllocator = main.heap.NeverFailingArenaAllocator;
const List = main.List;
const files = main.files;
const Tag = main.Tag;

var common: Assets = undefined;

Expand Down
2 changes: 1 addition & 1 deletion src/blocks.zig
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 {
const rotation_tags = _mode[size].getBlockTags();
const block_tags = Tag.loadTagsFromZon(main.stackAllocator, zon.getChild("tags"));
defer main.stackAllocator.free(block_tags);
_tags[size] = std.mem.concat(main.worldArena.allocator, Tag, &.{rotation_tags, block_tags}) catch unreachable;
_tags[size] = std.mem.concat(main.worldArena.allocator, Tag, &.{block_tags, rotation_tags}) catch unreachable;

if (_tags[size].len == 0) std.log.err("Block {s} is missing 'tags' field", .{id});
for (_tags[size]) |tag| {
Expand Down
22 changes: 16 additions & 6 deletions src/gui/components/Button.zig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ size: Vec2f,
disabled: bool = false,
pressed: bool = false,
hovered: bool = false,
hideBackground: bool = false,
onAction: main.callbacks.SimpleCallback,
child: GuiComponent,

Expand Down Expand Up @@ -88,6 +89,7 @@ pub fn globalDeinit() void {
const Options = struct {
onAction: main.callbacks.SimpleCallback = .{},
disabled: bool = false,
hideBackground: bool = false,
};

pub fn initText(pos: Vec2f, width: f32, text: []const u8, options: Options) *Button {
Expand All @@ -99,7 +101,9 @@ pub fn initText(pos: Vec2f, width: f32, text: []const u8, options: Options) *But
.onAction = options.onAction,
.child = label.toComponent(),
.disabled = options.disabled,
.hideBackground = options.hideBackground,
};
if (self.hideBackground) self.child.mutSize().* = self.size;
return self;
}

Expand All @@ -112,7 +116,9 @@ pub fn initIcon(pos: Vec2f, iconSize: Vec2f, iconTexture: Texture, options: Opti
.onAction = options.onAction,
.child = icon.toComponent(),
.disabled = options.disabled,
.hideBackground = options.hideBackground,
};
if (self.hideBackground) self.child.mutSize().* = self.size;
return self;
}

Expand Down Expand Up @@ -145,6 +151,16 @@ pub fn mainButtonReleased(self: *Button, mousePosition: Vec2f) void {
}

pub fn render(self: *Button, mousePosition: Vec2f) void {
if (!self.hideBackground) renderBackground(self, mousePosition);

const oldColor = draw.setColor(if (self.disabled) 0xff808080 else 0xffffffff);
defer draw.restoreColor(oldColor);
const textPos = self.pos + self.size/@as(Vec2f, @splat(2.0)) - self.child.size()/@as(Vec2f, @splat(2.0));
self.child.mutPos().* = textPos;
self.child.render(mousePosition - self.pos);
}

fn renderBackground(self: *Button, mousePosition: Vec2f) void {
const textures = blk: {
if (self.disabled) break :blk disabledTextures;
if (self.pressed) break :blk pressedTextures;
Expand All @@ -164,10 +180,4 @@ pub fn render(self: *Button, mousePosition: Vec2f) void {

textures.outlineTexture.bindTo(0);
graphics.draw.bound9SliceImage(self.pos, self.size, textures.outlineTextureSize, cornerSize, 2);

const oldColor = draw.setColor(if (self.disabled) 0xff808080 else 0xffffffff);
defer draw.restoreColor(oldColor);
const textPos = self.pos + self.size/@as(Vec2f, @splat(2.0)) - self.child.size()/@as(Vec2f, @splat(2.0));
self.child.mutPos().* = textPos;
self.child.render(mousePosition - self.pos);
}
16 changes: 16 additions & 0 deletions src/gui/windows/chest.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ pub var window = GuiWindow{
const padding: f32 = 8;
var itemSlots: main.List(*ItemSlot) = .empty;

var sortIcon: Texture = undefined;

pub fn init() void {
sortIcon = Texture.initFromFile("assets/cubyz/ui/inventory/sort_icon.png");
Comment thread
Crepestrom marked this conversation as resolved.
}

pub fn deinit() void {
sortIcon.deinit();
itemSlots.clearAndFree(main.globalAllocator);
}

Expand All @@ -39,7 +46,15 @@ pub fn setInventory(selectedInventory: main.items.Inventory.ClientInventory) voi
openInventory = selectedInventory;
}

fn sortItems() void {
const target = openInventory;
target.sortItems(.{.ignoredSlotCount = 0});
Comment thread
Crepestrom marked this conversation as resolved.
}

pub fn onOpen() void {
window.titleBar = HorizontalList.init();
window.titleBar.?.add(Button.initIcon(.{0, 0}, .{9, 9}, sortIcon, .{.onAction = .init(sortItems), .hideBackground = true}));

const list = VerticalList.init(.{padding, padding + 16}, 300, 0);

for (0..2) |y| {
Expand Down Expand Up @@ -67,4 +82,5 @@ pub fn onClose() void {
comp.deinit();
window.rootComponent = null;
}
window.titleBar.?.deinit();
}
12 changes: 12 additions & 0 deletions src/gui/windows/inventory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,29 @@ pub var window = GuiWindow{
const padding: f32 = 8;

var craftingIcon: Texture = undefined;
var sortIcon: Texture = undefined;

pub fn init() void {
craftingIcon = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_icon.png");
sortIcon = Texture.initFromFile("assets/cubyz/ui/inventory/sort_icon.png");
Comment thread
Crepestrom marked this conversation as resolved.
}

pub fn deinit() void {
craftingIcon.deinit();
sortIcon.deinit();
}

var itemSlots: [20]*ItemSlot = undefined;

fn sortItems() void {
const target = Player.inventory;
target.sortItems(.{.ignoredSlotCount = 12});
}

pub fn onOpen() void {
window.titleBar = HorizontalList.init();
window.titleBar.?.add(Button.initIcon(.{0, 0}, .{9, 9}, sortIcon, .{.onAction = .init(sortItems), .hideBackground = true}));

const list = VerticalList.init(.{padding, padding + 16}, 300, 0);
// Some miscellanious slots and buttons:
// TODO: armor slots, backpack slot + stack-based backpack inventory, other items maybe?
Expand Down Expand Up @@ -73,4 +84,5 @@ pub fn onClose() void {
if (window.rootComponent) |*comp| {
comp.deinit();
}
window.titleBar.?.deinit();
}
Loading