feat(Assets): add WorldEntityRegistry

This commit is contained in:
xeon
2026-02-08 17:48:07 +03:00
parent 5bcf875824
commit 1d25ab84af
4 changed files with 408115 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@ level_map_mark_groups: StringHashMap([]const configs.ClientSingleMapMarkData),
// instId-to-data mapping
map_mark_table: StringHashMap(*const configs.ClientSingleMapMarkData),
teleport_validation_table: configs.TeleportValidationDataTable,
world_entity_registry: configs.WorldEntityRegistry,
pub const IdGroup = enum {
char_id,
@@ -99,6 +100,13 @@ pub fn load(io: Io, gpa: Allocator) !Assets {
"MapTeleportValidationDataTable.json",
);
const world_entity_registry = try configs.loadJsonConfig(
configs.WorldEntityRegistry,
io,
arena.allocator(),
"WorldEntityRegistry.json",
);
return .{
.arena = arena,
.owned_tables = owned_tables,
@@ -111,6 +119,7 @@ pub fn load(io: Io, gpa: Allocator) !Assets {
.level_map_mark_groups = level_map_mark_groups,
.map_mark_table = map_mark_table,
.teleport_validation_table = teleport_validation_table,
.world_entity_registry = world_entity_registry,
};
}

View File

@@ -5,6 +5,7 @@ pub const CommonSkillConfig = @import("configs/CommonSkillConfig.zig");
pub const LevelConfig = @import("configs/LevelConfig.zig");
pub const ClientSingleMapMarkData = @import("configs/ClientSingleMapMarkData.zig");
pub const TeleportValidationDataTable = @import("configs/TeleportValidationDataTable.zig");
pub const WorldEntityRegistry = @import("configs/WorldEntityRegistry.zig");
const Io = std.Io;
const Allocator = std.mem.Allocator;
@@ -34,3 +35,46 @@ pub fn loadJsonConfig(
.{ .ignore_unknown_fields = true },
);
}
// std.json.ArrayHashMap, modified to work with integer keys.
pub fn ArrayIntMap(comptime Int: type, comptime T: type) type {
return struct {
map: std.AutoArrayHashMapUnmanaged(Int, T) = .empty,
pub fn deinit(self: *@This(), allocator: Allocator) void {
self.map.deinit(allocator);
}
pub fn jsonParse(allocator: Allocator, source: anytype, options: std.json.ParseOptions) !@This() {
var map: std.AutoArrayHashMapUnmanaged(Int, T) = .empty;
errdefer map.deinit(allocator);
if (.object_begin != try source.next()) return error.UnexpectedToken;
while (true) {
const token = try source.nextAlloc(allocator, options.allocate.?);
switch (token) {
inline .string, .allocated_string => |k| {
const int = std.fmt.parseInt(Int, k, 10) catch return error.UnexpectedToken;
const gop = try map.getOrPut(allocator, int);
if (gop.found_existing) {
switch (options.duplicate_field_behavior) {
.use_first => {
// Parse and ignore the redundant value.
// We don't want to skip the value, because we want type checking.
_ = try std.json.innerParse(T, allocator, source, options);
continue;
},
.@"error" => return error.DuplicateField,
.use_last => {},
}
}
gop.value_ptr.* = try std.json.innerParse(T, allocator, source, options);
},
.object_end => break,
else => unreachable,
}
}
return .{ .map = map };
}
};
}

View File

@@ -0,0 +1,12 @@
const std = @import("std");
const logic = @import("../../logic.zig");
const configs = @import("../configs.zig");
worldEntityBriefInfos: configs.ArrayIntMap(u64, WorldEntityBriefInfo),
pub const WorldEntityBriefInfo = struct {
entityType: u32,
detailId: ?[]const u8,
position: logic.Level.Object.Vector,
rotation: logic.Level.Object.Vector,
};