Add ToolTypeIndex struct (#1478)

## Description

This pull request adds `ToolTypeIndex` struct that behaves similarly to
`ModelIndex` and `BaseItemIndex` structs.

## Links

Related to: #1290 
Related to: #1060

---------

Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>
This commit is contained in:
Krzysztof Wiśniewski 2025-06-08 11:38:33 +02:00 committed by GitHub
parent cd4cd8e9b9
commit 9f0289551d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 91 additions and 49 deletions

View File

@ -15,6 +15,7 @@ const Vec3i = vec.Vec3i;
const ZonElement = main.ZonElement; const ZonElement = main.ZonElement;
const Neighbor = main.chunk.Neighbor; const Neighbor = main.chunk.Neighbor;
const BaseItemIndex = main.items.BaseItemIndex; const BaseItemIndex = main.items.BaseItemIndex;
const ToolTypeIndex = main.items.ToolTypeIndex;
const Gamemode = main.game.Gamemode; const Gamemode = main.game.Gamemode;
@ -1137,7 +1138,7 @@ pub const Command = struct { // MARK: Command
switch(self.inv.type) { switch(self.inv.type) {
.normal, .creative, .crafting => {}, .normal, .creative, .crafting => {},
.workbench => { .workbench => {
writer.writeSlice(self.inv.type.workbench.id); writer.writeSlice(self.inv.type.workbench.id());
}, },
} }
} }
@ -1180,7 +1181,7 @@ pub const Command = struct { // MARK: Command
}; };
const typ: Type = switch(typeEnum) { const typ: Type = switch(typeEnum) {
inline .normal, .creative, .crafting => |tag| tag, inline .normal, .creative, .crafting => |tag| tag,
.workbench => .{.workbench = main.items.getToolTypeByID(reader.remaining) orelse return error.Invalid}, .workbench => .{.workbench = ToolTypeIndex.fromId(reader.remaining) orelse return error.Invalid},
}; };
Sync.ServerSide.createInventory(user.?, id, len, typ, source); Sync.ServerSide.createInventory(user.?, id, len, typ, source);
return .{ return .{
@ -1231,7 +1232,7 @@ pub const Command = struct { // MARK: Command
cmd.tryCraftingTo(allocator, self.source, self.dest, side, user); cmd.tryCraftingTo(allocator, self.source, self.dest, side, user);
return; return;
} }
if(self.dest.inv.type == .workbench and self.dest.slot != 25 and self.dest.inv.type.workbench.slotInfos[self.dest.slot].disabled) return; if(self.dest.inv.type == .workbench and self.dest.slot != 25 and self.dest.inv.type.workbench.slotInfos()[self.dest.slot].disabled) return;
if(self.dest.inv.type == .workbench and self.dest.slot == 25) { if(self.dest.inv.type == .workbench and self.dest.slot == 25) {
if(self.source.ref().item == null and self.dest.ref().item != null) { if(self.source.ref().item == null and self.dest.ref().item != null) {
cmd.executeBaseOperation(allocator, .{.move = .{ cmd.executeBaseOperation(allocator, .{.move = .{
@ -1288,7 +1289,7 @@ pub const Command = struct { // MARK: Command
std.debug.assert(self.source.inv.type == .normal); std.debug.assert(self.source.inv.type == .normal);
if(self.dest.inv.type == .creative) return; if(self.dest.inv.type == .creative) return;
if(self.dest.inv.type == .crafting) return; if(self.dest.inv.type == .crafting) return;
if(self.dest.inv.type == .workbench and (self.dest.slot == 25 or self.dest.inv.type.workbench.slotInfos[self.dest.slot].disabled)) return; if(self.dest.inv.type == .workbench and (self.dest.slot == 25 or self.dest.inv.type.workbench.slotInfos()[self.dest.slot].disabled)) return;
if(self.dest.inv.type == .workbench and !canPutIntoWorkbench(self.source)) return; if(self.dest.inv.type == .workbench and !canPutIntoWorkbench(self.source)) return;
const itemSource = self.source.ref().item orelse return; const itemSource = self.source.ref().item orelse return;
if(self.dest.ref().item) |itemDest| { if(self.dest.ref().item) |itemDest| {
@ -1342,7 +1343,7 @@ pub const Command = struct { // MARK: Command
cmd.tryCraftingTo(allocator, self.dest, self.source, side, user); cmd.tryCraftingTo(allocator, self.dest, self.source, side, user);
return; return;
} }
if(self.source.inv.type == .workbench and self.source.slot != 25 and self.source.inv.type.workbench.slotInfos[self.source.slot].disabled) return; if(self.source.inv.type == .workbench and self.source.slot != 25 and self.source.inv.type.workbench.slotInfos()[self.source.slot].disabled) return;
if(self.source.inv.type == .workbench and self.source.slot == 25) { if(self.source.inv.type == .workbench and self.source.slot == 25) {
if(self.dest.ref().item == null and self.source.ref().item != null) { if(self.dest.ref().item == null and self.source.ref().item != null) {
cmd.executeBaseOperation(allocator, .{.move = .{ cmd.executeBaseOperation(allocator, .{.move = .{
@ -1413,7 +1414,7 @@ pub const Command = struct { // MARK: Command
} }
return; return;
} }
if(self.source.inv.type == .workbench and self.source.slot != 25 and self.source.inv.type.workbench.slotInfos[self.source.slot].disabled) return; if(self.source.inv.type == .workbench and self.source.slot != 25 and self.source.inv.type.workbench.slotInfos()[self.source.slot].disabled) return;
if(self.source.inv.type == .workbench and self.source.slot == 25) { if(self.source.inv.type == .workbench and self.source.slot == 25) {
cmd.removeToolCraftingIngredients(allocator, self.source.inv, side); cmd.removeToolCraftingIngredients(allocator, self.source.inv, side);
} }
@ -1449,7 +1450,7 @@ pub const Command = struct { // MARK: Command
amount: u16 = 0, amount: u16 = 0,
fn run(self: FillFromCreative, allocator: NeverFailingAllocator, cmd: *Command, side: Side, user: ?*main.server.User, mode: Gamemode) error{serverFailure}!void { fn run(self: FillFromCreative, allocator: NeverFailingAllocator, cmd: *Command, side: Side, user: ?*main.server.User, mode: Gamemode) error{serverFailure}!void {
if(self.dest.inv.type == .workbench and (self.dest.slot == 25 or self.dest.inv.type.workbench.slotInfos[self.dest.slot].disabled)) return; if(self.dest.inv.type == .workbench and (self.dest.slot == 25 or self.dest.inv.type.workbench.slotInfos()[self.dest.slot].disabled)) return;
if(side == .server and user != null and mode != .creative) return; if(side == .server and user != null and mode != .creative) return;
if(side == .client and mode != .creative) return; if(side == .client and mode != .creative) return;
@ -1847,7 +1848,7 @@ const Type = union(TypeEnum) {
normal: void, normal: void,
creative: void, creative: void,
crafting: void, crafting: void,
workbench: *const main.items.ToolType, workbench: ToolTypeIndex,
pub fn shouldDepositToUserOnClose(self: Type) bool { pub fn shouldDepositToUserOnClose(self: Type) bool {
return self == .workbench; return self == .workbench;
@ -1905,7 +1906,7 @@ fn update(self: Inventory) void {
self._items[self._items.len - 1].deinit(); self._items[self._items.len - 1].deinit();
self._items[self._items.len - 1].clear(); self._items[self._items.len - 1].clear();
var availableItems: [25]?BaseItemIndex = undefined; var availableItems: [25]?BaseItemIndex = undefined;
const slotInfos = self.type.workbench.slotInfos; const slotInfos = self.type.workbench.slotInfos();
for(0..25) |i| { for(0..25) |i| {
if(self._items[i].item != null and self._items[i].item.? == .baseItem) { if(self._items[i].item != null and self._items[i].item.? == .baseItem) {

View File

@ -6,6 +6,8 @@ const BaseItem = items.BaseItem;
const Inventory = items.Inventory; const Inventory = items.Inventory;
const Item = items.Item; const Item = items.Item;
const Tool = items.Tool; const Tool = items.Tool;
const ToolType = items.ToolType;
const ToolTypeIndex = items.ToolTypeIndex;
const Player = main.game.Player; const Player = main.game.Player;
const Texture = main.graphics.Texture; const Texture = main.graphics.Texture;
const Vec2f = main.vec.Vec2f; const Vec2f = main.vec.Vec2f;
@ -37,7 +39,7 @@ var inv: Inventory = undefined;
var itemSlots: [25]*ItemSlot = undefined; var itemSlots: [25]*ItemSlot = undefined;
var toolTypes: main.ListUnmanaged(*const main.items.ToolType) = .{}; var toolTypes: main.ListUnmanaged(ToolTypeIndex) = undefined;
var currentToolType: usize = 0; var currentToolType: usize = 0;
var toolButton: *Button = undefined; var toolButton: *Button = undefined;
@ -47,7 +49,7 @@ var needsUpdate: bool = false;
fn toggleTool(_: usize) void { fn toggleTool(_: usize) void {
currentToolType += 1; currentToolType += 1;
currentToolType %= toolTypes.items.len; currentToolType %= toolTypes.items.len;
toolButton.child.label.updateText(toolTypes.items[currentToolType].id); toolButton.child.label.updateText(toolTypes.items[currentToolType].id());
needsUpdate = true; needsUpdate = true;
} }
@ -61,7 +63,7 @@ fn openInventory() void {
const row = HorizontalList.init(); const row = HorizontalList.init();
for(0..5) |x| { for(0..5) |x| {
const index = x + y*5; const index = x + y*5;
const slotInfo = toolTypes.items[currentToolType].slotInfos[index]; const slotInfo = toolTypes.items[currentToolType].slotInfos()[index];
const slot = ItemSlot.init(.{0, 0}, inv, @intCast(index), if(slotInfo.disabled) .invisible else if(slotInfo.optional) .immutable else .default, if(slotInfo.disabled) .immutable else .normal); const slot = ItemSlot.init(.{0, 0}, inv, @intCast(index), if(slotInfo.disabled) .invisible else if(slotInfo.optional) .immutable else .default, if(slotInfo.disabled) .immutable else .normal);
itemSlots[index] = slot; itemSlots[index] = slot;
row.add(slot); row.add(slot);
@ -72,7 +74,7 @@ fn openInventory() void {
list.add(grid); list.add(grid);
} }
const verticalThing = VerticalList.init(.{0, 0}, 300, padding); const verticalThing = VerticalList.init(.{0, 0}, 300, padding);
toolButton = Button.initText(.{8, 0}, 116, toolTypes.items[currentToolType].id, .{.callback = &toggleTool}); toolButton = Button.initText(.{8, 0}, 116, toolTypes.items[currentToolType].id(), .{.callback = &toggleTool});
verticalThing.add(toolButton); verticalThing.add(toolButton);
const buttonHeight = verticalThing.size[1]; const buttonHeight = verticalThing.size[1];
const craftingResultList = HorizontalList.init(); const craftingResultList = HorizontalList.init();
@ -119,15 +121,17 @@ pub fn render() void {
pub fn onOpen() void { pub fn onOpen() void {
currentToolType = 0; currentToolType = 0;
var iterator = main.items.toolTypeIterator();
toolTypes = .{};
var iterator = ToolTypeIndex.iterator();
while(iterator.next()) |toolType| { while(iterator.next()) |toolType| {
toolTypes.append(main.globalAllocator, toolType); toolTypes.append(main.globalAllocator, toolType);
} }
openInventory(); openInventory();
} }
pub fn onClose() void { pub fn onClose() void {
toolTypes.deinit(main.globalAllocator);
closeInventory(); closeInventory();
toolTypes.clearAndFree(main.globalAllocator);
} }

View File

@ -16,6 +16,7 @@ const Vec2i = vec.Vec2i;
const Vec3i = vec.Vec3i; const Vec3i = vec.Vec3i;
const Vec3f = vec.Vec3f; const Vec3f = vec.Vec3f;
const NeverFailingAllocator = main.heap.NeverFailingAllocator; const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const ListUnmanaged = main.ListUnmanaged;
const modifierList = @import("tool/modifiers/_list.zig"); const modifierList = @import("tool/modifiers/_list.zig");
const modifierRestrictionList = @import("tool/modifiers/restrictions/_list.zig"); const modifierRestrictionList = @import("tool/modifiers/restrictions/_list.zig");
@ -340,8 +341,8 @@ const TextureGenerator = struct { // MARK: TextureGenerator
const img = tool.image; const img = tool.image;
for(0..16) |x| { for(0..16) |x| {
for(0..16) |y| { for(0..16) |y| {
const source = tool.type.pixelSources[x][y]; const source = tool.type.pixelSources()[x][y];
const sourceOverlay = tool.type.pixelSourcesOverlay[x][y]; const sourceOverlay = tool.type.pixelSourcesOverlay()[x][y];
if(sourceOverlay < 25 and tool.craftingGrid[sourceOverlay] != null) { if(sourceOverlay < 25 and tool.craftingGrid[sourceOverlay] != null) {
tool.materialGrid[x][y] = tool.craftingGrid[sourceOverlay]; tool.materialGrid[x][y] = tool.craftingGrid[sourceOverlay];
} else if(source < 25) { } else if(source < 25) {
@ -389,7 +390,7 @@ const ToolPhysics = struct { // MARK: ToolPhysics
} }
var tempModifiers: main.List(Modifier) = .init(main.stackAllocator); var tempModifiers: main.List(Modifier) = .init(main.stackAllocator);
defer tempModifiers.deinit(); defer tempModifiers.deinit();
for(tool.type.properties) |property| { for(tool.type.properties()) |property| {
var sum: f32 = 0; var sum: f32 = 0;
var weight: f32 = 0; var weight: f32 = 0;
for(0..25) |i| { for(0..25) |i| {
@ -504,6 +505,45 @@ const PropertyMatrix = struct { // MARK: PropertyMatrix
}; };
}; };
pub const ToolTypeIndex = packed struct {
index: u16,
const ToolTypeIterator = struct {
i: u16 = 0,
pub fn next(self: *ToolTypeIterator) ?ToolTypeIndex {
if(self.i >= toolTypeList.items.len) return null;
defer self.i += 1;
return ToolTypeIndex{.index = self.i};
}
};
pub fn iterator() ToolTypeIterator {
return .{};
}
pub fn fromId(_id: []const u8) ?ToolTypeIndex {
return toolTypeIdToIndex.get(_id);
}
pub fn id(self: ToolTypeIndex) []const u8 {
return toolTypeList.items[self.index].id;
}
pub fn blockTags(self: ToolTypeIndex) []const Tag {
return toolTypeList.items[self.index].blockTags;
}
pub fn properties(self: ToolTypeIndex) []const PropertyMatrix {
return toolTypeList.items[self.index].properties;
}
pub fn slotInfos(self: ToolTypeIndex) *const [25]SlotInfo {
return &toolTypeList.items[self.index].slotInfos;
}
pub fn pixelSources(self: ToolTypeIndex) *const [16][16]u8 {
return &toolTypeList.items[self.index].pixelSources;
}
pub fn pixelSourcesOverlay(self: ToolTypeIndex) *const [16][16]u8 {
return &toolTypeList.items[self.index].pixelSourcesOverlay;
}
};
pub const ToolType = struct { // MARK: ToolType pub const ToolType = struct { // MARK: ToolType
id: []const u8, id: []const u8,
blockTags: []main.Tag, blockTags: []main.Tag,
@ -534,7 +574,7 @@ pub const Tool = struct { // MARK: Tool
image: graphics.Image, image: graphics.Image,
texture: ?graphics.Texture, texture: ?graphics.Texture,
seed: u32, seed: u32,
type: *const ToolType, type: ToolTypeIndex,
damage: f32, damage: f32,
@ -600,7 +640,7 @@ pub const Tool = struct { // MARK: Tool
return result; return result;
} }
pub fn initFromCraftingGrid(craftingGrid: [25]?BaseItemIndex, seed: u32, typ: *const ToolType) *Tool { pub fn initFromCraftingGrid(craftingGrid: [25]?BaseItemIndex, seed: u32, typ: ToolTypeIndex) *Tool {
const self = init(); const self = init();
self.seed = seed; self.seed = seed;
self.craftingGrid = craftingGrid; self.craftingGrid = craftingGrid;
@ -613,9 +653,9 @@ pub const Tool = struct { // MARK: Tool
} }
pub fn initFromZon(zon: ZonElement) *Tool { pub fn initFromZon(zon: ZonElement) *Tool {
const self = initFromCraftingGrid(extractItemsFromZon(zon.getChild("grid")), zon.get(u32, "seed", 0), getToolTypeByID(zon.get([]const u8, "type", "cubyz:pickaxe")) orelse blk: { const self = initFromCraftingGrid(extractItemsFromZon(zon.getChild("grid")), zon.get(u32, "seed", 0), ToolTypeIndex.fromId(zon.get([]const u8, "type", "cubyz:pickaxe")) orelse blk: {
std.log.err("Couldn't find tool with type {s}. Replacing it with cubyz:pickaxe", .{zon.get([]const u8, "type", "cubyz:pickaxe")}); std.log.err("Couldn't find tool with type {s}. Replacing it with cubyz:pickaxe", .{zon.get([]const u8, "type", "cubyz:pickaxe")});
break :blk getToolTypeByID("cubyz:pickaxe") orelse @panic("cubyz:pickaxe tool not found. Did you load the game with the correct assets?"); break :blk ToolTypeIndex.fromId("cubyz:pickaxe") orelse @panic("cubyz:pickaxe tool not found. Did you load the game with the correct assets?");
}); });
self.durability = zon.get(u32, "durability", std.math.lossyCast(u32, self.maxDurability)); self.durability = zon.get(u32, "durability", std.math.lossyCast(u32, self.maxDurability));
return self; return self;
@ -643,7 +683,7 @@ pub const Tool = struct { // MARK: Tool
zonObject.put("grid", zonArray); zonObject.put("grid", zonArray);
zonObject.put("durability", self.durability); zonObject.put("durability", self.durability);
zonObject.put("seed", self.seed); zonObject.put("seed", self.seed);
zonObject.put("type", self.type.id); zonObject.put("type", self.type.id());
return zonObject; return zonObject;
} }
@ -685,7 +725,7 @@ pub const Tool = struct { // MARK: Tool
\\Damage: {d:.2} \\Damage: {d:.2}
\\Durability: {}/{} \\Durability: {}/{}
, .{ , .{
self.type.id, self.type.id(),
self.swingTime, self.swingTime,
self.damage, self.damage,
self.durability, self.durability,
@ -708,7 +748,7 @@ pub const Tool = struct { // MARK: Tool
damage = modifier.changeBlockDamage(damage, block); damage = modifier.changeBlockDamage(damage, block);
} }
for(block.blockTags()) |blockTag| { for(block.blockTags()) |blockTag| {
for(self.type.blockTags) |toolTag| { for(self.type.blockTags()) |toolTag| {
if(toolTag == blockTag) return damage; if(toolTag == blockTag) return damage;
} }
} }
@ -874,7 +914,10 @@ pub const Recipe = struct { // MARK: Recipe
}; };
var arena: main.heap.NeverFailingArenaAllocator = undefined; var arena: main.heap.NeverFailingArenaAllocator = undefined;
var toolTypes: std.StringHashMap(ToolType) = undefined;
var toolTypeList: ListUnmanaged(ToolType) = undefined;
var toolTypeIdToIndex: std.StringHashMapUnmanaged(ToolTypeIndex) = undefined;
var reverseIndices: std.StringHashMap(BaseItemIndex) = undefined; var reverseIndices: std.StringHashMap(BaseItemIndex) = undefined;
var modifiers: std.StringHashMap(*const Modifier.VTable) = undefined; var modifiers: std.StringHashMap(*const Modifier.VTable) = undefined;
var modifierRestrictions: std.StringHashMap(*const ModifierRestriction.VTable) = undefined; var modifierRestrictions: std.StringHashMap(*const ModifierRestriction.VTable) = undefined;
@ -888,11 +931,7 @@ pub fn hasRegistered(id: []const u8) bool {
} }
pub fn hasRegisteredTool(id: []const u8) bool { pub fn hasRegisteredTool(id: []const u8) bool {
return toolTypes.contains(id); return toolTypeIdToIndex.contains(id);
}
pub fn toolTypeIterator() std.StringHashMap(ToolType).ValueIterator {
return toolTypes.valueIterator();
} }
pub fn iterator() std.StringHashMap(BaseItemIndex).ValueIterator { pub fn iterator() std.StringHashMap(BaseItemIndex).ValueIterator {
@ -905,7 +944,10 @@ pub fn recipes() []Recipe {
pub fn globalInit() void { pub fn globalInit() void {
arena = .init(main.globalAllocator); arena = .init(main.globalAllocator);
toolTypes = .init(arena.allocator().allocator);
toolTypeList = .{};
toolTypeIdToIndex = .{};
reverseIndices = .init(arena.allocator().allocator); reverseIndices = .init(arena.allocator().allocator);
recipeList = .init(arena.allocator()); recipeList = .init(arena.allocator());
itemListSize = 0; itemListSize = 0;
@ -982,7 +1024,7 @@ fn loadPixelSources(assetFolder: []const u8, id: []const u8, layerPostfix: []con
} }
pub fn registerTool(assetFolder: []const u8, id: []const u8, zon: ZonElement) void { pub fn registerTool(assetFolder: []const u8, id: []const u8, zon: ZonElement) void {
if(toolTypes.contains(id)) { if(toolTypeIdToIndex.contains(id)) {
std.log.err("Registered tool type with id {s} twice!", .{id}); std.log.err("Registered tool type with id {s} twice!", .{id});
} }
var slotInfos: [25]SlotInfo = @splat(.{}); var slotInfos: [25]SlotInfo = @splat(.{});
@ -1000,9 +1042,9 @@ pub fn registerTool(assetFolder: []const u8, id: []const u8, zon: ZonElement) vo
} }
slotInfos[i].optional = zonDisabled.as(usize, 0) != 0; slotInfos[i].optional = zonDisabled.as(usize, 0) != 0;
} }
var parameterMatrics: main.List(PropertyMatrix) = .init(arena.allocator()); var parameterMatrices: main.List(PropertyMatrix) = .init(arena.allocator());
for(zon.getChild("parameters").toSlice()) |paramZon| { for(zon.getChild("parameters").toSlice()) |paramZon| {
const val = parameterMatrics.addOne(); const val = parameterMatrices.addOne();
val.source = MaterialProperty.fromString(paramZon.get([]const u8, "source", "not specified")); val.source = MaterialProperty.fromString(paramZon.get([]const u8, "source", "not specified"));
val.destination = ToolProperty.fromString(paramZon.get([]const u8, "destination", "not specified")); val.destination = ToolProperty.fromString(paramZon.get([]const u8, "destination", "not specified"));
val.resultScale = paramZon.get(f32, "factor", 1.0); val.resultScale = paramZon.get(f32, "factor", 1.0);
@ -1016,15 +1058,17 @@ pub fn registerTool(assetFolder: []const u8, id: []const u8, zon: ZonElement) vo
loadPixelSources(assetFolder, id, "", &pixelSources); loadPixelSources(assetFolder, id, "", &pixelSources);
var pixelSourcesOverlay: [16][16]u8 = undefined; var pixelSourcesOverlay: [16][16]u8 = undefined;
loadPixelSources(assetFolder, id, "_overlay", &pixelSourcesOverlay); loadPixelSources(assetFolder, id, "_overlay", &pixelSourcesOverlay);
const idDupe = arena.allocator().dupe(u8, id); const idDupe = arena.allocator().dupe(u8, id);
toolTypes.put(idDupe, .{ toolTypeList.append(arena.allocator(), .{
.id = idDupe, .id = idDupe,
.blockTags = Tag.loadTagsFromZon(arena.allocator(), zon.getChild("blockTags")), .blockTags = Tag.loadTagsFromZon(arena.allocator(), zon.getChild("blockTags")),
.slotInfos = slotInfos, .slotInfos = slotInfos,
.properties = parameterMatrics.toOwnedSlice(), .properties = parameterMatrices.toOwnedSlice(),
.pixelSources = pixelSources, .pixelSources = pixelSources,
.pixelSourcesOverlay = pixelSourcesOverlay, .pixelSourcesOverlay = pixelSourcesOverlay,
}) catch unreachable; });
toolTypeIdToIndex.put(arena.allocator().allocator, idDupe, .{.index = @intCast(toolTypeList.items.len - 1)}) catch unreachable;
std.log.debug("Registered tool: '{s}'", .{id}); std.log.debug("Registered tool: '{s}'", .{id});
} }
@ -1071,7 +1115,8 @@ pub fn registerRecipes(zon: ZonElement) void {
} }
pub fn reset() void { pub fn reset() void {
toolTypes.clearAndFree(); toolTypeList.clearAndFree(arena.allocator());
toolTypeIdToIndex.clearAndFree(arena.allocator().allocator);
reverseIndices.clearAndFree(); reverseIndices.clearAndFree();
for(recipeList.items) |recipe| { for(recipeList.items) |recipe| {
if(recipe.cachedInventory) |inv| { if(recipe.cachedInventory) |inv| {
@ -1084,7 +1129,8 @@ pub fn reset() void {
} }
pub fn deinit() void { pub fn deinit() void {
toolTypes.clearAndFree(); toolTypeList.deinit(arena.allocator());
toolTypeIdToIndex.deinit(arena.allocator().allocator);
reverseIndices.clearAndFree(); reverseIndices.clearAndFree();
for(recipeList.items) |recipe| { for(recipeList.items) |recipe| {
if(recipe.cachedInventory) |inv| { if(recipe.cachedInventory) |inv| {
@ -1097,12 +1143,3 @@ pub fn deinit() void {
arena.deinit(); arena.deinit();
Inventory.Sync.ClientSide.deinit(); Inventory.Sync.ClientSide.deinit();
} }
pub fn getToolTypeByID(id: []const u8) ?*const ToolType {
if(toolTypes.getPtr(id)) |result| {
return result;
} else {
std.log.err("Couldn't find item {s}.", .{id});
return null;
}
}