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); } }