From 404ca14c977781e397466b7746ffaac8c839a826 Mon Sep 17 00:00:00 2001 From: Rick Gibbed Date: Sat, 26 Dec 2020 08:43:14 -0600 Subject: [PATCH] Improvements to user types. - Add Vector3. - Add To* lua functions for constructing user types from a Lua table. - Add additional user type constructors. eg Vector4.new(1) is now possible. - Cleanup/fixes to user type ToString(). --- src/reverse/BasicTypes.cpp | 28 +++++---- src/reverse/BasicTypes.h | 80 ++++++++++++++++--------- src/reverse/Converter.cpp | 1 + src/reverse/Scripting.cpp | 119 +++++++++++++++++++++++++++++++------ 4 files changed, 170 insertions(+), 58 deletions(-) diff --git a/src/reverse/BasicTypes.cpp b/src/reverse/BasicTypes.cpp index dd18e5b6..c889efe3 100644 --- a/src/reverse/BasicTypes.cpp +++ b/src/reverse/BasicTypes.cpp @@ -1,43 +1,45 @@ #include "BasicTypes.h" -#include +#include #include "RED4ext/REDreverse/CName.hpp" +std::string Vector3::ToString() const noexcept +{ + return fmt::format("ToVector3{{ x = {0}, y = {1}, z = {2} }}", x, y, z); +} + std::string Vector4::ToString() const noexcept { - return "Vector4{ x: " + std::to_string(x) + " y: " + std::to_string(y) + " z: " + std::to_string(z) + " w: " + std::to_string(w) + " }"; + return fmt::format("ToVector4{{ x = {0}, y = {1}, z = {2}, w = {3} }}", x, y, z, w); } std::string EulerAngles::ToString() const noexcept { - return "EulerAngles{ x: " + std::to_string(x) + " y: " + std::to_string(y) + " z: " + std::to_string(z) + " }"; + return fmt::format("ToEulerAngles{{ pitch = {0}, yaw = {1}, roll = {2} }}", pitch, yaw, roll); } std::string Quaternion::ToString() const noexcept { - return "Quaternion{ x: " + std::to_string(x) + " y: " + std::to_string(y) + " z: " + std::to_string(z) + " w: " + std::to_string(w) + " }"; + return fmt::format("ToQuaternion{{ i = {0}, j = {1}, k = {2}, r = {3} }}", i, j, k, r); } std::string CName::ToString() const noexcept { - return "CName{ hash: " + std::to_string(hash) + " - '" + RED4ext::REDreverse::CName::ToString(hash) + "' }"; + const auto resolved = RED4ext::REDreverse::CName::ToString(hash); + if (!resolved) + return fmt::format("ToCName{{ hash_lo = 0x{0:08X}, hash_hi = 0x{1:08X} }}", hash_lo, hash_hi); + return fmt::format("ToCName{{ hash_lo = 0x{0:08X}, hash_hi = 0x{1:08X} --['{1}']-- }}", hash_lo, hash_hi, resolved); } std::string TweakDBID::ToString() const noexcept { - std::ostringstream oss; - oss << std::hex << "TweakDBID{ hash: " << name_hash << ", length: " << name_length << ", unk5: " << unk5 << " unk7: " << (uint32_t)unk7 << " }"; - - return oss.str(); + return fmt::format("ToTweakDBID{{ hash = 0x{0:08X}, length = {1:d} }}", name_hash, name_length); } std::string ItemID::ToString() const noexcept { - std::ostringstream oss; - oss << std::hex << "ItemID{ id: " << id.ToString() << ", rngSeed: " << rngSeed << ", unkC: " << unkC << " maybeType: " << (uint32_t)maybeType << " }"; - - return oss.str(); + return fmt::format("ToItemID{{ id = {0}, rng_seed = {1}, unknown = {2}, maybe_type = {3} }}", id.ToString(), rng_seed, unknown, maybe_type); } static const unsigned int crc32_table[] = diff --git a/src/reverse/BasicTypes.h b/src/reverse/BasicTypes.h index 71c998c8..1d420aee 100644 --- a/src/reverse/BasicTypes.h +++ b/src/reverse/BasicTypes.h @@ -11,6 +11,19 @@ namespace RED4ext { } } +struct Vector3 +{ + Vector3(float aX = 0.f, float aY = 0.f, float aZ = 0.f) + : x(aX), y(aY), z(aZ) + {} + + float x; + float y; + float z; + + std::string ToString() const noexcept; +}; + struct Vector4 { Vector4(float aX = 0.f, float aY = 0.f, float aZ = 0.f, float aW = 0.f) @@ -27,27 +40,27 @@ struct Vector4 struct EulerAngles { - EulerAngles(float aX = 0.f, float aY = 0.f, float aZ = 0.f) - : x(aX), y(aY), z(aZ) + EulerAngles(float aPitch = 0.f, float aYaw = 0.f, float aRoll = 0.f) + : pitch(aPitch), yaw(aYaw), roll(aRoll) {} - float x; - float y; - float z; + float pitch; + float yaw; + float roll; std::string ToString() const noexcept; }; -struct Quaternion : Vector4 +struct Quaternion { - Quaternion(float aX = 0.f, float aY = 0.f, float aZ = 0.f, float aW = 0.f) - : Vector4(aX, aY, aZ, aW) + Quaternion(float aI = 0.f, float aJ = 0.f, float aK = 0.f, float aR = 0.f) + : i(aI), j(aJ), k(aK), r(aR) {} - float x; - float y; - float z; - float w; + float i; + float j; + float k; + float r; std::string ToString() const noexcept; }; @@ -71,8 +84,18 @@ struct WeakHandle struct CName { CName(uint64_t aHash = 0) : hash(aHash){} + CName(uint32_t aHashLo, uint32_t aHashHi) : hash_lo(aHashLo), hash_hi(aHashHi) {} CName(const std::string& aName) : hash(RED4ext::FNV1a(aName.c_str())){} - uint64_t hash; + + union + { + uint64_t hash; + struct + { + uint32_t hash_lo; + uint32_t hash_hi; + }; + }; std::string ToString() const noexcept; }; @@ -82,17 +105,17 @@ struct TweakDBID { TweakDBID() = default; - TweakDBID(uint32_t name_hash, uint8_t name_length, uint16_t unk5 = 0, uint8_t unk7 = 0) + TweakDBID(uint32_t aNameHash, uint8_t aNameLength) { - this->name_hash = name_hash; - this->name_length = name_length; - this->unk5 = unk5; - this->unk7 = unk7; + this->name_hash = aNameHash; + this->name_length = aNameLength; + this->unk5 = 0; + this->unk7 = 0; } - TweakDBID(uint64_t value) + TweakDBID(uint64_t aValue) { - this->value = value; + this->value = aValue; } TweakDBID(const std::string_view aName) @@ -102,10 +125,10 @@ struct TweakDBID unk5 = unk7 = 0; } - TweakDBID(const TweakDBID& base, const std::string_view aName) + TweakDBID(const TweakDBID& aBase, const std::string_view aName) { - name_hash = crc32(aName.data(), aName.size(), base.name_hash); - name_length = aName.size() + base.name_length; + name_hash = crc32(aName.data(), aName.size(), aBase.name_hash); + name_length = aName.size() + aBase.name_length; unk5 = unk7 = 0; } @@ -129,15 +152,16 @@ static_assert(sizeof(TweakDBID) == 8); struct ItemID { ItemID() = default; - ItemID(const TweakDBID& aId) : id(aId) {} + ItemID(const TweakDBID& aId, uint32_t aRngSeed = 2, uint16_t aUnknown = 0, uint8_t aMaybeType = 0) + : id(aId), rng_seed(aRngSeed), unknown(aUnknown), maybe_type(aMaybeType), pad(0) {} std::string ToString() const noexcept; TweakDBID id; - uint32_t rngSeed{ 2 }; - uint16_t unkC{ 0 }; - uint8_t maybeType{ 0 }; - uint8_t padF; + uint32_t rng_seed{ 2 }; + uint16_t unknown{ 0 }; + uint8_t maybe_type{ 0 }; + uint8_t pad; }; static_assert(sizeof(ItemID) == 0x10); diff --git a/src/reverse/Converter.cpp b/src/reverse/Converter.cpp index 54ae8116..ba4d43a6 100644 --- a/src/reverse/Converter.cpp +++ b/src/reverse/Converter.cpp @@ -17,6 +17,7 @@ auto s_metaVisitor = [](auto... args) { LuaRED(), LuaRED(), LuaRED(), + LuaRED(), LuaRED(), LuaRED(), LuaRED(), diff --git a/src/reverse/Scripting.cpp b/src/reverse/Scripting.cpp index 4550b4ed..169fe37d 100644 --- a/src/reverse/Scripting.cpp +++ b/src/reverse/Scripting.cpp @@ -72,40 +72,121 @@ Scripting::Scripting() "Dump", &GameOptions::Dump, "List", &GameOptions::List); + m_lua.new_usertype("Vector3", + sol::constructors(), + sol::meta_function::to_string, &Vector3::ToString, + "x", &Vector3::x, + "y", &Vector3::y, + "z", &Vector3::z); + + m_lua["ToVector3"] = [this](sol::table table) -> Vector3 + { + return Vector3 + { + table["x"].get_or(0.f), + table["y"].get_or(0.f), + table["z"].get_or(0.f) + }; + }; + m_lua.new_usertype("Vector4", - sol::constructors(), + sol::constructors(), sol::meta_function::to_string, &Vector4::ToString, "x", &Vector4::x, "y", &Vector4::y, "z", &Vector4::z, "w", &Vector4::w); + m_lua["ToVector4"] = [this](sol::table table) -> Vector4 + { + return Vector4 + { + table["x"].get_or(0.f), + table["y"].get_or(0.f), + table["z"].get_or(0.f), + table["w"].get_or(0.f) + }; + }; + m_lua.new_usertype("EulerAngles", - sol::constructors(), + sol::constructors(), sol::meta_function::to_string, &EulerAngles::ToString, - "x", &EulerAngles::x, - "y", &EulerAngles::y, - "z", &EulerAngles::z); + "pitch", &EulerAngles::pitch, + "yaw", &EulerAngles::yaw, + "roll", &EulerAngles::roll); + + m_lua["ToEulerAngles"] = [this](sol::table table) -> EulerAngles + { + return EulerAngles + { + table["pitch"].get_or(0.f), + table["roll"].get_or(0.f), + table["yaw"].get_or(0.f) + }; + }; m_lua.new_usertype("Quaternion", - sol::constructors(), + sol::constructors(), sol::meta_function::to_string, &Quaternion::ToString, - "x", &Quaternion::x, - "y", &Quaternion::y, - "z", &Quaternion::z, - "w", &Quaternion::w); + "i", &Quaternion::i, + "j", &Quaternion::j, + "k", &Quaternion::k, + "r", &Quaternion::r); + + m_lua["ToQuaternion"] = [this](sol::table table) -> Quaternion + { + return Quaternion + { + table["i"].get_or(0.f), + table["j"].get_or(0.f), + table["k"].get_or(0.f), + table["r"].get_or(0.f) + }; + }; m_lua.new_usertype("CName", - sol::constructors(), + sol::constructors(), sol::meta_function::to_string, &CName::ToString, - "hash", &CName::hash); + "hash_lo", &CName::hash_lo, + "hash_hi", &CName::hash_hi); + + m_lua["ToCName"] = [this](sol::table table) -> CName + { + return CName + { + table["hash_lo"].get_or(0), + table["hash_hi"].get_or(0) + }; + }; - m_lua.new_usertype("TweakDBID", sol::constructors(), + m_lua.new_usertype("TweakDBID", + sol::constructors(), sol::meta_function::to_string, &TweakDBID::ToString); - m_lua.new_usertype("ItemID", sol::constructors(), + m_lua["ToTweakDBID"] = [this](sol::table table) -> TweakDBID + { + return TweakDBID + { + table["hash"].get_or(0), + table["length"].get_or(0) + }; + }; + + m_lua.new_usertype("ItemID", + sol::constructors(), sol::meta_function::to_string, &ItemID::ToString); + m_lua["ToItemID"] = [this](sol::table table) -> ItemID + { + return ItemID + { + table["id"].get_or(0), + table["rng_seed"].get_or(2), + table["unknown"].get_or(0), + table["maybe_type"].get_or(0), + }; + }; + m_lua.new_usertype("Descriptor", sol::meta_function::to_string, &Type::Descriptor::ToString); @@ -135,10 +216,14 @@ Scripting::Scripting() { std::ostringstream oss; sol::state_view s(L); - for(auto v : args) + for (auto it = args.cbegin(); it != args.cend(); ++it) { - std::string str = s["tostring"](v.get()); - oss << str << " "; + if (it != args.cbegin()) + { + oss << " "; + } + std::string str = s["tostring"]((*it).get()); + oss << str; } Overlay::Get().Log(oss.str()); };