Introduce modifiers that allow changing the power based on the block type.

Basically https://github.com/PixelGuys/Cubyz/issues/172#issuecomment-2685028175
This commit is contained in:
IntegratedQuantum 2025-02-26 23:02:18 +01:00
parent 54c2d2afc6
commit 163db4929a
16 changed files with 208 additions and 63 deletions

View File

@ -1,5 +1,5 @@
.{
.class = .stone,
.tags = .{.stone},
.blockHealth = 50,
.breakingPower = 10,
.drops = .{

View File

@ -1,5 +1,5 @@
.{
.class = .stone,
.tags = .{.stone},
.blockHealth = 40,
.breakingPower = 10,
.ore = .{

View File

@ -33,7 +33,7 @@ pub const BlockTag = enum(u32) {
tagIds.clearAndFree();
}
fn find(tag: []const u8) BlockTag {
pub fn find(tag: []const u8) BlockTag {
if(tagIds.get(tag)) |res| return res;
const result: BlockTag = @enumFromInt(tagList.items.len);
const dupedTag = allocator.dupe(u8, tag);

View File

@ -59,7 +59,7 @@ const Material = struct { // MARK: Material
};
modifier.* = .{
.vTable = vTable,
.strength = item.get(f32, "strength", 0),
.data = vTable.loadData(item),
};
}
}
@ -84,30 +84,37 @@ const Material = struct { // MARK: Material
};
const Modifier = struct {
strength: f32,
data: VTable.Data,
vTable: *const VTable,
pub const VTable = struct {
combineModifiers: *const fn(strength1: f32, strength2: f32) f32,
changeToolParameters: *const fn(tool: *Tool, stength: f32) void,
printTooltip: *const fn(outString: *main.List(u8), stength: f32) void,
const Data = packed struct(u128) {pad: u128};
combineModifiers: *const fn(data1: Data, data2: Data) ?Data,
changeToolParameters: *const fn(tool: *Tool, data: Data) void,
changeBlockPower: *const fn(power: f32, block: main.blocks.Block, data: Data) f32,
printTooltip: *const fn(outString: *main.List(u8), data: Data) void,
loadData: *const fn(zon: ZonElement) Data,
priority: f32,
};
pub fn combineModifiers(a: Modifier, b: Modifier) Modifier {
pub fn combineModifiers(a: Modifier, b: Modifier) ?Modifier {
std.debug.assert(a.vTable == b.vTable);
return .{
.strength = a.vTable.combineModifiers(a.strength, b.strength),
.data = a.vTable.combineModifiers(a.data, b.data) orelse return null,
.vTable = a.vTable,
};
}
pub fn changeToolParameters(self: Modifier, tool: *Tool) void {
self.vTable.changeToolParameters(tool, self.strength);
self.vTable.changeToolParameters(tool, self.data);
}
pub fn changeBlockPower(self: Modifier, power: f32, block: main.blocks.Block) f32 {
return self.vTable.changeBlockPower(power, block, self.data);
}
pub fn printTooltip(self: Modifier, outString: *main.List(u8)) void {
self.vTable.printTooltip(outString, self.strength);
self.vTable.printTooltip(outString, self.data);
}
};
@ -315,7 +322,7 @@ const ToolPhysics = struct { // MARK: ToolPhysics
outer: for(material.modifiers) |newMod| {
for(tempModifiers.items) |*oldMod| {
if(oldMod.vTable == newMod.vTable) {
oldMod.* = oldMod.combineModifiers(newMod);
oldMod.* = oldMod.combineModifiers(newMod) orelse continue;
continue :outer;
}
}
@ -570,10 +577,14 @@ pub const Tool = struct { // MARK: Tool
return self.tooltip.items;
}
pub fn getPowerByBlockTags(self: *Tool, blockTags: []const blocks.BlockTag) f32 {
for(blockTags) |blockTag| {
pub fn getBlockPower(self: *Tool, block: main.blocks.Block) f32 {
var power = self.power;
for(self.modifiers) |modifier| {
power = modifier.changeBlockPower(power, block);
}
for(block.blockTags()) |blockTag| {
for(self.type.blockTags) |toolTag| {
if(toolTag == blockTag) return self.power;
if(toolTag == blockTag) return power;
}
}
return 0;
@ -768,9 +779,11 @@ pub fn globalInit() void {
inline for(@typeInfo(modifierList).@"struct".decls) |decl| {
const ModifierStruct = @field(modifierList, decl.name);
modifiers.put(decl.name, &.{
.changeToolParameters = &ModifierStruct.changeToolParameters,
.combineModifiers = &ModifierStruct.combineModifiers,
.printTooltip = &ModifierStruct.printTooltip,
.changeToolParameters = @ptrCast(&ModifierStruct.changeToolParameters),
.changeBlockPower = @ptrCast(&ModifierStruct.changeBlockPower),
.combineModifiers = @ptrCast(&ModifierStruct.combineModifiers),
.printTooltip = @ptrCast(&ModifierStruct.printTooltip),
.loadData = @ptrCast(&ModifierStruct.loadData),
.priority = ModifierStruct.priority,
}) catch unreachable;
}

View File

@ -859,7 +859,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
var power: f32 = 0;
const isTool = stack.item != null and stack.item.? == .tool;
if(isTool) {
power = stack.item.?.tool.getPowerByBlockTags(block.blockTags());
power = stack.item.?.tool.getBlockPower(block);
}
const isChisel = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id, "cubyz:chisel");
if(isChisel and block.mode() == main.rotation.getByID("stairs")) { // TODO: Remove once the chisel is a tool.

View File

@ -71,7 +71,7 @@ pub const RotationMode = struct { // MARK: RotationMode
var power: f32 = 0;
const isTool = item.item != null and item.item.? == .tool;
if(isTool) {
power = item.item.?.tool.getPowerByBlockTags(oldBlock.blockTags());
power = item.item.?.tool.getBlockPower(oldBlock);
}
if(power >= oldBlock.breakingPower()) {
if(isTool) {

View File

@ -1,6 +1,8 @@
pub const bad_at = @import("bad_at.zig");
pub const durable = @import("durable.zig");
pub const fragile = @import("fragile.zig");
pub const good_at = @import("good_at.zig");
pub const heavy = @import("heavy.zig");
pub const light = @import("light.zig");
pub const powerful = @import("powerful.zig");

View File

@ -0,0 +1,30 @@
const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, tag: main.blocks.BlockTag, pad: u64 = undefined};
pub const priority = 1;
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = std.math.clamp(zon.get(f32, "strength", 0), 0, 1), .tag = .find(zon.get([]const u8, "tag", "incorrect"))};
}
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
if(data1.tag != data2.tag) return null;
return .{.strength = 1 - (1 - data1.strength)*(1 - data2.strength), .tag = data1.tag};
}
pub fn changeToolParameters(_: *Tool, _: Data) void {}
pub fn changeBlockPower(power: f32, block: main.blocks.Block, data: Data) f32 {
for(block.blockTags()) |tag| {
if(tag == data.tag) return power*(1 - data.strength);
}
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#a00050**Bad at**#808080 *Decreases power by **{d:.0}%** on \n***#a00050{s}#808080*** blocks", .{data.strength*100, data.tag.getName()}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return @max(0, strength1) + @max(0, strength2);
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = @max(0, zon.get(f32, "strength", 0))};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.maxDurability *= 1 + @max(0, strength);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = data1.strength + data2.strength};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#500090**Durable**#808080 *Increases durability by **{d:.0}%", .{@max(0, strength)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.maxDurability *= 1 + data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#500090**Durable**#808080 *Increases durability by **{d:.0}%", .{data.strength*100}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return 1 - (1 - std.math.clamp(strength1, 0, 1))*(1 - std.math.clamp(strength2, 0, 1));
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = std.math.clamp(zon.get(f32, "strength", 0), 0, 1)};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.maxDurability *= 1 - std.math.clamp(strength, 0, 1);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1 - (1 - data1.strength)*(1 - data2.strength)};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#ccddff**Fragile**#808080 *Decreases durability by **{d:.0}%", .{std.math.clamp(strength, 0, 1)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.maxDurability *= 1 - data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#ccddff**Fragile**#808080 *Decreases durability by **{d:.0}%", .{data.strength*100}) catch unreachable;
}

View File

@ -0,0 +1,30 @@
const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, tag: main.blocks.BlockTag, pad: u64 = undefined};
pub const priority = 1;
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = @max(0, zon.get(f32, "strength", 0)), .tag = .find(zon.get([]const u8, "tag", "incorrect"))};
}
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
if(data1.tag != data2.tag) return null;
return .{.strength = data1.strength + data2.strength, .tag = data1.tag};
}
pub fn changeToolParameters(_: *Tool, _: Data) void {}
pub fn changeBlockPower(power: f32, block: main.blocks.Block, data: Data) f32 {
for(block.blockTags()) |tag| {
if(tag == data.tag) return power*(1 + data.strength);
}
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#80ff40**Good at**#808080 *Increases power by **{d:.0}%** on \n***#80ff40{s}#808080*** blocks", .{data.strength*100, data.tag.getName()}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return @max(0, strength1) + @max(0, strength2);
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = @max(0, zon.get(f32, "strength", 0))};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.swingTime *= 1 + @max(0, strength);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = data1.strength + data2.strength};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#ffcc30**Heavy**#808080 *Increases swing time by **{d:.0}%", .{@max(0, strength)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.swingTime *= 1 + data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#ffcc30**Heavy**#808080 *Increases swing time by **{d:.0}%", .{data.strength*100}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return 1 - (1 - std.math.clamp(strength1, 0, 1))*(1 - std.math.clamp(strength2, 0, 1));
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = std.math.clamp(zon.get(f32, "strength", 0), 0, 1)};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.swingTime *= 1 - std.math.clamp(strength, 0, 1);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1 - (1 - data1.strength)*(1 - data2.strength)};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#9fffde**Light**#808080 *Decreases swing time by **{d:.0}%", .{std.math.clamp(strength, 0, 1)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.swingTime *= 1 - data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#9fffde**Light**#808080 *Decreases swing time by **{d:.0}%", .{data.strength*100}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return @max(0, strength1) + @max(0, strength2);
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = @max(0, zon.get(f32, "strength", 0))};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.power *= 1 + @max(0, strength);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = data1.strength + data2.strength};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#f84a00**Powerful**#808080 *Increases power by **{d:.0}%", .{@max(0, strength)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.power *= 1 + data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#f84a00**Powerful**#808080 *Increases power by **{d:.0}%", .{data.strength*100}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1000;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return @max(1, @min(strength1, strength2));
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = @max(1, zon.get(f32, "strength", 1))};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.maxDurability = @max(1, strength);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = @min(data1.strength, data2.strength)};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#800000**Single-use**#808080 *Sets durability to **{d:.0}", .{@max(1, strength)}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.maxDurability = data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#800000**Single-use**#808080 *Sets durability to **{d:.0}", .{data.strength}) catch unreachable;
}

View File

@ -3,16 +3,26 @@ const std = @import("std");
const main = @import("root");
const Tool = main.items.Tool;
pub const Data = packed struct(u128) {strength: f32, pad: u96 = undefined};
pub const priority = 1;
pub fn combineModifiers(strength1: f32, strength2: f32) f32 {
return 1 - (1 - std.math.clamp(strength1, 0, 1))*(1 - std.math.clamp(strength2, 0, 1));
pub fn loadData(zon: main.ZonElement) Data {
return .{.strength = std.math.clamp(zon.get(f32, "strength", 0), 0, 1)};
}
pub fn changeToolParameters(tool: *Tool, strength: f32) void {
tool.power *= 1 - std.math.clamp(strength, 0, 1);
pub fn combineModifiers(data1: Data, data2: Data) ?Data {
return .{.strength = 1 - (1 - data1.strength)*(1 - data2.strength)};
}
pub fn printTooltip(outString: *main.List(u8), strength: f32) void {
outString.writer().print("#fcb5e3**Weak**#808080 *Decreases power by **{d:.0}%", .{std.math.clamp(strength, 0, 1)*100}) catch unreachable;
pub fn changeToolParameters(tool: *Tool, data: Data) void {
tool.power *= 1 - data.strength;
}
pub fn changeBlockPower(power: f32, _: main.blocks.Block, _: Data) f32 {
return power;
}
pub fn printTooltip(outString: *main.List(u8), data: Data) void {
outString.writer().print("#fcb5e3**Weak**#808080 *Decreases power by **{d:.0}%", .{data.strength*100}) catch unreachable;
}