140 lines
4.1 KiB
C++
140 lines
4.1 KiB
C++
#include "proto_node.h"
|
|
|
|
#include "../asset_io.h"
|
|
|
|
#include <godot_cpp/core/class_db.hpp>
|
|
|
|
#include <string>
|
|
|
|
using namespace godot;
|
|
|
|
namespace mtgodot {
|
|
|
|
void Metin2Proto::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("load_item_proto", "path"), &Metin2Proto::load_item_proto);
|
|
ClassDB::bind_method(D_METHOD("load_mob_proto", "path"), &Metin2Proto::load_mob_proto);
|
|
ClassDB::bind_method(D_METHOD("item", "vnum"), &Metin2Proto::item);
|
|
ClassDB::bind_method(D_METHOD("mob", "vnum"), &Metin2Proto::mob);
|
|
ClassDB::bind_method(D_METHOD("item_count"), &Metin2Proto::item_count);
|
|
ClassDB::bind_method(D_METHOD("mob_count"), &Metin2Proto::mob_count);
|
|
ClassDB::bind_method(D_METHOD("get_last_error"), &Metin2Proto::get_last_error);
|
|
}
|
|
|
|
bool Metin2Proto::load_item_proto(const String &path) {
|
|
std::string err;
|
|
PackedByteArray bytes = mtgodot::read_file(path);
|
|
std::vector<uint8_t> buf(bytes.ptr(), bytes.ptr() + bytes.size());
|
|
if (!mtproto::load_proto_bytes(buf, mtproto::ITEM_PROTO_KEY, m_item, &err)) {
|
|
last_error = String(err.c_str());
|
|
return false;
|
|
}
|
|
m_item_ix.clear();
|
|
m_item_ix.reserve(m_item.elements);
|
|
for (uint32_t i = 0; i < m_item.elements; ++i) {
|
|
mtproto::ItemRecord r = mtproto::parse_item(m_item.record(i), m_item.stride);
|
|
m_item_ix[r.vnum] = i;
|
|
}
|
|
last_error = "";
|
|
return true;
|
|
}
|
|
|
|
bool Metin2Proto::load_mob_proto(const String &path) {
|
|
std::string err;
|
|
PackedByteArray bytes = mtgodot::read_file(path);
|
|
std::vector<uint8_t> buf(bytes.ptr(), bytes.ptr() + bytes.size());
|
|
if (!mtproto::load_proto_bytes(buf, mtproto::MOB_PROTO_KEY, m_mob, &err)) {
|
|
last_error = String(err.c_str());
|
|
return false;
|
|
}
|
|
m_mob_ix.clear();
|
|
m_mob_ix.reserve(m_mob.elements);
|
|
for (uint32_t i = 0; i < m_mob.elements; ++i) {
|
|
mtproto::MobRecord r = mtproto::parse_mob(m_mob.record(i), m_mob.stride);
|
|
m_mob_ix[r.vnum] = i;
|
|
}
|
|
last_error = "";
|
|
return true;
|
|
}
|
|
|
|
Dictionary Metin2Proto::item(int vnum) const {
|
|
Dictionary d;
|
|
auto it = m_item_ix.find((uint32_t)vnum);
|
|
if (it == m_item_ix.end() || m_item.record(it->second) == nullptr) {
|
|
return d;
|
|
}
|
|
mtproto::ItemRecord r = mtproto::parse_item(m_item.record(it->second), m_item.stride);
|
|
d["vnum"] = (int)r.vnum;
|
|
d["vnum_range"] = (int)r.vnum_range;
|
|
d["name"] = String::utf8(r.name.c_str());
|
|
d["locale_name"] = String::utf8(r.locale_name.c_str());
|
|
d["type"] = (int)r.type;
|
|
d["sub_type"] = (int)r.sub_type;
|
|
d["weight"] = (int)r.weight;
|
|
d["size"] = (int)r.size;
|
|
d["anti_flags"] = (int)r.anti_flags;
|
|
d["flags"] = (int)r.flags;
|
|
d["wear_flags"] = (int)r.wear_flags;
|
|
d["buy_price"] = (int)r.buy_price;
|
|
d["sell_price"] = (int)r.sell_price;
|
|
{
|
|
Array limits;
|
|
for (const mtproto::ItemLimit &limit : r.limits) {
|
|
Dictionary entry;
|
|
entry["type"] = (int)limit.type;
|
|
entry["value"] = (int)limit.value;
|
|
limits.push_back(entry);
|
|
}
|
|
d["limits"] = limits;
|
|
}
|
|
{
|
|
Array applies;
|
|
for (const mtproto::ItemApply &apply : r.applies) {
|
|
Dictionary entry;
|
|
entry["type"] = (int)apply.type;
|
|
entry["value"] = (int)apply.value;
|
|
applies.push_back(entry);
|
|
}
|
|
d["applies"] = applies;
|
|
}
|
|
{
|
|
Array vals;
|
|
for (int i = 0; i < 6; ++i) {
|
|
vals.push_back((int)r.values[i]);
|
|
}
|
|
d["values"] = vals; // armor: values[3] = body shape index for the race .msm
|
|
}
|
|
{
|
|
Array sockets;
|
|
for (int socket : r.sockets) {
|
|
sockets.push_back(socket);
|
|
}
|
|
d["sockets"] = sockets;
|
|
}
|
|
d["refined_vnum"] = (int)r.refined_vnum;
|
|
d["refine_set"] = (int)r.refine_set;
|
|
d["alter_to_magic_pct"] = (int)r.alter_to_magic_pct;
|
|
d["specular"] = (int)r.specular;
|
|
d["gain_socket_pct"] = (int)r.gain_socket_pct;
|
|
return d;
|
|
}
|
|
|
|
Dictionary Metin2Proto::mob(int vnum) const {
|
|
Dictionary d;
|
|
auto it = m_mob_ix.find((uint32_t)vnum);
|
|
if (it == m_mob_ix.end() || m_mob.record(it->second) == nullptr) {
|
|
return d;
|
|
}
|
|
mtproto::MobRecord r = mtproto::parse_mob(m_mob.record(it->second), m_mob.stride);
|
|
d["vnum"] = (int)r.vnum;
|
|
d["name"] = String::utf8(r.name.c_str());
|
|
d["locale_name"] = String::utf8(r.locale_name.c_str());
|
|
d["type"] = (int)r.type;
|
|
d["rank"] = (int)r.rank;
|
|
d["battle_type"] = (int)r.battle_type;
|
|
d["level"] = (int)r.level;
|
|
d["size"] = (int)r.size;
|
|
return d;
|
|
}
|
|
|
|
} // namespace mtgodot
|