Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions assets/cubyz/blocks/diamond_ore.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@
.id = "powerful",
.strength = 0.5,
.restriction = .{
.id = .encased,
.tag = .precious,
.amount = 4,
.id = .for_each,
.child = .{
.id = .encased,
.tag = .precious,
.amount = 4,
},
},
},
},
Expand Down
45 changes: 31 additions & 14 deletions src/items.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const Material = struct { // MARK: Material
.vTable = vTable,
.data = vTable.loadData(item),
.restriction = ModifierRestriction.loadFromZon(allocator, item.getChild("restriction")),
.restrictionPower = 1,
};
}
}
Expand Down Expand Up @@ -107,6 +108,11 @@ const Material = struct { // MARK: Material
if (modifier.restriction.vTable == modifierRestrictions.get("always").?) {
modifier.printTooltip(outString);
outString.appendSlice("\n");
} else if (modifier.restriction.vTable == modifierRestrictions.get("for_each").?) {
modifier.restriction.printTooltip(outString);
outString.appendSlice("\n ");
modifier.printTooltip(outString);
outString.appendSlice("\n");
} else {
outString.appendSlice("§#808080if ");
modifier.restriction.printTooltip(outString);
Expand All @@ -118,17 +124,24 @@ const Material = struct { // MARK: Material
}
};

pub const ModifierRestrictionOutput = struct {
ifSatisfied: bool,
totalItemsChecked: usize,
totalCountedItems: usize,
modifierPower: f32,
};

pub const ModifierRestriction = struct {
vTable: *const VTable,
data: *anyopaque,

pub const VTable = struct {
satisfied: *const fn (data: *anyopaque, proceduralItem: *const ProceduralItem, x: i32, y: i32) bool,
satisfied: *const fn (data: *anyopaque, proceduralItem: *const ProceduralItem, x: i32, y: i32) ModifierRestrictionOutput,
loadFromZon: *const fn (allocator: NeverFailingAllocator, zon: ZonElement) *anyopaque,
printTooltip: *const fn (data: *anyopaque, outString: *main.ListManaged(u8)) void,
};

pub fn satisfied(self: ModifierRestriction, proceduralItem: *const ProceduralItem, x: i32, y: i32) bool {
pub fn satisfied(self: ModifierRestriction, proceduralItem: *const ProceduralItem, x: i32, y: i32) ModifierRestrictionOutput {
return self.vTable.satisfied(self.data, proceduralItem, x, y);
}

Expand All @@ -153,19 +166,20 @@ const Modifier = struct {
data: VTable.Data,
restriction: ModifierRestriction,
vTable: *const VTable,
restrictionPower: f32,

pub const VTable = struct {
const Data = packed struct(u128) { pad: u128 };
combineModifiers: *const fn (data1: Data, data2: Data) ?Data,
changeProceduralItemParameters: *const fn (proceduralItem: *ProceduralItem, data: Data) void,
changeBlockDamage: *const fn (damage: f32, block: Block, data: Data) f32,
printTooltip: *const fn (outString: *main.ListManaged(u8), data: Data) void,
changeProceduralItemParameters: *const fn (proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void,
changeBlockDamage: *const fn (damage: f32, block: Block, data: Data, restrictionPower: f32) f32,
printTooltip: *const fn (outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void,
loadData: *const fn (zon: ZonElement) Data,
priority: f32,

const Defaults = struct {
pub fn changeProceduralItemParameters(_: *ProceduralItem, _: Data) void {}
pub fn changeBlockDamage(damage: f32, _: Block, _: Data) f32 {
pub fn changeProceduralItemParameters(_: *ProceduralItem, _: Data, _: f32) void {}
pub fn changeBlockDamage(damage: f32, _: Block, _: Data, _: f32) f32 {
return damage;
}
};
Expand All @@ -188,19 +202,20 @@ const Modifier = struct {
.data = a.vTable.combineModifiers(a.data, b.data) orelse return null,
.vTable = a.vTable,
.restriction = undefined,
.restrictionPower = std.math.hypot(a.restrictionPower, b.restrictionPower),
};
}

pub fn changeProceduralItemParameters(self: Modifier, proceduralItem: *ProceduralItem) void {
self.vTable.changeProceduralItemParameters(proceduralItem, self.data);
self.vTable.changeProceduralItemParameters(proceduralItem, self.data, self.restrictionPower);
}

pub fn changeBlockDamage(self: Modifier, damage: f32, block: Block) f32 {
return self.vTable.changeBlockDamage(damage, block, self.data);
return self.vTable.changeBlockDamage(damage, block, self.data, self.restrictionPower);
}

pub fn printTooltip(self: Modifier, outString: *main.ListManaged(u8)) void {
self.vTable.printTooltip(outString, self.data);
self.vTable.printTooltip(outString, self.data, self.restrictionPower);
}
};

Expand Down Expand Up @@ -484,15 +499,17 @@ const ProceduralItemPhysics = struct { // MARK: ProceduralItemPhysics
if (proceduralItem.getProperty(.swingSpeed) < 1) proceduralItem.setProperty(.swingSpeed, 1/(2 - proceduralItem.getProperty(.swingSpeed)));
for (0..25) |i| {
const material = (proceduralItem.craftingGrid[i] orelse continue).material() orelse continue;
outer: for (material.modifiers) |newMod| {
if (!newMod.restriction.satisfied(proceduralItem, @intCast(i%5), @intCast(i/5))) continue;
outer: for (material.modifiers) |*newMod| {
const checkedRestrictionValues = newMod.restriction.satisfied(proceduralItem, @intCast(i%5), @intCast(i/5));
if (!checkedRestrictionValues.ifSatisfied) continue;
for (tempModifiers.items) |*oldMod| {
if (oldMod.vTable == newMod.vTable) {
oldMod.* = oldMod.combineModifiers(newMod) orelse continue;
oldMod.* = oldMod.combineModifiers(newMod.*) orelse continue;
continue :outer;
}
}
tempModifiers.append(main.stackAllocator, newMod);
newMod.restrictionPower = checkedRestrictionValues.modifierPower;
tempModifiers.append(main.stackAllocator, newMod.*);
}
}
std.sort.insertion(Modifier, tempModifiers.items, {}, struct {
Expand Down
4 changes: 2 additions & 2 deletions src/proceduralItem/modifiers/bad_at.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1.0 - 1.0/(1.0 + std.math.hypot(1.0/(1.0 - data1.strength) - 1.0, 1.0/(1.0 - data2.strength) - 1.0)), .tag = data1.tag};
}

pub fn changeBlockDamage(damage: f32, block: main.blocks.Block, data: Data) f32 {
pub fn changeBlockDamage(damage: f32, block: main.blocks.Block, data: Data, restrictionPower: f32) f32 {
for (block.tags()) |tag| {
if (tag == data.tag) return damage*(1 - data.strength);
if (tag == data.tag) return damage*(1 - @min(data.strength*restrictionPower, 0));
}
return damage;
}
Expand Down
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/durable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = std.math.hypot(data1.strength, data2.strength)};
}

pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data) void {
proceduralItem.setProperty(.maxDurability, proceduralItem.getProperty(.maxDurability)*(1 + data.strength));
pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void {
proceduralItem.setProperty(.maxDurability, proceduralItem.getProperty(.maxDurability)*(1 + data.strength*restrictionPower));
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#500090**Durable**#808080 *Increases durability by **{d:.0}%", .{data.strength*100});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#500090**Durable**#808080 *Increases durability by **{d:.0}%", .{data.strength*100*restrictionPower});
}
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/fragile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1.0 - 1.0/(1.0 + std.math.hypot(1.0/(1.0 - data1.strength) - 1.0, 1.0/(1.0 - data2.strength) - 1.0))};
}

pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data) void {
proceduralItem.setProperty(.maxDurability, proceduralItem.getProperty(.maxDurability)*(1 - data.strength));
pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void {
proceduralItem.setProperty(.maxDurability, proceduralItem.getProperty(.maxDurability)*(1 - @min(data.strength*restrictionPower, 0)));
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#ccddff**Fragile**#808080 *Decreases durability by **{d:.0}%", .{data.strength*100});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#ccddff**Fragile**#808080 *Decreases durability by **{d:.0}%", .{@min(data.strength*100*restrictionPower, 100)});
}
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/good_at.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = std.math.hypot(data1.strength, data2.strength), .tag = data1.tag};
}

pub fn changeBlockDamage(damage: f32, block: main.blocks.Block, data: Data) f32 {
pub fn changeBlockDamage(damage: f32, block: main.blocks.Block, data: Data, restrictionPower: f32) f32 {
for (block.tags()) |tag| {
if (tag == data.tag) return damage*(1 + data.strength);
if (tag == data.tag) return damage*(1 + data.strength*restrictionPower);
}
return damage;
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#80ff40**Good at**#808080 *Increases damage by **{d:.0}%** on \n***#80ff40{s}#808080*** blocks", .{data.strength*100, data.tag.getName()});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#80ff40**Good at**#808080 *Increases damage by **{d:.0}%** on \n***#80ff40{s}#808080*** blocks", .{data.strength*100*restrictionPower, data.tag.getName()});
}
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/heavy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1.0 - 1.0/(1.0 + std.math.hypot(1.0/(1.0 - data1.strength) - 1.0, 1.0/(1.0 - data2.strength) - 1.0))};
}

pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data) void {
proceduralItem.setProperty(.swingSpeed, proceduralItem.getProperty(.swingSpeed)*(1 - data.strength));
pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void {
proceduralItem.setProperty(.swingSpeed, proceduralItem.getProperty(.swingSpeed)*(1 - @min(data.strength*restrictionPower, 0)));
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#ffcc30**Heavy**#808080 *Decreases swing speed by **{d:.0}%", .{data.strength*100});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#ffcc30**Heavy**#808080 *Decreases swing speed by **{d:.0}%", .{@min(data.strength*100*restrictionPower, 100)});
}
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/light.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = std.math.hypot(data1.strength, data2.strength)};
}

pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data) void {
proceduralItem.setProperty(.swingSpeed, proceduralItem.getProperty(.swingSpeed)*(1 + data.strength));
pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void {
proceduralItem.setProperty(.swingSpeed, proceduralItem.getProperty(.swingSpeed)*(1 + data.strength*restrictionPower));
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#9fffde**Light**#808080 *Increases swing speed by **{d:.0}%", .{data.strength*100});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#9fffde**Light**#808080 *Increases swing speed by **{d:.0}%", .{data.strength*100*restrictionPower});
}
8 changes: 4 additions & 4 deletions src/proceduralItem/modifiers/powerful.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = std.math.hypot(data1.strength, data2.strength)};
}

pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data) void {
proceduralItem.setProperty(.damage, proceduralItem.getProperty(.damage)*(1 + data.strength));
pub fn changeProceduralItemParameters(proceduralItem: *ProceduralItem, data: Data, restrictionPower: f32) void {
proceduralItem.setProperty(.damage, proceduralItem.getProperty(.damage)*(1 + data.strength*restrictionPower));
}

pub fn printTooltip(outString: *main.ListManaged(u8), data: Data) void {
outString.print("#f84a00**Powerful**#808080 *Increases damage by **{d:.0}%", .{data.strength*100});
pub fn printTooltip(outString: *main.ListManaged(u8), data: Data, restrictionPower: f32) void {
outString.print("#f84a00**Powerful**#808080 *Increases damage by **{d:.0}%", .{data.strength*100*restrictionPower});
}
1 change: 1 addition & 0 deletions src/proceduralItem/modifiers/restrictions/_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub const @"and" = @import("and.zig");
pub const encased = @import("encased.zig");
pub const not = @import("not.zig");
pub const @"or" = @import("or.zig");
pub const for_each = @import("for_each.zig");
10 changes: 8 additions & 2 deletions src/proceduralItem/modifiers/restrictions/always.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ const main = @import("main");
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const ProceduralItem = main.items.ProceduralItem;
const ZonElement = main.ZonElement;
const ModifierRestrictionOutput = main.items.ModifierRestrictionOutput;

pub fn satisfied(_: *const anyopaque, _: *const ProceduralItem, _: i32, _: i32) bool {
return true;
pub fn satisfied(_: *const anyopaque, _: *const ProceduralItem, _: i32, _: i32) ModifierRestrictionOutput {
return .{
.ifSatisfied = true,
.totalItemsChecked = 0,
.totalCountedItems = 0,
.modifierPower = 1,
};
}

pub fn loadFromZon(_: NeverFailingAllocator, _: ZonElement) *const anyopaque {
Expand Down
20 changes: 17 additions & 3 deletions src/proceduralItem/modifiers/restrictions/and.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,30 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const ModifierRestriction = main.items.ModifierRestriction;
const ProceduralItem = main.items.ProceduralItem;
const ZonElement = main.ZonElement;
const ModifierRestrictionOutput = main.items.ModifierRestrictionOutput;

const And = struct {
children: []ModifierRestriction,
};

pub fn satisfied(self: *const And, proceduralItem: *const ProceduralItem, x: i32, y: i32) bool {
pub fn satisfied(self: *const And, proceduralItem: *const ProceduralItem, x: i32, y: i32) ModifierRestrictionOutput {
var combinedIsSatisfied = true;
var combinedtotalCountedItems: usize = 0;
var combinedTotalItemsChecked: usize = 0;
var combinedModifierPower: f32 = 0;
for (self.children) |child| {
if (!child.satisfied(proceduralItem, x, y)) return false;
const childValues: ModifierRestrictionOutput = child.satisfied(proceduralItem, x, y);
if (!childValues.ifSatisfied) combinedIsSatisfied = false;
combinedtotalCountedItems += childValues.totalCountedItems;
combinedTotalItemsChecked += childValues.totalItemsChecked;
combinedModifierPower = std.math.hypot(combinedModifierPower, childValues.modifierPower);
}
return true;
return .{
.ifSatisfied = combinedIsSatisfied,
.totalItemsChecked = combinedTotalItemsChecked,
.totalCountedItems = combinedtotalCountedItems,
.modifierPower = combinedModifierPower,
};
}

pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const And {
Expand Down
18 changes: 14 additions & 4 deletions src/proceduralItem/modifiers/restrictions/encased.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@ const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const ModifierRestriction = main.items.ModifierRestriction;
const ProceduralItem = main.items.ProceduralItem;
const ZonElement = main.ZonElement;
const ModifierRestrictionOutput = main.items.ModifierRestrictionOutput;

const Encased = struct {
tag: main.Tag,
amount: usize,
};

pub fn satisfied(self: *const Encased, proceduralItem: *const ProceduralItem, x: i32, y: i32) bool {
pub fn satisfied(self: *const Encased, proceduralItem: *const ProceduralItem, x: i32, y: i32) ModifierRestrictionOutput {
var count: usize = 0;
for ([_]i32{-1, 0, 1}) |dx| {
for ([_]i32{-1, 0, 1}) |dy| {
if ((proceduralItem.getItemAt(x + dx, y + dy) orelse continue).hasTag(self.tag)) count += 1;
}
}
return count >= self.amount;
return .{
.ifSatisfied = count >= self.amount,
.totalItemsChecked = 9,
.totalCountedItems = count,
.modifierPower = 1,
};
}

pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const Encased {
Expand All @@ -28,11 +34,15 @@ pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const Enc
std.log.err("Missing tag field for encased restriction.", .{});
break :blk "not specified";
}),
.amount = zon.get(usize, "amount") orelse 8,
.amount = zon.get(usize, "amount") orelse 0,
};
return result;
}

pub fn printTooltip(self: *const Encased, outString: *main.ListManaged(u8)) void {
outString.print("encased in {} .{s}", .{self.amount, self.tag.getName()});
if (self.amount == 0) {
outString.print("encased in .{s}", .{self.tag.getName()});
} else {
outString.print("encased in {} .{s}", .{self.amount, self.tag.getName()});
}
}
43 changes: 43 additions & 0 deletions src/proceduralItem/modifiers/restrictions/for_each.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const std = @import("std");

const main = @import("main");
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const ModifierRestriction = main.items.ModifierRestriction;
const ProceduralItem = main.items.ProceduralItem;
const ZonElement = main.ZonElement;
const ModifierRestrictionOutput = main.items.ModifierRestrictionOutput;

const ForEach = struct {
child: ModifierRestriction,
};

pub fn satisfied(self: *const ForEach, proceduralItem: *const ProceduralItem, x: i32, y: i32) ModifierRestrictionOutput {
const childValues = self.child.satisfied(proceduralItem, x, y);
const loopCount = childValues.totalCountedItems;
var combinedModifierPower: f32 = 0;
std.log.debug("loop count {}", .{loopCount});
for (0..loopCount) |i| {
_ = i;
combinedModifierPower = std.math.hypot(combinedModifierPower, 1);
}
std.log.debug("restrictionPower {}", .{combinedModifierPower});
return .{
.ifSatisfied = childValues.ifSatisfied,
.totalItemsChecked = childValues.totalItemsChecked,
.totalCountedItems = childValues.totalCountedItems,
.modifierPower = combinedModifierPower,
};
}

pub fn loadFromZon(allocator: NeverFailingAllocator, zon: ZonElement) *const ForEach {
const result = allocator.create(ForEach);
result.* = .{
.child = ModifierRestriction.loadFromZon(allocator, zon.getChild("child")),
};
return result;
}

pub fn printTooltip(self: *const ForEach, outString: *main.ListManaged(u8)) void {
outString.appendSlice("for each ");
self.child.printTooltip(outString);
}
Loading
Loading