mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Add the ItemSlot component.
This commit is contained in:
parent
f158da89d4
commit
642624c94d
BIN
assets/cubyz/ui/inventory/slot.png
Normal file
BIN
assets/cubyz/ui/inventory/slot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 696 B |
110
src/gui/components/ItemSlot.zig
Normal file
110
src/gui/components/ItemSlot.zig
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const main = @import("root");
|
||||||
|
const ItemStack = main.items.ItemStack;
|
||||||
|
const graphics = main.graphics;
|
||||||
|
const draw = graphics.draw;
|
||||||
|
const Texture = graphics.Texture;
|
||||||
|
const TextBuffer = graphics.TextBuffer;
|
||||||
|
const vec = main.vec;
|
||||||
|
const Vec2f = vec.Vec2f;
|
||||||
|
|
||||||
|
const gui = @import("../gui.zig");
|
||||||
|
const GuiComponent = gui.GuiComponent;
|
||||||
|
|
||||||
|
const ItemSlot = @This();
|
||||||
|
|
||||||
|
var texture: Texture = undefined;
|
||||||
|
const border: f32 = 3;
|
||||||
|
|
||||||
|
pos: Vec2f,
|
||||||
|
size: Vec2f = .{32 + 2*border, 32 + 2*border},
|
||||||
|
itemStack: *ItemStack,
|
||||||
|
oldStack: ItemStack,
|
||||||
|
text: TextBuffer,
|
||||||
|
textSize: Vec2f = .{0, 0},
|
||||||
|
hovered: bool = false,
|
||||||
|
pressed: bool = false,
|
||||||
|
|
||||||
|
pub fn __init() !void {
|
||||||
|
texture = try Texture.initFromFile("assets/cubyz/ui/inventory/slot.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __deinit() void {
|
||||||
|
texture.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(pos: Vec2f, itemStack: *ItemStack) Allocator.Error!*ItemSlot {
|
||||||
|
const self = try gui.allocator.create(ItemSlot);
|
||||||
|
var buf: [16]u8 = undefined;
|
||||||
|
self.* = ItemSlot {
|
||||||
|
.itemStack = itemStack,
|
||||||
|
.oldStack = itemStack.*,
|
||||||
|
.pos = pos,
|
||||||
|
.text = try TextBuffer.init(gui.allocator, std.fmt.bufPrint(&buf, "{}", .{self.itemStack.amount}) catch "∞", .{}, false, .right),
|
||||||
|
};
|
||||||
|
self.textSize = try self.text.calculateLineBreaks(8, self.size[0] - 2*border);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *const ItemSlot) void {
|
||||||
|
self.text.deinit();
|
||||||
|
gui.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refreshText(self: *ItemSlot) !void {
|
||||||
|
self.text.deinit();
|
||||||
|
var buf: [16]u8 = undefined;
|
||||||
|
self.text = try TextBuffer.init(gui.allocator, std.fmt.bufPrint(&buf, "{}", .{self.itemStack.amount}) catch "∞", .{}, false, .right);
|
||||||
|
self.textSize = try self.text.calculateLineBreaks(8, self.size[0] - 2*border);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toComponent(self: *ItemSlot) GuiComponent {
|
||||||
|
return GuiComponent{
|
||||||
|
.itemSlot = self
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn updateHovered(self: *ItemSlot, _: Vec2f) void {
|
||||||
|
self.hovered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mainButtonPressed(self: *ItemSlot, _: Vec2f) void {
|
||||||
|
self.pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mainButtonReleased(self: *ItemSlot, mousePosition: Vec2f) void {
|
||||||
|
if(self.pressed) {
|
||||||
|
self.pressed = false;
|
||||||
|
if(GuiComponent.contains(self.pos, self.size, mousePosition)) {
|
||||||
|
//TODO: self.onAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(self: *ItemSlot, _: Vec2f) !void {
|
||||||
|
const newStack = self.itemStack.*;
|
||||||
|
if(newStack.amount != self.oldStack.amount) {
|
||||||
|
try self.refreshText();
|
||||||
|
}
|
||||||
|
draw.setColor(0xffffffff);
|
||||||
|
texture.bindTo(0);
|
||||||
|
draw.boundImage(self.pos, self.size);
|
||||||
|
if(self.itemStack.item) |item| {
|
||||||
|
const itemTexture = try item.getTexture();
|
||||||
|
itemTexture.bindTo(0);
|
||||||
|
draw.boundImage(self.pos + @splat(2, border), self.size - @splat(2, 2*border));
|
||||||
|
if(self.itemStack.amount > 1) {
|
||||||
|
try self.text.render(self.pos[0] + self.size[0] - self.textSize[0] - border, self.pos[1] + self.size[1] - self.textSize[1] - border, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(self.pressed) {
|
||||||
|
draw.setColor(0x80808080);
|
||||||
|
draw.rect(self.pos, self.size);
|
||||||
|
} else if(self.hovered) {
|
||||||
|
self.hovered = false;
|
||||||
|
draw.setColor(0x300000ff);
|
||||||
|
draw.rect(self.pos, self.size);
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ const Vec2f = vec.Vec2f;
|
|||||||
|
|
||||||
const Button = @import("components/Button.zig");
|
const Button = @import("components/Button.zig");
|
||||||
const CheckBox = @import("components/CheckBox.zig");
|
const CheckBox = @import("components/CheckBox.zig");
|
||||||
|
const ItemSlot = @import("components/ItemSlot.zig");
|
||||||
const ScrollBar = @import("components/ScrollBar.zig");
|
const ScrollBar = @import("components/ScrollBar.zig");
|
||||||
const Slider = @import("components/Slider.zig");
|
const Slider = @import("components/Slider.zig");
|
||||||
const TextInput = @import("components/TextInput.zig");
|
const TextInput = @import("components/TextInput.zig");
|
||||||
@ -46,6 +47,7 @@ pub fn init(_allocator: Allocator) !void {
|
|||||||
try GuiWindow.__init();
|
try GuiWindow.__init();
|
||||||
try Button.__init();
|
try Button.__init();
|
||||||
try CheckBox.__init();
|
try CheckBox.__init();
|
||||||
|
try ItemSlot.__init();
|
||||||
try ScrollBar.__init();
|
try ScrollBar.__init();
|
||||||
try Slider.__init();
|
try Slider.__init();
|
||||||
try TextInput.__init();
|
try TextInput.__init();
|
||||||
@ -65,6 +67,7 @@ pub fn deinit() void {
|
|||||||
GuiWindow.__deinit();
|
GuiWindow.__deinit();
|
||||||
Button.__deinit();
|
Button.__deinit();
|
||||||
CheckBox.__deinit();
|
CheckBox.__deinit();
|
||||||
|
ItemSlot.__deinit();
|
||||||
ScrollBar.__deinit();
|
ScrollBar.__deinit();
|
||||||
Slider.__deinit();
|
Slider.__deinit();
|
||||||
TextInput.__deinit();
|
TextInput.__deinit();
|
||||||
|
@ -9,6 +9,7 @@ pub const GuiComponent = union(enum) {
|
|||||||
pub const Button = @import("components/Button.zig");
|
pub const Button = @import("components/Button.zig");
|
||||||
pub const CheckBox = @import("components/CheckBox.zig");
|
pub const CheckBox = @import("components/CheckBox.zig");
|
||||||
pub const HorizontalList = @import("components/HorizontalList.zig");
|
pub const HorizontalList = @import("components/HorizontalList.zig");
|
||||||
|
pub const ItemSlot = @import("components/ItemSlot.zig");
|
||||||
pub const Label = @import("components/Label.zig");
|
pub const Label = @import("components/Label.zig");
|
||||||
pub const MutexComponent = @import("components/MutexComponent.zig");
|
pub const MutexComponent = @import("components/MutexComponent.zig");
|
||||||
pub const Slider = @import("components/Slider.zig");
|
pub const Slider = @import("components/Slider.zig");
|
||||||
@ -20,6 +21,7 @@ pub const GuiComponent = union(enum) {
|
|||||||
button: *Button,
|
button: *Button,
|
||||||
checkBox: *CheckBox,
|
checkBox: *CheckBox,
|
||||||
horizontalList: *HorizontalList,
|
horizontalList: *HorizontalList,
|
||||||
|
itemSlot: *ItemSlot,
|
||||||
label: *Label,
|
label: *Label,
|
||||||
mutexComponent: *MutexComponent,
|
mutexComponent: *MutexComponent,
|
||||||
scrollBar: *ScrollBar,
|
scrollBar: *ScrollBar,
|
||||||
|
@ -2,20 +2,45 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const main = @import("root");
|
const main = @import("root");
|
||||||
|
const Player = main.game.Player;
|
||||||
const Vec2f = main.vec.Vec2f;
|
const Vec2f = main.vec.Vec2f;
|
||||||
|
|
||||||
const gui = @import("../gui.zig");
|
const gui = @import("../gui.zig");
|
||||||
const GuiComponent = gui.GuiComponent;
|
const GuiComponent = gui.GuiComponent;
|
||||||
const GuiWindow = gui.GuiWindow;
|
const GuiWindow = gui.GuiWindow;
|
||||||
|
const HorizontalList = GuiComponent.HorizontalList;
|
||||||
|
const ItemSlot = GuiComponent.ItemSlot;
|
||||||
|
|
||||||
|
var components: [1]GuiComponent = undefined;
|
||||||
pub var window = GuiWindow {
|
pub var window = GuiWindow {
|
||||||
.contentSize = Vec2f{64*8, 64},
|
.contentSize = Vec2f{64*8, 64},
|
||||||
.title = "Hotbar",
|
.title = "Hotbar",
|
||||||
.id = "cubyz:hotbar",
|
.id = "cubyz:hotbar",
|
||||||
|
.onOpenFn = &onOpen,
|
||||||
|
.onCloseFn = &onClose,
|
||||||
.renderFn = &render,
|
.renderFn = &render,
|
||||||
|
.components = &components,
|
||||||
.isHud = true,
|
.isHud = true,
|
||||||
|
.showTitleBar = false,
|
||||||
|
.hasBackground = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn render() Allocator.Error!void {
|
pub fn onOpen() Allocator.Error!void {
|
||||||
|
var list = try HorizontalList.init();
|
||||||
|
for(0..8) |i| {
|
||||||
|
try list.add(try ItemSlot.init(.{0, 0}, &Player.inventory__SEND_CHANGES_TO_SERVER.items[i]));
|
||||||
|
}
|
||||||
|
list.finish(.{0, 0}, .center);
|
||||||
|
components[0] = list.toComponent();
|
||||||
|
window.contentSize = components[0].size();
|
||||||
|
gui.updateWindowPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn onClose() void {
|
||||||
|
for(&components) |*comp| {
|
||||||
|
comp.deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render() Allocator.Error!void {
|
||||||
}
|
}
|
@ -570,7 +570,7 @@ pub const ItemDropRenderer = struct {
|
|||||||
.item = template.item,
|
.item = template.item,
|
||||||
};
|
};
|
||||||
// Find sizes and free index:
|
// Find sizes and free index:
|
||||||
const img = self.item.getTexture();
|
const img = self.item.getImage();
|
||||||
self.size = Vec3i{img.width, 1, img.height};
|
self.size = Vec3i{img.width, 1, img.height};
|
||||||
var freeSlot: ?*ItemVoxelModel = null;
|
var freeSlot: ?*ItemVoxelModel = null;
|
||||||
for(freeSlots.items, 0..) |potentialSlot, i| {
|
for(freeSlots.items, 0..) |potentialSlot, i| {
|
||||||
|
@ -67,7 +67,8 @@ const Material = struct {
|
|||||||
|
|
||||||
|
|
||||||
pub const BaseItem = struct {
|
pub const BaseItem = struct {
|
||||||
texture: graphics.Image,
|
image: graphics.Image,
|
||||||
|
texture: ?graphics.Texture, // TODO: Properly deinit
|
||||||
id: []const u8,
|
id: []const u8,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ pub const BaseItem = struct {
|
|||||||
|
|
||||||
fn init(self: *BaseItem, allocator: Allocator, texturePath: []const u8, replacementTexturePath: []const u8, id: []const u8, json: JsonElement) !void {
|
fn init(self: *BaseItem, allocator: Allocator, texturePath: []const u8, replacementTexturePath: []const u8, id: []const u8, json: JsonElement) !void {
|
||||||
self.id = try allocator.dupe(u8, id);
|
self.id = try allocator.dupe(u8, id);
|
||||||
self.texture = graphics.Image.readFromFile(allocator, texturePath) catch graphics.Image.readFromFile(allocator, replacementTexturePath) catch blk: {
|
self.image = graphics.Image.readFromFile(allocator, texturePath) catch graphics.Image.readFromFile(allocator, replacementTexturePath) catch blk: {
|
||||||
std.log.err("Item texture not found in {s} and {s}.", .{texturePath, replacementTexturePath});
|
std.log.err("Item texture not found in {s} and {s}.", .{texturePath, replacementTexturePath});
|
||||||
break :blk graphics.Image.defaultImage;
|
break :blk graphics.Image.defaultImage;
|
||||||
};
|
};
|
||||||
@ -94,6 +95,7 @@ pub const BaseItem = struct {
|
|||||||
self.block = blk: {
|
self.block = blk: {
|
||||||
break :blk blocks.getByID(json.get(?[]const u8, "block", null) orelse break :blk null);
|
break :blk blocks.getByID(json.get(?[]const u8, "block", null) orelse break :blk null);
|
||||||
};
|
};
|
||||||
|
self.texture = null;
|
||||||
self.foodValue = json.get(f32, "food", 0);
|
self.foodValue = json.get(f32, "food", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +106,14 @@ pub const BaseItem = struct {
|
|||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getTexture(self: *BaseItem) !graphics.Texture {
|
||||||
|
if(self.texture == null) {
|
||||||
|
self.texture = graphics.Texture.init();
|
||||||
|
try self.texture.?.generate(self.image);
|
||||||
|
}
|
||||||
|
return self.texture.?;
|
||||||
|
}
|
||||||
// TODO: Check if/how this is needed:
|
// TODO: Check if/how this is needed:
|
||||||
// protected Item(int stackSize) {
|
// protected Item(int stackSize) {
|
||||||
// id = Resource.EMPTY;
|
// id = Resource.EMPTY;
|
||||||
@ -412,7 +422,7 @@ const TextureGenerator = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(tool: *Tool) !void {
|
pub fn generate(tool: *Tool) !void {
|
||||||
const img = tool.texture;
|
const img = tool.image;
|
||||||
var pixelMaterials: [16][16]PixelData = undefined;
|
var pixelMaterials: [16][16]PixelData = undefined;
|
||||||
for(0..16) |x| {
|
for(0..16) |x| {
|
||||||
for(0..16) |y| {
|
for(0..16) |y| {
|
||||||
@ -869,7 +879,8 @@ const ToolPhysics = struct {
|
|||||||
const Tool = struct {
|
const Tool = struct {
|
||||||
craftingGrid: [25]?*const BaseItem,
|
craftingGrid: [25]?*const BaseItem,
|
||||||
materialGrid: [16][16]?*const BaseItem,
|
materialGrid: [16][16]?*const BaseItem,
|
||||||
texture: graphics.Image,
|
image: graphics.Image,
|
||||||
|
texture: ?graphics.Texture,
|
||||||
seed: u32,
|
seed: u32,
|
||||||
|
|
||||||
/// Reduction factor to block breaking time.
|
/// Reduction factor to block breaking time.
|
||||||
@ -901,12 +912,16 @@ const Tool = struct {
|
|||||||
|
|
||||||
pub fn init() !*Tool {
|
pub fn init() !*Tool {
|
||||||
var self = try main.globalAllocator.create(Tool);
|
var self = try main.globalAllocator.create(Tool);
|
||||||
self.texture = try graphics.Image.init(main.globalAllocator, 16, 16);
|
self.image = try graphics.Image.init(main.globalAllocator, 16, 16);
|
||||||
|
self.texture = null;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *const Tool) void {
|
pub fn deinit(self: *const Tool) void {
|
||||||
self.texture.deinit(main.globalAllocator);
|
if(self.texture) |texture| {
|
||||||
|
texture.deinit();
|
||||||
|
}
|
||||||
|
self.image.deinit(main.globalAllocator);
|
||||||
main.globalAllocator.destroy(self);
|
main.globalAllocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,6 +976,14 @@ const Tool = struct {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getTexture(self: *Tool) !graphics.Texture {
|
||||||
|
if(self.texture == null) {
|
||||||
|
self.texture = graphics.Texture.init();
|
||||||
|
try self.texture.?.generate(self.image);
|
||||||
|
}
|
||||||
|
return self.texture.?;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getPowerByBlockClass(self: *Tool, blockClass: blocks.BlockClass) f32 {
|
pub fn getPowerByBlockClass(self: *Tool, blockClass: blocks.BlockClass) f32 {
|
||||||
return switch(blockClass) {
|
return switch(blockClass) {
|
||||||
.fluid => 0,
|
.fluid => 0,
|
||||||
@ -979,8 +1002,8 @@ const Tool = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Item = union(enum) {
|
pub const Item = union(enum) {
|
||||||
baseItem: *const BaseItem,
|
baseItem: *BaseItem,
|
||||||
tool: *const Tool,
|
tool: *Tool,
|
||||||
|
|
||||||
pub fn init(json: JsonElement) !Item {
|
pub fn init(json: JsonElement) !Item {
|
||||||
if(reverseIndices.get(json.get([]const u8, "item", "null"))) |baseItem| {
|
if(reverseIndices.get(json.get([]const u8, "item", "null"))) |baseItem| {
|
||||||
@ -1026,13 +1049,24 @@ pub const Item = union(enum) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTexture(self: Item) graphics.Image {
|
pub fn getTexture(self: Item) !graphics.Texture {
|
||||||
switch(self) {
|
switch(self) {
|
||||||
.baseItem => |_baseItem| {
|
.baseItem => |_baseItem| {
|
||||||
return _baseItem.texture;
|
return try _baseItem.getTexture();
|
||||||
},
|
},
|
||||||
.tool => |_tool| {
|
.tool => |_tool| {
|
||||||
return _tool.texture;
|
return try _tool.getTexture();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getImage(self: Item) graphics.Image {
|
||||||
|
switch(self) {
|
||||||
|
.baseItem => |_baseItem| {
|
||||||
|
return _baseItem.image;
|
||||||
|
},
|
||||||
|
.tool => |_tool| {
|
||||||
|
return _tool.image;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1256,7 +1290,7 @@ pub fn deinit() void {
|
|||||||
arena.deinit();
|
arena.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getByID(id: []const u8) ?*const BaseItem {
|
pub fn getByID(id: []const u8) ?*BaseItem {
|
||||||
if(reverseIndices.get(id)) |result| {
|
if(reverseIndices.get(id)) |result| {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user