artificer/lib/craft_goal.zig
2025-01-03 17:35:44 +02:00

68 lines
2.0 KiB
Zig

// zig fmt: off
const Api = @import("artifacts-api");
const Artificer = @import("./root.zig");
const Goal = @This();
item: Api.Store.Id,
quantity: u64,
pub fn tick(self: *Goal, goal_id: Artificer.GoalId, artificer: *Artificer) !void {
const store = artificer.server.store;
const character = store.characters.get(artificer.character).?;
if (self.quantity == 0) {
artificer.removeGoal(goal_id);
return;
}
const item = store.items.get(self.item).?;
const craft = item.craft.?;
const skill = craft.skill.toCharacterSkill();
if (character.skills.get(skill).level < craft.level) {
return error.SkillTooLow;
}
const craft_multiples: u64 = @intFromFloat(@ceil(
@as(f32, @floatFromInt(self.quantity)) /
@as(f32, @floatFromInt(craft.quantity))
));
for (craft.items.items.slice()) |craft_item| {
const inventory_item_quantity = character.inventory.getQuantity(craft_item.id);
if (inventory_item_quantity < craft_item.quantity * craft_multiples) {
return error.NotEnoughItems;
}
}
const workshop_position = artificer.findNearestWorkstation(craft.skill).?;
if (!workshop_position.eql(character.position)) {
artificer.queued_actions.appendAssumeCapacity(.{
.goal = goal_id,
.action = .{ .move = workshop_position }
});
return;
}
artificer.queued_actions.appendAssumeCapacity(.{
.goal = goal_id,
.action = .{ .craft = .{ .item = self.item, .quantity = self.quantity } }
});
}
pub fn onActionCompleted(self: *Goal, goal_id: Artificer.GoalId, result: Artificer.ActionResult) void {
_ = goal_id;
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;
}
}
}