191 lines
6.6 KiB
Zig
191 lines
6.6 KiB
Zig
// zig fmt: off
|
|
const std = @import("std");
|
|
const Store = @import("../store.zig");
|
|
const EnumStringUtils = @import("../enum_string_utils.zig").EnumStringUtils;
|
|
const json_utils = @import("../json_utils.zig");
|
|
pub const Equipment = @import("./equipment.zig");
|
|
const Task = @import("./task.zig");
|
|
const SimpleItem = @import("./simple_item.zig");
|
|
|
|
const Character = @This();
|
|
|
|
pub const Skin = enum {
|
|
men1,
|
|
men2,
|
|
men3,
|
|
women1,
|
|
women2,
|
|
women3,
|
|
|
|
const Utils = EnumStringUtils(Skin, .{
|
|
.{ "men1" , Skin.men1 },
|
|
.{ "men2" , Skin.men2 },
|
|
.{ "men3" , Skin.men3 },
|
|
.{ "women1", Skin.women1 },
|
|
.{ "women2", Skin.women2 },
|
|
.{ "women3", Skin.women3 },
|
|
});
|
|
|
|
pub const fromString = Utils.fromString;
|
|
pub const toString = Utils.toString;
|
|
};
|
|
|
|
pub const Skill = enum {
|
|
combat,
|
|
fishing,
|
|
weaponcrafting,
|
|
gearcrafting,
|
|
jewelrycrafting,
|
|
cooking,
|
|
woodcutting,
|
|
mining,
|
|
alchemy,
|
|
|
|
const Utils = EnumStringUtils(Skill, .{
|
|
.{ "combat" , Skill.combat },
|
|
.{ "fishing" , Skill.fishing },
|
|
.{ "weaponcrafting" , Skill.weaponcrafting },
|
|
.{ "gearcrafting" , Skill.gearcrafting },
|
|
.{ "jewelrycrafting", Skill.jewelrycrafting },
|
|
.{ "cooking" , Skill.cooking },
|
|
.{ "woodcutting" , Skill.woodcutting },
|
|
.{ "mining" , Skill.mining },
|
|
.{ "alchemy" , Skill.alchemy },
|
|
});
|
|
|
|
pub const toString = Utils.toString;
|
|
pub const fromString = Utils.fromString;
|
|
};
|
|
|
|
pub const SkillStats = struct {
|
|
level: u64 = 0,
|
|
xp: u64 = 0,
|
|
max_xp: u64 = 0,
|
|
|
|
pub fn parse(object: std.json.ObjectMap, level: []const u8, xp: []const u8, max_xp: []const u8) !SkillStats {
|
|
return SkillStats{
|
|
.level = try json_utils.getPositiveIntegerRequired(object, level),
|
|
.xp = try json_utils.getPositiveIntegerRequired(object, xp),
|
|
.max_xp = try json_utils.getPositiveIntegerRequired(object, max_xp),
|
|
};
|
|
}
|
|
};
|
|
|
|
pub const Element = enum {
|
|
water,
|
|
fire,
|
|
earth,
|
|
air,
|
|
};
|
|
|
|
pub const ElementalStats = struct {
|
|
attack: i64,
|
|
damage: i64,
|
|
resistance: i64,
|
|
|
|
pub fn parse(object: std.json.ObjectMap, attack: []const u8, damage: []const u8, resistance: []const u8) !ElementalStats {
|
|
return ElementalStats{
|
|
.attack = try json_utils.getIntegerRequired(object, attack),
|
|
.damage = try json_utils.getIntegerRequired(object, damage),
|
|
.resistance = try json_utils.getIntegerRequired(object, resistance),
|
|
};
|
|
}
|
|
};
|
|
|
|
const TaskMasterTask = struct {
|
|
target: Store.Id,
|
|
type: Task.Type,
|
|
progress: u64,
|
|
total: u64,
|
|
|
|
fn parse(store: *Store, obj: std.json.ObjectMap) !?TaskMasterTask {
|
|
const task_target = try json_utils.getStringRequired(obj, "task");
|
|
if (task_target.len == 0) {
|
|
return null;
|
|
}
|
|
|
|
const task_type = try json_utils.getStringRequired(obj, "task_type");
|
|
const progress = try json_utils.getPositiveIntegerRequired(obj, "task_progress");
|
|
const total = try json_utils.getPositiveIntegerRequired(obj, "task_total");
|
|
|
|
return TaskMasterTask{
|
|
.target = try store.tasks.getOrReserveId(task_target),
|
|
.type = Task.Type.fromString(task_type) orelse return error.InvalidTaskType,
|
|
.total = total,
|
|
.progress = progress,
|
|
};
|
|
}
|
|
};
|
|
|
|
pub const ElementalStatsArray = std.EnumArray(Element, ElementalStats);
|
|
|
|
pub const Skills = std.EnumArray(Skill, SkillStats);
|
|
|
|
pub const max_name_size = 12;
|
|
pub const Name = std.BoundedArray(u8, max_name_size);
|
|
|
|
pub const max_account_size = 32;
|
|
pub const Account = std.BoundedArray(u8, max_account_size);
|
|
|
|
pub const Inventory = SimpleItem.BoundedArray(20);
|
|
|
|
name: Name,
|
|
account: Account,
|
|
skin: Skin,
|
|
gold: u64,
|
|
skills: Skills,
|
|
elemental_stats: ElementalStatsArray,
|
|
equipment: Equipment,
|
|
task: ?TaskMasterTask,
|
|
inventory_max_items: u64,
|
|
inventory: Inventory,
|
|
|
|
pub fn parse(store: *Store, obj: std.json.ObjectMap) !Character {
|
|
const name = try json_utils.getStringRequired(obj, "name");
|
|
if (name.len == 0) {
|
|
return error.InvalidName;
|
|
}
|
|
|
|
const inventory = try json_utils.getArrayRequired(obj, "inventory");
|
|
const account = try json_utils.getStringRequired(obj, "name");
|
|
const skin = try json_utils.getStringRequired(obj, "skin");
|
|
const gold = try json_utils.getPositiveIntegerRequired(obj, "gold");
|
|
const inventory_max_items = try json_utils.getPositiveIntegerRequired(obj, "inventory_max_items");
|
|
|
|
const skill_stats = Skills.init(.{
|
|
.combat = try SkillStats.parse(obj, "level", "xp", "max_xp"),
|
|
.mining = try SkillStats.parse(obj, "mining_level", "mining_xp", "mining_max_xp"),
|
|
.woodcutting = try SkillStats.parse(obj, "woodcutting_level", "woodcutting_xp", "woodcutting_max_xp"),
|
|
.fishing = try SkillStats.parse(obj, "fishing_level", "fishing_xp", "fishing_max_xp"),
|
|
.weaponcrafting = try SkillStats.parse(obj, "weaponcrafting_level", "weaponcrafting_xp", "weaponcrafting_max_xp"),
|
|
.gearcrafting = try SkillStats.parse(obj, "gearcrafting_level", "gearcrafting_xp", "gearcrafting_max_xp"),
|
|
.jewelrycrafting = try SkillStats.parse(obj, "jewelrycrafting_level", "jewelrycrafting_xp", "jewelrycrafting_max_xp"),
|
|
.cooking = try SkillStats.parse(obj, "cooking_level", "cooking_xp", "cooking_max_xp"),
|
|
.alchemy = try SkillStats.parse(obj, "alchemy_level", "alchemy_xp", "alchemy_max_xp"),
|
|
});
|
|
|
|
const elemental_stats = ElementalStatsArray.init(.{
|
|
.water = try ElementalStats.parse(obj, "attack_water", "dmg_water", "res_water"),
|
|
.fire = try ElementalStats.parse(obj, "attack_fire", "dmg_fire", "res_fire"),
|
|
.earth = try ElementalStats.parse(obj, "attack_earth", "dmg_earth", "res_earth"),
|
|
.air = try ElementalStats.parse(obj, "attack_air", "dmg_air", "res_air"),
|
|
});
|
|
|
|
return Character{
|
|
.name = try Name.fromSlice(name),
|
|
.account = try Account.fromSlice(account),
|
|
.skin = Skin.fromString(skin) orelse return error.SkinNotFound,
|
|
.gold = gold,
|
|
.skills = skill_stats,
|
|
.elemental_stats = elemental_stats,
|
|
.equipment = try Equipment.parse(store, obj),
|
|
.task = try TaskMasterTask.parse(store, obj),
|
|
.inventory_max_items = inventory_max_items,
|
|
.inventory = try Inventory.parse(store, inventory)
|
|
};
|
|
}
|
|
|
|
pub fn parseAndAppend(store: *Store, obj: std.json.ObjectMap) !Store.Id {
|
|
return store.characters.appendOrUpdate(try parse(store, obj));
|
|
}
|