105 lines
3.0 KiB
Zig
105 lines
3.0 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,
|
|
paused_until: ?i64 = null, // ms
|
|
|
|
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();
|
|
}
|
|
|
|
pub fn performNextAction(self: *Brain, api: *Server) !void {
|
|
const log = std.log.default;
|
|
assert(self.action_queue.items.len > 0);
|
|
|
|
const retry_delay = 500; // 500ms
|
|
|
|
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 => {
|
|
self.paused_until = std.time.milliTimestamp() + retry_delay;
|
|
log.warn("[{s}] retry action", .{self.name});
|
|
return;
|
|
},
|
|
.restart => {
|
|
log.warn("[{s}] clear action queue", .{self.name});
|
|
self.action_queue.clearAndFree();
|
|
return;
|
|
},
|
|
.abort => {
|
|
log.warn("[{s}] abort action {s}", .{ self.name, @tagName(next_action) });
|
|
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.paused_until) |paused_until| {
|
|
if (std.time.milliTimestamp() < paused_until) {
|
|
return;
|
|
}
|
|
self.paused_until = null;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
pub fn cooldown(self: *Brain, api: *Server) i64 {
|
|
const character = api.store.getCharacter(self.name).?;
|
|
const cooldown_expiration: i64 = @intFromFloat(character.cooldown_expiration * std.time.ms_per_s);
|
|
|
|
if (self.paused_until) |pause_until| {
|
|
return @max(cooldown_expiration, pause_until);
|
|
} else {
|
|
return cooldown_expiration;
|
|
}
|
|
}
|