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",
|
.id = "fragile",
|
||||||
.strength = 0.5,
|
.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 NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||||
|
|
||||||
const modifierList = @import("tool/modifiers/_list.zig");
|
const modifierList = @import("tool/modifiers/_list.zig");
|
||||||
|
const modifierRestrictionList = @import("tool/modifiers/restrictions/_list.zig");
|
||||||
|
|
||||||
pub const Inventory = @import("Inventory.zig");
|
pub const Inventory = @import("Inventory.zig");
|
||||||
|
|
||||||
@ -54,12 +55,13 @@ const Material = struct { // MARK: Material
|
|||||||
for(modifiersZon.toSlice(), self.modifiers) |item, *modifier| {
|
for(modifiersZon.toSlice(), self.modifiers) |item, *modifier| {
|
||||||
const id = item.get([]const u8, "id", "not specified");
|
const id = item.get([]const u8, "id", "not specified");
|
||||||
const vTable = modifiers.get(id) orelse blk: {
|
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;
|
break :blk modifiers.get("durable") orelse unreachable;
|
||||||
};
|
};
|
||||||
modifier.* = .{
|
modifier.* = .{
|
||||||
.vTable = vTable,
|
.vTable = vTable,
|
||||||
.data = vTable.loadData(item),
|
.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 {
|
const Modifier = struct {
|
||||||
data: VTable.Data,
|
data: VTable.Data,
|
||||||
|
restriction: ModifierRestriction,
|
||||||
vTable: *const VTable,
|
vTable: *const VTable,
|
||||||
|
|
||||||
pub const VTable = struct {
|
pub const VTable = struct {
|
||||||
@ -102,6 +131,7 @@ const Modifier = struct {
|
|||||||
return .{
|
return .{
|
||||||
.data = a.vTable.combineModifiers(a.data, b.data) orelse return null,
|
.data = a.vTable.combineModifiers(a.data, b.data) orelse return null,
|
||||||
.vTable = a.vTable,
|
.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);
|
tool.getProperty(set.destination).* += set.factor*set.functionType.eval(material.getProperty(set.source) + set.additionConstant);
|
||||||
}
|
}
|
||||||
outer: for(material.modifiers) |newMod| {
|
outer: for(material.modifiers) |newMod| {
|
||||||
|
if(!newMod.restriction.satisfied(tool, @intCast(i%5), @intCast(i/5))) continue;
|
||||||
for(tempModifiers.items) |*oldMod| {
|
for(tempModifiers.items) |*oldMod| {
|
||||||
if(oldMod.vTable == newMod.vTable) {
|
if(oldMod.vTable == newMod.vTable) {
|
||||||
oldMod.* = oldMod.combineModifiers(newMod) orelse continue;
|
oldMod.* = oldMod.combineModifiers(newMod) orelse continue;
|
||||||
@ -537,6 +568,12 @@ pub const Tool = struct { // MARK: Tool
|
|||||||
return hash;
|
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 {
|
fn getProperty(self: *Tool, prop: ToolProperty) *f32 {
|
||||||
switch(prop) {
|
switch(prop) {
|
||||||
inline else => |field| return &@field(self, @tagName(field)),
|
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 toolTypes: std.StringHashMap(ToolType) = undefined;
|
||||||
var reverseIndices: std.StringHashMap(*BaseItem) = undefined;
|
var reverseIndices: std.StringHashMap(*BaseItem) = 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;
|
||||||
pub var itemList: [65536]BaseItem = undefined;
|
pub var itemList: [65536]BaseItem = undefined;
|
||||||
pub var itemListSize: u16 = 0;
|
pub var itemListSize: u16 = 0;
|
||||||
|
|
||||||
@ -790,6 +828,14 @@ pub fn globalInit() void {
|
|||||||
.priority = ModifierStruct.priority,
|
.priority = ModifierStruct.priority,
|
||||||
}) catch unreachable;
|
}) 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();
|
Inventory.Sync.ClientSide.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,6 +998,7 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
recipeList.clearAndFree();
|
recipeList.clearAndFree();
|
||||||
modifiers.deinit();
|
modifiers.deinit();
|
||||||
|
modifierRestrictions.deinit();
|
||||||
arena.deinit();
|
arena.deinit();
|
||||||
Inventory.Sync.ClientSide.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