feat: add new rule for BMapInspector
This commit is contained in:
@@ -19,6 +19,7 @@ PRIVATE
|
|||||||
Rule/BBugRules.cpp
|
Rule/BBugRules.cpp
|
||||||
Rule/SOneRules.cpp
|
Rule/SOneRules.cpp
|
||||||
Rule/SSBRules.cpp
|
Rule/SSBRules.cpp
|
||||||
|
Rule/LXRules.cpp
|
||||||
)
|
)
|
||||||
# Setup headers
|
# Setup headers
|
||||||
target_sources(BMapInspector
|
target_sources(BMapInspector
|
||||||
@@ -40,6 +41,7 @@ FILES
|
|||||||
Rule/BBugRules.hpp
|
Rule/BBugRules.hpp
|
||||||
Rule/SOneRules.hpp
|
Rule/SOneRules.hpp
|
||||||
Rule/SSBRules.hpp
|
Rule/SSBRules.hpp
|
||||||
|
Rule/LXRules.hpp
|
||||||
)
|
)
|
||||||
# Setup header infomation
|
# Setup header infomation
|
||||||
target_include_directories(BMapInspector
|
target_include_directories(BMapInspector
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Rule/ZZQRules.hpp"
|
#include "Rule/ZZQRules.hpp"
|
||||||
#include "Rule/SOneRules.hpp"
|
#include "Rule/SOneRules.hpp"
|
||||||
#include "Rule/SSBRules.hpp"
|
#include "Rule/SSBRules.hpp"
|
||||||
|
#include "Rule/LXRules.hpp"
|
||||||
|
|
||||||
namespace BMapInspector::Rule {
|
namespace BMapInspector::Rule {
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ namespace BMapInspector::Rule {
|
|||||||
rules.emplace_back(new YYCRule2());
|
rules.emplace_back(new YYCRule2());
|
||||||
rules.emplace_back(new SOneRule1());
|
rules.emplace_back(new SOneRule1());
|
||||||
rules.emplace_back(new SSBRule1());
|
rules.emplace_back(new SSBRule1());
|
||||||
|
rules.emplace_back(new LXRule1());
|
||||||
// Add more rules...
|
// Add more rules...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
Ballance/BMapInspector/Rule/LXRules.cpp
Normal file
119
Ballance/BMapInspector/Rule/LXRules.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "YYCRules.hpp"
|
||||||
|
#include "Shared.hpp"
|
||||||
|
#include "LXRules.hpp"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace L = LibCmo;
|
||||||
|
namespace C = LibCmo::CK2;
|
||||||
|
namespace O = LibCmo::CK2::ObjImpls;
|
||||||
|
|
||||||
|
namespace BMapInspector::Rule {
|
||||||
|
#pragma region LX Rule 1
|
||||||
|
|
||||||
|
constexpr char8_t LX1[] = u8"LX1";
|
||||||
|
|
||||||
|
LXRule1::LXRule1() : IRule() {}
|
||||||
|
|
||||||
|
LXRule1::~LXRule1() {}
|
||||||
|
|
||||||
|
std::u8string_view LXRule1::GetRuleName() const {
|
||||||
|
return LX1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LXRule1::Check(Reporter::Reporter& reporter, Map::Level& level) const {
|
||||||
|
auto* ctx = level.GetCKContext();
|
||||||
|
|
||||||
|
// First we fetch all Ballance element and push them into set.
|
||||||
|
std::set<O::CK3dObject*> elements;
|
||||||
|
for (auto* group_name : Shared::GroupNames::ALL_PH) {
|
||||||
|
auto* group = Shared::FetchGroup(ctx, group_name);
|
||||||
|
if (group == nullptr) continue;
|
||||||
|
auto group_objects = Shared::Iter3dObjects(group);
|
||||||
|
for (auto* group_object : group_objects) {
|
||||||
|
elements.emplace(group_object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then we analyse their mesh, material, texture and fill corresponding set.
|
||||||
|
std::set<O::CKMesh*> element_meshes;
|
||||||
|
std::set<O::CKMaterial*> element_materials;
|
||||||
|
std::set<O::CKTexture*> element_textures;
|
||||||
|
for (auto* element_object : elements) {
|
||||||
|
auto* mesh = element_object->GetCurrentMesh();
|
||||||
|
if (mesh == nullptr) continue;
|
||||||
|
|
||||||
|
// Add into mesh set
|
||||||
|
auto mesh_insert_rv = element_meshes.emplace(mesh);
|
||||||
|
|
||||||
|
// Only process it if we have inserted it
|
||||||
|
// because we do not want to duplicatedly process it.
|
||||||
|
if (mesh_insert_rv.second) {
|
||||||
|
// Iterate all meshes
|
||||||
|
auto mtls = Shared::IterMaterial(mesh);
|
||||||
|
for (auto* mtl : mtls) {
|
||||||
|
// Add into material set
|
||||||
|
auto mtl_insert_rv = element_materials.emplace(mtl);
|
||||||
|
|
||||||
|
// Also only process it if we have inserted it
|
||||||
|
if (mtl_insert_rv.second) {
|
||||||
|
// Fetch texture
|
||||||
|
auto texture = mtl->GetTexture();
|
||||||
|
if (texture == nullptr) continue;
|
||||||
|
// And insert it
|
||||||
|
element_textures.emplace(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, check any other object whether use these data.
|
||||||
|
for (auto* other_object : level.Get3dObjects()) {
|
||||||
|
// If it is element, skip it.
|
||||||
|
if (elements.contains(other_object)) continue;
|
||||||
|
|
||||||
|
// Get mesh
|
||||||
|
auto* mesh = other_object->GetCurrentMesh();
|
||||||
|
if (mesh == nullptr) continue;
|
||||||
|
// And check mesh
|
||||||
|
if (element_meshes.contains(mesh)) {
|
||||||
|
reporter.FormatError(
|
||||||
|
LX1,
|
||||||
|
u8R"(Object "%s" used mesh "%s" is already used by a Ballance element. This will cause this object can not be rendered correctly in level.)",
|
||||||
|
Shared::RenderObjectName(other_object),
|
||||||
|
Shared::RenderObjectName(mesh));
|
||||||
|
} else {
|
||||||
|
// If not, check material.
|
||||||
|
// Iterate all meshes
|
||||||
|
auto mtls = Shared::IterMaterial(mesh);
|
||||||
|
for (auto* mtl : mtls) {
|
||||||
|
if (element_materials.contains(mtl)) {
|
||||||
|
reporter.FormatError(
|
||||||
|
LX1,
|
||||||
|
u8R"(Object "%s" used material "%s" (referred by mesh "%s") is already used by a Ballance element. This will cause this object can not be rendered correctly in level.)",
|
||||||
|
Shared::RenderObjectName(other_object),
|
||||||
|
Shared::RenderObjectName(mtl),
|
||||||
|
Shared::RenderObjectName(mesh));
|
||||||
|
} else {
|
||||||
|
// Still not, check texture.
|
||||||
|
// Fetch texture
|
||||||
|
auto texture = mtl->GetTexture();
|
||||||
|
if (texture == nullptr) continue;
|
||||||
|
// And check it
|
||||||
|
if (element_textures.contains(texture)) {
|
||||||
|
reporter.FormatError(
|
||||||
|
LX1,
|
||||||
|
u8R"(Object "%s" used texture "%s" (referred by mesh "%s" and material "%s") is already used by a Ballance element. This will cause this object can not be rendered correctly in level.)",
|
||||||
|
Shared::RenderObjectName(other_object),
|
||||||
|
Shared::RenderObjectName(texture),
|
||||||
|
Shared::RenderObjectName(mesh),
|
||||||
|
Shared::RenderObjectName(mtl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
} // namespace BMapInspector::Rule
|
||||||
22
Ballance/BMapInspector/Rule/LXRules.hpp
Normal file
22
Ballance/BMapInspector/Rule/LXRules.hpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../Rule.hpp"
|
||||||
|
|
||||||
|
namespace BMapInspector::Rule {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LengXi Rule 1
|
||||||
|
* @details
|
||||||
|
* All meshes, materials and textures used by Ballance elements should not be used by any other objects.
|
||||||
|
*/
|
||||||
|
class LXRule1 : public IRule {
|
||||||
|
public:
|
||||||
|
LXRule1();
|
||||||
|
virtual ~LXRule1();
|
||||||
|
YYCC_DELETE_COPY_MOVE(LXRule1)
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::u8string_view GetRuleName() const override;
|
||||||
|
void Check(Reporter::Reporter& reporter, Map::Level& level) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,6 +29,13 @@ namespace BMapInspector::Rule {
|
|||||||
for (auto* physicalized_3dobject : physicalized_3dobjects) {
|
for (auto* physicalized_3dobject : physicalized_3dobjects) {
|
||||||
// Get its world matrix
|
// Get its world matrix
|
||||||
const auto& matrix = physicalized_3dobject->GetWorldMatrix();
|
const auto& matrix = physicalized_3dobject->GetWorldMatrix();
|
||||||
|
|
||||||
|
// YYC MARK:
|
||||||
|
// Following method is the bad way to check scale factor,
|
||||||
|
// because it rely on some premise.
|
||||||
|
// But it is simple, especially we do not have fully implement VxMatrix,
|
||||||
|
// or have any linear algebra library.
|
||||||
|
|
||||||
// Extract 3 columns
|
// Extract 3 columns
|
||||||
V::VxVector3 col1(matrix[0][0], matrix[1][0], matrix[2][0]);
|
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 col2(matrix[0][1], matrix[1][1], matrix[2][1]);
|
||||||
|
|||||||
@@ -16,6 +16,37 @@ namespace BMapInspector::Rule::Shared {
|
|||||||
constexpr char8_t PHYS_FLOORS[] = u8"Phys_Floors";
|
constexpr char8_t PHYS_FLOORS[] = u8"Phys_Floors";
|
||||||
constexpr char8_t PHYS_FLOORRAILS[] = u8"Phys_FloorRails";
|
constexpr char8_t PHYS_FLOORRAILS[] = u8"Phys_FloorRails";
|
||||||
constexpr char8_t PHYS_FLOORSTOPPER[] = u8"Phys_FloorStopper";
|
constexpr char8_t PHYS_FLOORSTOPPER[] = u8"Phys_FloorStopper";
|
||||||
|
|
||||||
|
constexpr std::array ALL_PH{
|
||||||
|
u8"P_Extra_Life",
|
||||||
|
u8"P_Extra_Point",
|
||||||
|
u8"P_Trafo_Paper",
|
||||||
|
u8"P_Trafo_Stone",
|
||||||
|
u8"P_Trafo_Wood",
|
||||||
|
u8"P_Ball_Paper",
|
||||||
|
u8"P_Ball_Stone",
|
||||||
|
u8"P_Ball_Wood",
|
||||||
|
u8"P_Box",
|
||||||
|
u8"P_Dome",
|
||||||
|
u8"P_Modul_01",
|
||||||
|
u8"P_Modul_03",
|
||||||
|
u8"P_Modul_08",
|
||||||
|
u8"P_Modul_17",
|
||||||
|
u8"P_Modul_18",
|
||||||
|
u8"P_Modul_19",
|
||||||
|
u8"P_Modul_25",
|
||||||
|
u8"P_Modul_26",
|
||||||
|
u8"P_Modul_29",
|
||||||
|
u8"P_Modul_30",
|
||||||
|
u8"P_Modul_34",
|
||||||
|
u8"P_Modul_37",
|
||||||
|
u8"P_Modul_41",
|
||||||
|
u8"PS_Levelstart",
|
||||||
|
u8"PE_Levelende",
|
||||||
|
u8"PC_Checkpoints",
|
||||||
|
u8"PR_Resetpoints",
|
||||||
|
};
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
} // namespace GroupNames
|
} // namespace GroupNames
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace BMapInspector::Rule {
|
|||||||
// No, this is not rail texture, throw error.
|
// No, this is not rail texture, throw error.
|
||||||
reporter.FormatError(
|
reporter.FormatError(
|
||||||
YYC1,
|
YYC1,
|
||||||
u8R"(Object "%s" is grouped into Phys_FloorRails, but its texture "%s" (referred by mesh %s and material %s) seems not the rail texture. This will cause this object be smooth unexpectly.)",
|
u8R"(Object "%s" is grouped into Phys_FloorRails, but its texture "%s" (referred by mesh %s and material %s) seems not the rail texture. This will cause some parts of this object be smooth unexpectly.)",
|
||||||
Shared::RenderObjectName(group_3dobject),
|
Shared::RenderObjectName(group_3dobject),
|
||||||
Shared::RenderObjectName(texture),
|
Shared::RenderObjectName(texture),
|
||||||
Shared::RenderObjectName(mesh),
|
Shared::RenderObjectName(mesh),
|
||||||
|
|||||||
Reference in New Issue
Block a user