mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Implement basic modifier restrictions with an example for diamond.
Still needs tooltips and item tags to be more useful
This commit is contained in:
parent
5f54d48a73
commit
4286455915
@ -14,6 +14,24 @@
|
||||
.{
|
||||
.id = "fragile",
|
||||
.strength = 0.5,
|
||||
.restriction = .{
|
||||
.id = .not,
|
||||
.child = .{
|
||||
.id = "or",
|
||||
.children = .{
|
||||
.{
|
||||
.id = .encased,
|
||||
.item = "cubyz:gold_ingot",
|
||||
.amount = 5,
|
||||
},
|
||||
.{
|
||||
.id = .encased,
|
||||
.item = "cubyz:silver_ingot",
|
||||
.amount = 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -17,6 +17,7 @@ const Vec3f = vec.Vec3f;
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
|
||||
const modifierList = @import("tool/modifiers/_list.zig");
|
||||
const modifierRestrictionList = @import("tool/modifiers/restrictions/_list.zig");
|
||||
|
||||
pub const Inventory = @import("Inventory.zig");
|
||||
|
||||
@ -54,12 +55,13 @@ const Material = struct { // MARK: Material
|
||||
for(modifiersZon.toSlice(), self.modifiers) |item, *modifier| {
|
||||
const id = item.get([]const u8, "id", "not specified");
|
||||
const vTable = modifiers.get(id) orelse blk: {
|
||||
std.log.err("Couldn't find modifier with id {s}. Replacing it with 'Durable'", .{id});
|
||||
std.log.err("Couldn't find modifier with id '{s}'. Replacing it with 'durable'", .{id});
|
||||
break :blk modifiers.get("durable") orelse unreachable;
|
||||
};
|
||||
modifier.* = .{
|
||||
.vTable = vTable,
|
||||
.data = vTable.loadData(item),
|
||||
.restriction = ModifierRestriction.loadFromZon(allocator, item.getChild("restriction")),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -83,8 +85,35 @@ const Material = struct { // MARK: Material
|
||||
}
|
||||
};
|
||||
|
||||
pub const ModifierRestriction = struct {
|
||||
vTable: *const VTable,
|
||||
data: *anyopaque,
|
||||
|
||||
pub const VTable = struct {
|
||||
satisfied: *const fn(data: *anyopaque, tool: *const Tool, x: i32, y: i32) bool,
|
||||
loadFromZon: *const fn(allocator: NeverFailingAllocator, zon: ZonElement) *anyopaque,
|
||||
};
|
||||
|
||||
pub fn satisfied(self: ModifierRestriction, tool: *const Tool, x: i32, y: i32) bool {
|
||||
return self.vTable.satisfied(self.data, tool, x, y);
|
||||
}
|
||||
|
||||
pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) ModifierRestriction {
|
||||
const id = zon.get([]const u8, "id", "always");
|
||||
const vTable = modifierRestrictions.get(id) orelse blk: {
|
||||
std.log.err("Couldn't find modifier restriction with id '{s}'. Replacing it with 'always'", .{id});
|
||||
break :blk modifierRestrictions.get("always") orelse unreachable;
|
||||
};
|
||||
return .{
|
||||
.vTable = vTable,
|
||||
.data = vTable.loadFromZon(allocator, zon),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const Modifier = struct {
|
||||
data: VTable.Data,
|
||||
restriction: ModifierRestriction,
|
||||
vTable: *const VTable,
|
||||
|
||||
pub const VTable = struct {
|
||||
@ -102,6 +131,7 @@ const Modifier = struct {
|
||||
return .{
|
||||
.data = a.vTable.combineModifiers(a.data, b.data) orelse return null,
|
||||
.vTable = a.vTable,
|
||||
.restriction = undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@ -319,6 +349,7 @@ const ToolPhysics = struct { // MARK: ToolPhysics
|
||||
tool.getProperty(set.destination).* += set.factor*set.functionType.eval(material.getProperty(set.source) + set.additionConstant);
|
||||
}
|
||||
outer: for(material.modifiers) |newMod| {
|
||||
if(!newMod.restriction.satisfied(tool, @intCast(i%5), @intCast(i/5))) continue;
|
||||
for(tempModifiers.items) |*oldMod| {
|
||||
if(oldMod.vTable == newMod.vTable) {
|
||||
oldMod.* = oldMod.combineModifiers(newMod) orelse continue;
|
||||
@ -537,6 +568,12 @@ pub const Tool = struct { // MARK: Tool
|
||||
return hash;
|
||||
}
|
||||
|
||||
pub fn getItemAt(self: *const Tool, x: i32, y: i32) ?*const BaseItem {
|
||||
if(x < 0 or x >= 5) return null;
|
||||
if(y < 0 or y >= 5) return null;
|
||||
return self.craftingGrid[@intCast(x + y*5)];
|
||||
}
|
||||
|
||||
fn getProperty(self: *Tool, prop: ToolProperty) *f32 {
|
||||
switch(prop) {
|
||||
inline else => |field| return &@field(self, @tagName(field)),
|
||||
@ -751,6 +788,7 @@ var arena: main.heap.NeverFailingArenaAllocator = undefined;
|
||||
var toolTypes: std.StringHashMap(ToolType) = undefined;
|
||||
var reverseIndices: std.StringHashMap(*BaseItem) = undefined;
|
||||
var modifiers: std.StringHashMap(*const Modifier.VTable) = undefined;
|
||||
var modifierRestrictions: std.StringHashMap(*const ModifierRestriction.VTable) = undefined;
|
||||
pub var itemList: [65536]BaseItem = undefined;
|
||||
pub var itemListSize: u16 = 0;
|
||||
|
||||
@ -790,6 +828,14 @@ pub fn globalInit() void {
|
||||
.priority = ModifierStruct.priority,
|
||||
}) catch unreachable;
|
||||
}
|
||||
modifierRestrictions = .init(main.globalAllocator.allocator);
|
||||
inline for(@typeInfo(modifierRestrictionList).@"struct".decls) |decl| {
|
||||
const ModifierRestrictionStruct = @field(modifierRestrictionList, decl.name);
|
||||
modifierRestrictions.put(decl.name, &.{
|
||||
.satisfied = comptime main.utils.castFunctionSelfToAnyopaque(ModifierRestrictionStruct.satisfied),
|
||||
.loadFromZon = comptime main.utils.castFunctionReturnToAnyopaque(ModifierRestrictionStruct.loadFromZon),
|
||||
}) catch unreachable;
|
||||
}
|
||||
Inventory.Sync.ClientSide.init();
|
||||
}
|
||||
|
||||
@ -952,6 +998,7 @@ pub fn deinit() void {
|
||||
}
|
||||
recipeList.clearAndFree();
|
||||
modifiers.deinit();
|
||||
modifierRestrictions.deinit();
|
||||
arena.deinit();
|
||||
Inventory.Sync.ClientSide.deinit();
|
||||
}
|
||||
|
5
src/tool/modifiers/restrictions/_list.zig
Normal file
5
src/tool/modifiers/restrictions/_list.zig
Normal file
@ -0,0 +1,5 @@
|
||||
pub const always = @import("always.zig");
|
||||
pub const @"and" = @import("and.zig");
|
||||
pub const encased = @import("encased.zig");
|
||||
pub const not = @import("not.zig");
|
||||
pub const @"or" = @import("or.zig");
|
14
src/tool/modifiers/restrictions/always.zig
Normal file
14
src/tool/modifiers/restrictions/always.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const Tool = main.items.Tool;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
pub fn satisfied(_: *const anyopaque, _: *const Tool, _: i32, _: i32) bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn loadFromZon(_: NeverFailingAllocator, _: ZonElement) *const anyopaque {
|
||||
return undefined;
|
||||
}
|
28
src/tool/modifiers/restrictions/and.zig
Normal file
28
src/tool/modifiers/restrictions/and.zig
Normal file
@ -0,0 +1,28 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const ModifierRestriction = main.items.ModifierRestriction;
|
||||
const Tool = main.items.Tool;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
const And = struct {
|
||||
children: []ModifierRestriction,
|
||||
};
|
||||
|
||||
pub fn satisfied(self: *const And, tool: *const Tool, x: i32, y: i32) bool {
|
||||
for(self.children) |child| {
|
||||
if(!child.satisfied(tool, x, y)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const And {
|
||||
const result = allocator.create(And);
|
||||
const childrenZon = zon.getChild("children").toSlice();
|
||||
result.children = allocator.alloc(ModifierRestriction, childrenZon.len);
|
||||
for(result.children, childrenZon) |*child, childZon| {
|
||||
child.* = ModifierRestriction.loadFromZon(allocator, childZon);
|
||||
}
|
||||
return result;
|
||||
}
|
32
src/tool/modifiers/restrictions/encased.zig
Normal file
32
src/tool/modifiers/restrictions/encased.zig
Normal file
@ -0,0 +1,32 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const ModifierRestriction = main.items.ModifierRestriction;
|
||||
const Tool = main.items.Tool;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
const Encased = struct {
|
||||
item: []const u8, // TODO: Use item tags instead
|
||||
amount: usize,
|
||||
};
|
||||
|
||||
pub fn satisfied(self: *const Encased, tool: *const Tool, x: i32, y: i32) bool {
|
||||
var count: usize = 0;
|
||||
for([_]i32{-1, 0, 1}) |dx| {
|
||||
for([_]i32{-1, 0, 1}) |dy| {
|
||||
if(std.mem.eql(u8, (tool.getItemAt(x + dx, y + dy) orelse continue).id, self.item)) count += 1;
|
||||
}
|
||||
}
|
||||
std.log.debug("{} {}", .{count, self.amount});
|
||||
return count >= self.amount;
|
||||
}
|
||||
|
||||
pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const Encased {
|
||||
const result = allocator.create(Encased);
|
||||
result.* = .{
|
||||
.item = zon.get([]const u8, "item", "not specified"),
|
||||
.amount = zon.get(usize, "amount", 8),
|
||||
};
|
||||
return result;
|
||||
}
|
23
src/tool/modifiers/restrictions/not.zig
Normal file
23
src/tool/modifiers/restrictions/not.zig
Normal file
@ -0,0 +1,23 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const ModifierRestriction = main.items.ModifierRestriction;
|
||||
const Tool = main.items.Tool;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
const Not = struct {
|
||||
child: ModifierRestriction,
|
||||
};
|
||||
|
||||
pub fn satisfied(self: *const Not, tool: *const Tool, x: i32, y: i32) bool {
|
||||
return !self.child.satisfied(tool, x, y);
|
||||
}
|
||||
|
||||
pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const Not {
|
||||
const result = allocator.create(Not);
|
||||
result.* = .{
|
||||
.child = ModifierRestriction.loadFromZon(allocator, zon.getChild("child")),
|
||||
};
|
||||
return result;
|
||||
}
|
28
src/tool/modifiers/restrictions/or.zig
Normal file
28
src/tool/modifiers/restrictions/or.zig
Normal file
@ -0,0 +1,28 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const ModifierRestriction = main.items.ModifierRestriction;
|
||||
const Tool = main.items.Tool;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
const Or = struct {
|
||||
children: []ModifierRestriction,
|
||||
};
|
||||
|
||||
pub fn satisfied(self: *const Or, tool: *const Tool, x: i32, y: i32) bool {
|
||||
for(self.children) |child| {
|
||||
if(child.satisfied(tool, x, y)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const Or {
|
||||
const result = allocator.create(Or);
|
||||
const childrenZon = zon.getChild("children").toSlice();
|
||||
result.children = allocator.alloc(ModifierRestriction, childrenZon.len);
|
||||
for(result.children, childrenZon) |*child, childZon| {
|
||||
child.* = ModifierRestriction.loadFromZon(allocator, childZon);
|
||||
}
|
||||
return result;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user