Complete remaining client gap features

This commit is contained in:
shenlei
2026-09-04 13:25:05 +09:00
parent 13ccb8d02d
commit 9a4a044da5
47 changed files with 6667 additions and 140 deletions
+56
View File
@@ -0,0 +1,56 @@
// .mdatr —— Metin2 AttributeData 静态碰撞 / 高度网格资源。
//
// The legacy client reads this file as a packed little-endian stream. Keep the
// format layer independent from Godot so it can be used by the world loader and
// by host-side validation tests alike.
#pragma once
#include <array>
#include <cstdint>
#include <string>
#include <vector>
namespace fmt {
enum class AttributeCollisionType : std::uint32_t {
Plane = 0,
Box = 1,
Sphere = 2,
Cylinder = 3,
Aabb = 4,
Obb = 5,
};
struct AttributeCollision {
std::uint32_t type = 0;
std::string name;
std::array<float, 3> position = {0.0f, 0.0f, 0.0f};
// Plane/Cylinder use dimensions[0..1], the other supported primitives use
// dimensions[0..2]. Values retain the source units (centimetres).
std::array<float, 3> dimensions = {0.0f, 0.0f, 0.0f};
// x, y, z, w in the same order as the D3DXQUATERNION on disk.
std::array<float, 4> quaternion = {0.0f, 0.0f, 0.0f, 1.0f};
};
struct AttributeHeight {
std::string name;
// The legacy file calls these vertices "primitives". They are a flat
// triangle list: every consecutive three vertices form one triangle.
std::vector<std::array<float, 3>> vertices;
};
struct AttributeData {
std::vector<AttributeCollision> collisions;
std::vector<AttributeHeight> heights;
};
// Parse the complete byte buffer. The parser rejects truncated data, unknown
// primitive types and unreasonable counts rather than accepting a partial
// collision resource.
bool parse_attribute_data(const std::uint8_t *data, std::size_t size,
AttributeData &out, std::string *err = nullptr);
bool parse_attribute_data_file(const std::string &path, AttributeData &out,
std::string *err = nullptr);
} // namespace fmt