artificer/lib/craft_goal.zig

78 lines
2.0 KiB
Zig

// zig fmt: off
const Api = @import("./api/root.zig");
const Artificer = @import("./artificer.zig");
const Context = Artificer.GoalContext;
const Requirements = Artificer.Requirements;
const Goal = @This();
item: Api.Store.Id,
quantity: u64,
fn getCraftMultiples(self: Goal, craft: Api.Craft) u64 {
return @intFromFloat(@ceil(
@as(f32, @floatFromInt(self.quantity)) /
@as(f32, @floatFromInt(craft.quantity))
));
}
pub fn tick(self: *Goal, ctx: *Context) !void {
const store = ctx.store;
if (self.quantity == 0) {
ctx.completed = true;
return;
}
const item = store.items.get(self.item).?;
const craft = item.craft.?;
const skill = craft.skill.toCharacterSkill();
if (ctx.character.skills.get(skill).level < craft.level) {
return error.SkillTooLow;
}
const workshop_position = ctx.findNearestWorkstation(craft.skill).?;
if (!workshop_position.eql(ctx.character.position)) {
ctx.queueAction(.{
.move = workshop_position
});
return;
}
ctx.queueAction(.{
.craft = .{ .item = self.item, .quantity = self.quantity }
});
}
pub fn requirements(self: Goal, ctx: *Context) Requirements {
var reqs: Requirements = .{};
const store = ctx.store;
const item = store.items.get(self.item).?;
const craft = item.craft.?;
const craft_multiples = self.getCraftMultiples(craft);
for (craft.items.slice()) |craft_item| {
reqs.items.addAssumeCapacity(craft_item.id, craft_item.quantity * craft_multiples);
}
return reqs;
}
pub fn onActionCompleted(self: *Goal, ctx: *Context, result: Artificer.ActionResult) void {
_ = ctx;
if (result == .craft) {
const craft_result = result.craft;
const craft_quantity = craft_result.details.items.getQuantity(self.item);
if (self.quantity > craft_quantity) {
self.quantity -= craft_quantity;
} else {
self.quantity = 0;
}
}
}