From 2240f559641b64c3c834aff5106c299760db3ee1 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Wed, 4 Feb 2026 21:32:34 +0800 Subject: [PATCH] feat: add new rule in BMapInspector --- Ballance/BMapInspector/CMakeLists.txt | 2 + Ballance/BMapInspector/Rule.cpp | 2 + Ballance/BMapInspector/Rule/SSBRules.cpp | 53 ++++++++++++++++++++++++ Ballance/BMapInspector/Rule/SSBRules.hpp | 22 ++++++++++ Ballance/BMapInspector/Rule/Shared.cpp | 13 +++--- Ballance/BMapInspector/Rule/Shared.hpp | 10 ++++- 6 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 Ballance/BMapInspector/Rule/SSBRules.cpp create mode 100644 Ballance/BMapInspector/Rule/SSBRules.hpp diff --git a/Ballance/BMapInspector/CMakeLists.txt b/Ballance/BMapInspector/CMakeLists.txt index ffde74e..0c19734 100644 --- a/Ballance/BMapInspector/CMakeLists.txt +++ b/Ballance/BMapInspector/CMakeLists.txt @@ -18,6 +18,7 @@ PRIVATE Rule/ZZQRules.cpp Rule/BBugRules.cpp Rule/SOneRules.cpp + Rule/SSBRules.cpp ) # Setup headers target_sources(BMapInspector @@ -38,6 +39,7 @@ FILES Rule/ZZQRules.hpp Rule/BBugRules.hpp Rule/SOneRules.hpp + Rule/SSBRules.hpp ) # Setup header infomation target_include_directories(BMapInspector diff --git a/Ballance/BMapInspector/Rule.cpp b/Ballance/BMapInspector/Rule.cpp index e5f6230..49a09ac 100644 --- a/Ballance/BMapInspector/Rule.cpp +++ b/Ballance/BMapInspector/Rule.cpp @@ -6,6 +6,7 @@ #include "Rule/BBugRules.hpp" #include "Rule/ZZQRules.hpp" #include "Rule/SOneRules.hpp" +#include "Rule/SSBRules.hpp" namespace BMapInspector::Rule { @@ -28,6 +29,7 @@ namespace BMapInspector::Rule { rules.emplace_back(new YYCRule1()); rules.emplace_back(new YYCRule2()); rules.emplace_back(new SOneRule1()); + rules.emplace_back(new SSBRule1()); // Add more rules... } diff --git a/Ballance/BMapInspector/Rule/SSBRules.cpp b/Ballance/BMapInspector/Rule/SSBRules.cpp new file mode 100644 index 0000000..2621ff5 --- /dev/null +++ b/Ballance/BMapInspector/Rule/SSBRules.cpp @@ -0,0 +1,53 @@ +#include "YYCRules.hpp" +#include "Shared.hpp" +#include "SSBRules.hpp" + +namespace L = LibCmo; +namespace C = LibCmo::CK2; +namespace V = LibCmo::VxMath; +namespace O = LibCmo::CK2::ObjImpls; + +namespace BMapInspector::Rule { +#pragma region SSB Rule 1 + + constexpr char8_t SSB1[] = u8"SSB1"; + constexpr L::CKFLOAT TOLERANCE = 0.001f; + + SSBRule1::SSBRule1() : IRule() {} + + SSBRule1::~SSBRule1() {} + + std::u8string_view SSBRule1::GetRuleName() const { + return SSB1; + } + + void SSBRule1::Check(Reporter::Reporter& reporter, Map::Level& level) const { + auto* ctx = level.GetCKContext(); + auto physicalized_3dobjects = Shared::FetchPhysicalized3dObjects(ctx); + + // Iterate all physicalized 3dobject + for (auto* physicalized_3dobject : physicalized_3dobjects) { + // Get its world matrix + const auto& matrix = physicalized_3dobject->GetWorldMatrix(); + // Extract 3 columns + V::VxVector3 col1(matrix[0][0], matrix[1][0], matrix[2][0]); + V::VxVector3 col2(matrix[0][1], matrix[1][1], matrix[2][1]); + V::VxVector3 col3(matrix[0][2], matrix[1][2], matrix[2][2]); + // Compute their length, then check their value with tolerance. + bool has_scale = false; + if (!Shared::FPEqual(col1.Length(), 1.0f, TOLERANCE)) has_scale = true; + if (!Shared::FPEqual(col2.Length(), 1.0f, TOLERANCE)) has_scale = true; + if (!Shared::FPEqual(col3.Length(), 1.0f, TOLERANCE)) has_scale = true; + // If it has scale factor, report error + if (has_scale) { + reporter.FormatError( + SSB1, + u8R"(Object "%s" grouped into physicalization groups has scale factor. This will cause its collision shape is different with its render shape.)", + Shared::RenderObjectName(physicalized_3dobject)); + } + } + } + +#pragma endregion + +} // namespace BMapInspector::Rule diff --git a/Ballance/BMapInspector/Rule/SSBRules.hpp b/Ballance/BMapInspector/Rule/SSBRules.hpp new file mode 100644 index 0000000..14a7f56 --- /dev/null +++ b/Ballance/BMapInspector/Rule/SSBRules.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "../Rule.hpp" + +namespace BMapInspector::Rule { + + /** + * @brief speedystoneball Rule 1 + * @details + * Pjysicalized object should not have scale factor, especially negative scale factor (mirror). + */ + class SSBRule1 : public IRule { + public: + SSBRule1(); + virtual ~SSBRule1(); + YYCC_DELETE_COPY_MOVE(SSBRule1) + + public: + std::u8string_view GetRuleName() const override; + void Check(Reporter::Reporter& reporter, Map::Level& level) const override; + }; + +} // namespace BMapInspector::Rule diff --git a/Ballance/BMapInspector/Rule/Shared.cpp b/Ballance/BMapInspector/Rule/Shared.cpp index 54b1140..7fbea23 100644 --- a/Ballance/BMapInspector/Rule/Shared.cpp +++ b/Ballance/BMapInspector/Rule/Shared.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace termcolor = yycc::carton::termcolor; @@ -9,12 +10,12 @@ namespace BMapInspector::Rule::Shared { #pragma region Check Functions - /** - * @brief - * @param[in] ctx Can not be nullptr. - * @param[in] name Can not be nullptr. - * @return Found pointer to CKGroup, otherwise nullptr. - */ + bool FPEqual(L::CKFLOAT lhs, L::CKFLOAT rhs, L::CKFLOAT tolerance) { + auto diff = lhs - rhs; + auto absolute_diff = std::fabs(diff); + return absolute_diff <= tolerance; + } + O::CKGroup* FetchGroup(C::CKContext* ctx, L::CKSTRING name) { return static_cast(ctx->GetObjectByNameAndClass(name, C::CK_CLASSID::CKCID_GROUP, nullptr)); } diff --git a/Ballance/BMapInspector/Rule/Shared.hpp b/Ballance/BMapInspector/Rule/Shared.hpp index 00c1b6d..5cbd1be 100644 --- a/Ballance/BMapInspector/Rule/Shared.hpp +++ b/Ballance/BMapInspector/Rule/Shared.hpp @@ -30,11 +30,19 @@ namespace BMapInspector::Rule::Shared { #pragma region Check Functions + /** + * @brief Check whether given 2 float point values are equal with given tolerance. + * @param lhs + * @param rhs + * @param tolerance + * @return + */ + bool FPEqual(L::CKFLOAT lhs, L::CKFLOAT rhs, L::CKFLOAT tolerance); /** * @brief * @param[in] ctx Can not be nullptr. * @param[in] name Can not be nullptr. - * @return + * @return Found pointer to CKGroup, otherwise nullptr. */ O::CKGroup* FetchGroup(C::CKContext* ctx, L::CKSTRING name); std::vector FetchPhysicalized3dObjects(C::CKContext* ctx);