add basic gui
This commit is contained in:
parent
45e32424cb
commit
f9dc023b90
@ -44,7 +44,7 @@ air: CombatStats,
|
||||
|
||||
equipment: Equipment,
|
||||
|
||||
inventory_max_items: i64,
|
||||
inventory_max_items: u64,
|
||||
inventory: Inventory,
|
||||
|
||||
pub fn parse(api: *Server, obj: json.ObjectMap, allocator: Allocator) !Character {
|
||||
@ -54,7 +54,14 @@ pub fn parse(api: *Server, obj: json.ObjectMap, allocator: Allocator) !Character
|
||||
const x = try json_utils.getIntegerRequired(obj, "x");
|
||||
const y = try json_utils.getIntegerRequired(obj, "y");
|
||||
const name = (try json_utils.dupeString(allocator, obj, "name")) orelse return error.MissingProperty;
|
||||
assert(name.len > 0);
|
||||
if (name.len == 0) {
|
||||
return error.InvalidName;
|
||||
}
|
||||
|
||||
const inventory_max_items = json_utils.getInteger(obj, "inventory_max_items") orelse return error.MissingProperty;
|
||||
if (inventory_max_items < 0) {
|
||||
return error.InvalidInventoryMaxItems;
|
||||
}
|
||||
|
||||
return Character{
|
||||
.allocator = allocator,
|
||||
@ -84,7 +91,7 @@ pub fn parse(api: *Server, obj: json.ObjectMap, allocator: Allocator) !Character
|
||||
|
||||
.equipment = try Equipment.parse(api, obj),
|
||||
|
||||
.inventory_max_items = json_utils.getInteger(obj, "inventory_max_items") orelse return error.MissingProperty,
|
||||
.inventory_max_items = @intCast(inventory_max_items),
|
||||
.inventory = try Inventory.parse(api, inventory)
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Artificer = @import("artificer");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
@ -29,6 +30,11 @@ pub fn main() !void {
|
||||
var artificer = try Artificer.init(allocator, token);
|
||||
defer artificer.deinit();
|
||||
|
||||
if (builtin.mode != .Debug) {
|
||||
std.log.info("Prefetching server data", .{});
|
||||
try artificer.server.prefetch();
|
||||
}
|
||||
|
||||
std.log.info("Starting main loop", .{});
|
||||
while (true) {
|
||||
const waitUntil = artificer.nextStepAt();
|
||||
|
62
gui/main.zig
62
gui/main.zig
@ -1,18 +1,76 @@
|
||||
const std = @import("std");
|
||||
const Artificer = @import("artificer");
|
||||
const rl = @import("raylib");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const srcery = @import("./srcery.zig");
|
||||
|
||||
const UI = @import("./ui.zig");
|
||||
const UIStack = @import("./ui_stack.zig");
|
||||
const RectUtils = @import("./rect_utils.zig");
|
||||
|
||||
fn getAPITokenFromArgs(allocator: Allocator) !?[]u8 {
|
||||
const args = try std.process.argsAlloc(allocator);
|
||||
defer std.process.argsFree(allocator, args);
|
||||
|
||||
if (args.len < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const filename = args[1];
|
||||
const cwd = std.fs.cwd();
|
||||
var token_buffer: [256]u8 = undefined;
|
||||
const token = try cwd.readFile(filename, &token_buffer);
|
||||
|
||||
return try allocator.dupe(u8, std.mem.trim(u8,token,"\n\t "));
|
||||
}
|
||||
|
||||
fn drawCharacterInfo(ui: *UI, rect: rl.Rectangle, brain: Artificer.Brain) void {
|
||||
const name_height = 20;
|
||||
UI.drawTextCentered(ui.font, brain.name, .{
|
||||
.x = RectUtils.center(rect).x,
|
||||
.y = rect.y + name_height/2
|
||||
}, 20, 2, srcery.bright_white);
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const token = (try getAPITokenFromArgs(allocator)) orelse return error.MissingToken;
|
||||
defer allocator.free(token);
|
||||
|
||||
var artificer = try Artificer.init(allocator, token);
|
||||
defer artificer.deinit();
|
||||
|
||||
rl.initWindow(800, 450, "Artificer");
|
||||
defer rl.closeWindow();
|
||||
|
||||
rl.setTargetFPS(60);
|
||||
|
||||
var ui = UI.init();
|
||||
defer ui.deinit();
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
if (std.time.timestamp() > artificer.nextStepAt()) {
|
||||
try artificer.step();
|
||||
}
|
||||
|
||||
const screen_size = rl.Vector2.init(
|
||||
@floatFromInt(rl.getScreenWidth()),
|
||||
@floatFromInt(rl.getScreenHeight())
|
||||
);
|
||||
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(srcery.black);
|
||||
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, rl.Color.light_gray);
|
||||
var info_stack = UIStack.init(rl.Rectangle.init(0, 0, screen_size.x, screen_size.y), .left_to_right);
|
||||
for (artificer.characters.items) |brain| {
|
||||
const info_width = screen_size.x / @as(f32, @floatFromInt(artificer.characters.items.len));
|
||||
drawCharacterInfo(&ui, info_stack.next(info_width), brain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
142
gui/rect_utils.zig
Normal file
142
gui/rect_utils.zig
Normal file
@ -0,0 +1,142 @@
|
||||
const rl = @import("raylib");
|
||||
const Rect = rl.Rectangle;
|
||||
|
||||
pub const AlignX = enum { left, center, right };
|
||||
pub const AlignY = enum { top, center, bottom };
|
||||
|
||||
pub fn initCentered(rect: Rect, width: f32, height: f32) Rect {
|
||||
const unused_width = rect.width - width;
|
||||
const unused_height = rect.height - height;
|
||||
return Rect.init(rect.x + unused_width / 2, rect.y + unused_height / 2, width, height);
|
||||
}
|
||||
|
||||
pub fn center(rect: Rect) rl.Vector2 {
|
||||
return rl.Vector2{
|
||||
.x = rect.x + rect.width / 2,
|
||||
.y = rect.y + rect.height / 2,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bottomLeft(rect: Rect) rl.Vector2 {
|
||||
return rl.Vector2{
|
||||
.x = rect.x,
|
||||
.y = rect.y + rect.height,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn bottomRight(rect: Rect) rl.Vector2 {
|
||||
return rl.Vector2{
|
||||
.x = rect.x + rect.width,
|
||||
.y = rect.y + rect.height,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn topLeft(rect: Rect) rl.Vector2 {
|
||||
return rl.Vector2{
|
||||
.x = rect.x,
|
||||
.y = rect.y,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn topRight(rect: Rect) rl.Vector2 {
|
||||
return rl.Vector2{
|
||||
.x = rect.x + rect.width,
|
||||
.y = rect.y,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn aligned(rect: Rect, align_x: AlignX, align_y: AlignY) rl.Vector2 {
|
||||
const x = switch(align_x) {
|
||||
.left => rect.x,
|
||||
.center => rect.x + rect.width/2,
|
||||
.right => rect.x + rect.width,
|
||||
};
|
||||
|
||||
const y = switch(align_y) {
|
||||
.top => rect.y,
|
||||
.center => rect.y + rect.height/2,
|
||||
.bottom => rect.y + rect.height,
|
||||
};
|
||||
|
||||
return rl.Vector2.init(x, y);
|
||||
}
|
||||
|
||||
pub fn shrink(rect: Rect, x: f32, y: f32) rl.Rectangle {
|
||||
return Rect.init(rect.x + x, rect.y + y, rect.width - 2 * x, rect.height - 2 * y);
|
||||
}
|
||||
|
||||
pub fn shrinkX(rect: rl.Rectangle, offset: f32) rl.Rectangle {
|
||||
return shrink(rect, offset, 0);
|
||||
}
|
||||
|
||||
pub fn shrinkY(rect: rl.Rectangle, offset: f32) rl.Rectangle {
|
||||
return shrink(rect, 0, offset);
|
||||
}
|
||||
|
||||
pub fn shrinkTop(rect: rl.Rectangle, offset: f32) rl.Rectangle {
|
||||
return Rect.init(rect.x, rect.y + offset, rect.width, rect.height - offset);
|
||||
}
|
||||
|
||||
pub fn grow(rect: Rect, x: f32, y: f32) rl.Rectangle {
|
||||
return shrink(rect, -x, -y);
|
||||
}
|
||||
|
||||
pub fn growY(rect: Rect, offset: f32) rl.Rectangle {
|
||||
return grow(rect, 0, offset);
|
||||
}
|
||||
|
||||
pub fn position(rect: rl.Rectangle) rl.Vector2 {
|
||||
return rl.Vector2.init(rect.x, rect.y);
|
||||
}
|
||||
|
||||
pub fn isInside(rect: rl.Rectangle, x: f32, y: f32) bool {
|
||||
return (rect.x <= x and x < rect.x + rect.width) and (rect.y < y and y < rect.y + rect.height);
|
||||
}
|
||||
|
||||
pub fn isInsideVec2(rect: rl.Rectangle, vec2: rl.Vector2) bool {
|
||||
return isInside(rect, vec2.x, vec2.y);
|
||||
}
|
||||
|
||||
pub fn top(rect: rl.Rectangle) f32 {
|
||||
return rect.y;
|
||||
}
|
||||
|
||||
pub fn bottom(rect: rl.Rectangle) f32 {
|
||||
return rect.y + rect.height;
|
||||
}
|
||||
|
||||
pub fn left(rect: rl.Rectangle) f32 {
|
||||
return rect.x;
|
||||
}
|
||||
|
||||
pub fn right(rect: rl.Rectangle) f32 {
|
||||
return rect.x + rect.width;
|
||||
}
|
||||
|
||||
pub fn verticalSplit(rect: rl.Rectangle, left_side_width: f32) [2]rl.Rectangle {
|
||||
var left_side = rect;
|
||||
left_side.width = left_side_width;
|
||||
|
||||
var right_side = rect;
|
||||
right_side.x += left_side_width;
|
||||
right_side.width -= left_side_width;
|
||||
|
||||
return .{
|
||||
left_side,
|
||||
right_side
|
||||
};
|
||||
}
|
||||
|
||||
pub fn horizontalSplit(rect: rl.Rectangle, top_side_height: f32) [2]rl.Rectangle {
|
||||
var top_side = rect;
|
||||
top_side.height = top_side_height;
|
||||
|
||||
var bottom_side = rect;
|
||||
bottom_side.y += top_side_height;
|
||||
bottom_side.height -= top_side_height;
|
||||
|
||||
return .{
|
||||
top_side,
|
||||
bottom_side
|
||||
};
|
||||
}
|
43
gui/srcery.zig
Normal file
43
gui/srcery.zig
Normal file
@ -0,0 +1,43 @@
|
||||
const rl = @import("raylib");
|
||||
|
||||
fn rgb(r: u8, g: u8, b: u8) rl.Color {
|
||||
return rl.Color.init(r, g, b, 255);
|
||||
}
|
||||
|
||||
// Primary
|
||||
pub const black = rgb(28 , 27 , 25 );
|
||||
pub const red = rgb(239, 47 , 39 );
|
||||
pub const green = rgb(81 , 159, 80 );
|
||||
pub const yellow = rgb(251, 184, 41 );
|
||||
pub const blue = rgb(44 , 120, 191);
|
||||
pub const magenta = rgb(224, 44 , 109);
|
||||
pub const cyan = rgb(10 , 174, 179);
|
||||
pub const white = rgb(186, 166, 127);
|
||||
pub const bright_black = rgb(145, 129, 117);
|
||||
pub const bright_red = rgb(247, 83 , 65 );
|
||||
pub const bright_green = rgb(152, 188, 55 );
|
||||
pub const bright_yellow = rgb(254, 208, 110);
|
||||
pub const bright_blue = rgb(104, 168, 228);
|
||||
pub const bright_magenta = rgb(255, 92 , 143);
|
||||
pub const bright_cyan = rgb(43 , 228, 208);
|
||||
pub const bright_white = rgb(252, 232, 195);
|
||||
|
||||
// Secondary
|
||||
pub const orange = rgb(255, 95, 0);
|
||||
pub const bright_orange = rgb(255, 135, 0);
|
||||
pub const hard_black = rgb(18, 18, 18);
|
||||
pub const teal = rgb(0, 128, 128);
|
||||
|
||||
// Grays
|
||||
pub const xgray1 = rgb(38 , 38 , 38 );
|
||||
pub const xgray2 = rgb(48 , 48 , 48 );
|
||||
pub const xgray3 = rgb(58 , 58 , 58 );
|
||||
pub const xgray4 = rgb(68 , 68 , 68 );
|
||||
pub const xgray5 = rgb(78 , 78 , 78 );
|
||||
pub const xgray6 = rgb(88 , 88 , 88 );
|
||||
pub const xgray7 = rgb(98 , 98 , 98 );
|
||||
pub const xgray8 = rgb(108, 108, 108);
|
||||
pub const xgray9 = rgb(118, 118, 118);
|
||||
pub const xgray10 = rgb(128, 128, 128);
|
||||
pub const xgray11 = rgb(138, 138, 138);
|
||||
pub const xgray12 = rgb(148, 148, 148);
|
159
gui/ui.zig
Normal file
159
gui/ui.zig
Normal file
@ -0,0 +1,159 @@
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
const UI = @This();
|
||||
|
||||
font: rl.Font,
|
||||
|
||||
pub fn init() UI {
|
||||
return UI{
|
||||
.font = rl.getFontDefault()
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: UI) void {
|
||||
rl.unloadFont(self.font);
|
||||
}
|
||||
|
||||
// Reimplementation of `GetGlyphIndex` from raylib in src/rtext.c
|
||||
fn GetGlyphIndex(font: rl.Font, codepoint: i32) usize {
|
||||
var index: usize = 0;
|
||||
|
||||
var fallbackIndex: usize = 0; // Get index of fallback glyph '?'
|
||||
|
||||
for (0..@intCast(font.glyphCount), font.glyphs) |i, glyph| {
|
||||
if (glyph.value == '?') fallbackIndex = i;
|
||||
|
||||
if (glyph.value == codepoint)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((index == 0) and (font.glyphs[0].value != codepoint)) index = fallbackIndex;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
fn GetCodePointNext(text: []const u8, next: *usize) i32 {
|
||||
var letter: i32 = '?';
|
||||
|
||||
if (std.unicode.utf8ByteSequenceLength(text[0])) |codepointSize| {
|
||||
next.* = codepointSize;
|
||||
if (std.unicode.utf8Decode(text[0..codepointSize])) |codepoint| {
|
||||
letter = @intCast(codepoint);
|
||||
} else |_| {}
|
||||
} else |_| {}
|
||||
|
||||
return letter;
|
||||
}
|
||||
|
||||
// NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup
|
||||
const textLineSpacing = 2; // TODO: Assume that line spacing is not changed.
|
||||
|
||||
// Reimplementation of `rl.drawTextEx`, so a null terminated would not be required
|
||||
pub fn drawTextEx(font: rl.Font, text: []const u8, position: rl.Vector2, font_size: f32, spacing: f32, tint: rl.Color) void {
|
||||
var used_font = font;
|
||||
if (font.texture.id == 0) {
|
||||
used_font = rl.getFontDefault();
|
||||
}
|
||||
|
||||
var text_offset_y: f32 = 0;
|
||||
var text_offset_x: f32 = 0;
|
||||
|
||||
const scale_factor = font_size / @as(f32, @floatFromInt(used_font.baseSize));
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < text.len) {
|
||||
var next: usize = 0;
|
||||
|
||||
const letter = GetCodePointNext(text[i..], &next);
|
||||
const index = GetGlyphIndex(font, letter);
|
||||
|
||||
i += next;
|
||||
|
||||
if (letter == '\n') {
|
||||
text_offset_x = 0;
|
||||
text_offset_y += (font_size + textLineSpacing);
|
||||
} else {
|
||||
if (letter != ' ' and letter != '\t') {
|
||||
rl.drawTextCodepoint(font, letter, .{
|
||||
.x = position.x + text_offset_x,
|
||||
.y = position.y + text_offset_y,
|
||||
}, font_size, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) {
|
||||
text_offset_x += font.recs[index].width*scale_factor + spacing;
|
||||
} else {
|
||||
text_offset_x += @as(f32, @floatFromInt(font.glyphs[index].advanceX))*scale_factor + spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reimplementation of `rl.measureTextEx`, so a null terminated would not be required
|
||||
pub fn measureTextEx(font: rl.Font, text: []const u8, fontSize: f32, spacing: f32) rl.Vector2 {
|
||||
var textSize = rl.Vector2.init(0, 0);
|
||||
|
||||
if (font.texture.id == 0) return textSize; // Security check
|
||||
|
||||
var tempByteCounter: i32 = 0; // Used to count longer text line num chars
|
||||
var byteCounter: i32 = 0;
|
||||
|
||||
var textWidth: f32 = 0;
|
||||
var tempTextWidth: f32 = 0; // Used to count longer text line width
|
||||
|
||||
var textHeight: f32 = fontSize;
|
||||
const scaleFactor: f32 = fontSize/@as(f32, @floatFromInt(font.baseSize));
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < text.len)
|
||||
{
|
||||
byteCounter += 1;
|
||||
|
||||
var next: usize = 0;
|
||||
|
||||
const letter = GetCodePointNext(text[i..], &next);
|
||||
const index = GetGlyphIndex(font, letter);
|
||||
|
||||
i += next;
|
||||
|
||||
if (letter != '\n')
|
||||
{
|
||||
if (font.glyphs[index].advanceX != 0) {
|
||||
textWidth += @floatFromInt(font.glyphs[index].advanceX);
|
||||
} else {
|
||||
textWidth += font.recs[index].width;
|
||||
textWidth += @floatFromInt(font.glyphs[index].offsetX);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
byteCounter = 0;
|
||||
textWidth = 0;
|
||||
|
||||
textHeight += (fontSize + textLineSpacing);
|
||||
}
|
||||
|
||||
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
|
||||
}
|
||||
|
||||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
|
||||
textSize.x = tempTextWidth*scaleFactor + @as(f32, @floatFromInt(tempByteCounter - 1)) * spacing;
|
||||
textSize.y = textHeight;
|
||||
|
||||
return textSize;
|
||||
}
|
||||
|
||||
pub fn drawTextCentered(font: rl.Font, text: []const u8, position: rl.Vector2, font_size: f32, spacing: f32, color: rl.Color) void {
|
||||
const text_size = measureTextEx(font, text, font_size, spacing);
|
||||
const adjusted_position = rl.Vector2{
|
||||
.x = position.x - text_size.x/2,
|
||||
.y = position.y - text_size.y/2,
|
||||
};
|
||||
drawTextEx(font, text, adjusted_position, font_size, spacing, color);
|
||||
}
|
42
gui/ui_stack.zig
Normal file
42
gui/ui_stack.zig
Normal file
@ -0,0 +1,42 @@
|
||||
const rl = @import("raylib");
|
||||
const Stack = @This();
|
||||
|
||||
pub const Direction = enum {
|
||||
top_to_bottom,
|
||||
bottom_to_top,
|
||||
left_to_right
|
||||
};
|
||||
|
||||
unused_box: rl.Rectangle,
|
||||
dir: Direction,
|
||||
gap: f32 = 0,
|
||||
|
||||
pub fn init(box: rl.Rectangle, dir: Direction) Stack {
|
||||
return Stack{
|
||||
.unused_box = box,
|
||||
.dir = dir
|
||||
};
|
||||
}
|
||||
|
||||
pub fn next(self: *Stack, size: f32) rl.Rectangle {
|
||||
return switch (self.dir) {
|
||||
.top_to_bottom => {
|
||||
const next_box = rl.Rectangle.init(self.unused_box.x, self.unused_box.y, self.unused_box.width, size);
|
||||
self.unused_box.y += size;
|
||||
self.unused_box.y += self.gap;
|
||||
return next_box;
|
||||
},
|
||||
.bottom_to_top => {
|
||||
const next_box = rl.Rectangle.init(self.unused_box.x, self.unused_box.y + self.unused_box.height - size, self.unused_box.width, size);
|
||||
self.unused_box.height -= size;
|
||||
self.unused_box.height -= self.gap;
|
||||
return next_box;
|
||||
},
|
||||
.left_to_right => {
|
||||
const next_box = rl.Rectangle.init(self.unused_box.x, self.unused_box.y, size, self.unused_box.height);
|
||||
self.unused_box.x += size;
|
||||
self.unused_box.x += self.gap;
|
||||
return next_box;
|
||||
},
|
||||
};
|
||||
}
|
@ -400,7 +400,7 @@ pub fn isTaskFinished(self: *CharacterBrain) bool {
|
||||
|
||||
pub fn performTask(self: *CharacterBrain, api: *Server) !void {
|
||||
if (self.task == null) {
|
||||
std.log.debug("[{s}] idle", .{self.name});
|
||||
// TODO: std.log.debug("[{s}] idle", .{self.name});
|
||||
return;
|
||||
}
|
||||
|
||||
|
26
lib/root.zig
26
lib/root.zig
@ -2,7 +2,7 @@ const std = @import("std");
|
||||
const Api = @import("artifacts-api");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const CharacterBrain = @import("./brain.zig");
|
||||
pub const Brain = @import("./brain.zig");
|
||||
|
||||
const Artificer = @This();
|
||||
|
||||
@ -10,7 +10,7 @@ const expiration_margin: u64 = 100 * std.time.ns_per_ms; // 100ms
|
||||
const server_down_retry_interval = 5; // minutes
|
||||
|
||||
server: Api.Server,
|
||||
characters: std.ArrayList(CharacterBrain),
|
||||
characters: std.ArrayList(Brain),
|
||||
|
||||
paused_until: ?i64 = null,
|
||||
|
||||
@ -20,16 +20,15 @@ pub fn init(allocator: Allocator, token: []const u8) !Artificer {
|
||||
|
||||
try server.setToken(token);
|
||||
|
||||
var characters = std.ArrayList(CharacterBrain).init(allocator);
|
||||
defer characters.deinit();
|
||||
// TODO: Add character deinit
|
||||
var characters = std.ArrayList(Brain).init(allocator);
|
||||
errdefer characters.deinit(); // TODO: Add character deinit
|
||||
|
||||
// const chars = try api.listMyCharacters();
|
||||
// defer chars.deinit();
|
||||
const chars = try server.listMyCharacters();
|
||||
defer chars.deinit();
|
||||
|
||||
// for (chars.items) |char| {
|
||||
// try scheduler.addCharacter(char.name);
|
||||
// }
|
||||
for (chars.items) |char| {
|
||||
try characters.append(try Brain.init(allocator, char.name));
|
||||
}
|
||||
|
||||
return Artificer{
|
||||
.server = server,
|
||||
@ -37,11 +36,12 @@ pub fn init(allocator: Allocator, token: []const u8) !Artificer {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Artificer) void {
|
||||
pub fn deinit(self: *Artificer) void {
|
||||
for (self.characters.items) |brain| {
|
||||
brain.deinit();
|
||||
}
|
||||
self.characters.deinit();
|
||||
self.server.deinit();
|
||||
}
|
||||
|
||||
pub fn step(self: *Artificer) !void {
|
||||
@ -93,7 +93,7 @@ pub fn nextStepAt(self: *Artificer) i64 {
|
||||
return earliestCooldown(self.characters.items, &self.server) orelse 0;
|
||||
}
|
||||
|
||||
fn earliestCooldown(characters: []CharacterBrain, api: *Api.Server) ?i64 {
|
||||
fn earliestCooldown(characters: []Brain, api: *Api.Server) ?i64 {
|
||||
var earliest_cooldown: ?i64 = null;
|
||||
for (characters) |*brain| {
|
||||
if (brain.action_queue.items.len == 0) continue;
|
||||
@ -109,7 +109,7 @@ fn earliestCooldown(characters: []CharacterBrain, api: *Api.Server) ?i64 {
|
||||
return earliest_cooldown;
|
||||
}
|
||||
|
||||
fn runNextActions(characters: []CharacterBrain, api: *Api.Server) !void {
|
||||
fn runNextActions(characters: []Brain, api: *Api.Server) !void {
|
||||
const maybe_earliest_cooldown = earliestCooldown(characters, api);
|
||||
if (maybe_earliest_cooldown == null) return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user