99 lines
3.1 KiB
Zig
99 lines
3.1 KiB
Zig
// zig fmt: off
|
|
const std = @import("std");
|
|
const Store = @import("../store.zig");
|
|
const Position = @import("./position.zig");
|
|
const json_utils = @import("../json_utils.zig");
|
|
const Monster = @import("./monster.zig");
|
|
const Resource = @import("./resource.zig");
|
|
const Craft = @import("./craft.zig");
|
|
const EnumStringUtils = @import("../enum_string_utils.zig").EnumStringUtils;
|
|
|
|
const Map = @This();
|
|
|
|
pub const Name = std.BoundedArray(u8, 16);
|
|
|
|
pub const max_skin_size = 32;
|
|
pub const Skin = std.BoundedArray(u8, max_skin_size);
|
|
|
|
pub const Content = struct {
|
|
pub const Type = enum {
|
|
monster,
|
|
resource,
|
|
workshop,
|
|
bank,
|
|
grand_exchange,
|
|
tasks_master,
|
|
santa_claus,
|
|
|
|
const Utils = EnumStringUtils(Type, .{
|
|
.{ "monster" , Type.monster },
|
|
.{ "resource" , Type.resource },
|
|
.{ "workshop" , Type.workshop },
|
|
.{ "bank" , Type.bank },
|
|
.{ "grand_exchange", Type.grand_exchange },
|
|
.{ "tasks_master" , Type.tasks_master },
|
|
.{ "santa_claus" , Type.santa_claus },
|
|
});
|
|
|
|
pub const fromString = Utils.fromString;
|
|
pub const toString = Utils.toString;
|
|
};
|
|
|
|
pub const max_code_size = size: {
|
|
var max: usize = 0;
|
|
max = @max(max, Monster.max_code_size);
|
|
max = @max(max, Resource.max_code_size);
|
|
for (std.meta.fields(Craft.Skill)) |field| {
|
|
max = @max(max, Craft.Skill.toString(@enumFromInt(field.value)).len);
|
|
}
|
|
max = @max(max, "bank".len);
|
|
max = @max(max, "grand_exchange".len);
|
|
// TODO: max type 'tasks_master'
|
|
break :size max;
|
|
};
|
|
pub const Code = std.BoundedArray(u8, max_code_size);
|
|
|
|
type: Type,
|
|
code: Code,
|
|
};
|
|
|
|
name: Name,
|
|
skin: Skin,
|
|
position: Position,
|
|
content: ?Content,
|
|
|
|
pub fn parse(store: *Store, obj: std.json.ObjectMap) !Map {
|
|
_ = store;
|
|
|
|
const name = try json_utils.getStringRequired(obj, "name");
|
|
const skin = try json_utils.getStringRequired(obj, "skin");
|
|
const x = try json_utils.getIntegerRequired(obj, "x");
|
|
const y = try json_utils.getIntegerRequired(obj, "y");
|
|
|
|
var content: ?Content = null;
|
|
if (json_utils.getObject(obj, "content")) |content_obj| {
|
|
const content_code = try json_utils.getStringRequired(content_obj, "code");
|
|
const content_type = try json_utils.getStringRequired(content_obj, "type");
|
|
content = Content{
|
|
.code = try Content.Code.fromSlice(content_code),
|
|
.type = Content.Type.fromString(content_type) orelse return error.InvalidContentType
|
|
};
|
|
}
|
|
|
|
return Map{
|
|
.name = try Name.fromSlice(name),
|
|
.skin = try Skin.fromSlice(skin),
|
|
.position = Position.init(x, y),
|
|
.content = content
|
|
};
|
|
}
|
|
|
|
pub fn parseAndAppend(store: *Store, obj: std.json.ObjectMap) !Position {
|
|
return store.appendOrUpdateMap(try parse(store, obj));
|
|
}
|
|
|
|
pub fn parseAndAppendObject(store: *Store, obj: std.json.ObjectMap) !Map {
|
|
const position = try parseAndAppend(store, obj);
|
|
return store.getMap(position).?.*;
|
|
}
|