artificer/lib/brain.zig

89 lines
2.5 KiB
Zig

const std = @import("std");
const Api = @import("artifacts-api");
const Server = Api.Server;
const Position = Api.Position;
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const CharacterTask = @import("./task.zig").Task;
const QueuedAction = @import("./action.zig").Action;
const QueuedActionResult = @import("./action.zig").ActionResult;
const Brain = @This();
name: []const u8,
action_queue: std.ArrayList(QueuedAction),
task: ?CharacterTask = null,
pub fn init(allocator: Allocator, name: []const u8) !Brain {
return Brain{
.name = try allocator.dupe(u8, name),
.action_queue = std.ArrayList(QueuedAction).init(allocator),
};
}
pub fn deinit(self: Brain) void {
const allocator = self.action_queue.allocator;
allocator.free(self.name);
self.action_queue.deinit();
}
fn currentTime() f64 {
const timestamp: f64 = @floatFromInt(std.time.milliTimestamp());
return timestamp / std.time.ms_per_s;
}
pub fn performNextAction(self: *Brain, api: *Server) !void {
const log = std.log.default;
assert(self.action_queue.items.len > 0);
const retry_delay = 0.5; // 500ms
var character = api.findCharacterPtr(self.name).?;
const next_action = self.action_queue.items[0];
const action_result = try next_action.perform(api, self.name);
if (action_result.getErrorResponse()) |error_response| {
switch (error_response) {
.retry => {
character.cooldown_expiration = currentTime() + retry_delay;
log.warn("[{s}] retry withdrawing item", .{self.name});
},
.restart => {
log.warn("[{s}] clear action queue", .{self.name});
self.action_queue.clearAndFree();
},
.abort => {
try action_result.getError();
// The error above should always return
unreachable;
},
.ignore => { },
}
}
_ = self.action_queue.orderedRemove(0);
if (self.task) |*task| {
task.onActionCompleted(action_result);
}
}
pub fn step(self: *Brain, api: *Api.Server) !void {
if (self.action_queue.items.len > 0) return;
if (self.task) |task| {
if (task.isComplete()) {
// if (try brain.depositItemsToBank(&self.server)) {
// continue;
// }
self.task = null;
}
}
if (self.task) |task| {
try task.queueActions(api, self.name, &self.action_queue);
}
}