yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_validator.cc
Go to the documentation of this file.
1#include "dungeon_validator.h"
2
3#include "absl/strings/str_format.h"
5
6namespace yaze {
7namespace zelda3 {
8
10 ValidationResult result;
11
12 // Check object count
13 size_t object_count = room.GetTileObjects().size();
14 if (object_count > kMaxTileObjects) {
15 result.warnings.push_back(absl::StrFormat(
16 "High object count (%zu > %d). May cause lag or memory issues.",
17 object_count, kMaxTileObjects));
18 }
19
20 // Check sprite count
21 size_t sprite_count = room.GetSprites().size();
22 if (sprite_count > kMaxTotalSprites) {
23 result.warnings.push_back(
24 absl::StrFormat("Too many sprites (%zu > %d). Game limit is strict.",
25 sprite_count, kMaxTotalSprites));
26 }
27
28 // Check chest count (approximate, based on object ID)
29 int chest_count = 0;
30 for (const auto& obj : room.GetTileObjects()) {
31 // Check for Big Chest (0xE4?? No, let's trust standard ranges)
32 // ZScream logic for chests:
33 // 0xF9 = Small Key Chest
34 // 0xFA = Big Key Chest
35 // 0xFB = Map Chest
36 // 0xFC = Compass Chest
37 // 0xFD = Big Chest
38 // But simple chest objects are also common.
39 // Let's count objects in the 0xF9-0xFD range as chests for now.
40 if (obj.id_ >= 0xF9 && obj.id_ <= 0xFD) {
41 chest_count++;
42 }
43 }
44
45 if (chest_count > kMaxChests) {
46 result.errors.push_back(absl::StrFormat(
47 "Too many chests (%d > %d). Item collection flags will conflict.",
48 chest_count, kMaxChests));
49 result.is_valid = false;
50 }
51
52 // Check bounds
53 int bg3_count = 0;
54 for (const auto& obj : room.GetTileObjects()) {
55 const int layer = static_cast<int>(obj.GetLayerValue());
56 if (layer < 0 || layer > 2) {
57 result.errors.push_back(absl::StrFormat(
58 "Object 0x%02X has invalid layer %d", obj.id_, layer));
59 result.is_valid = false;
60 } else if (layer == 2) {
61 ++bg3_count;
62 }
63
64 const auto semantics = GetObjectLayerSemantics(obj);
65 if (layer == 2 && semantics.draws_to_both_bgs) {
66 result.errors.push_back(absl::StrFormat(
67 "Object 0x%02X in BG3 is marked as Both-BGs (unsafe layer state)",
68 obj.id_));
69 result.is_valid = false;
70 }
71
72 if (obj.x_ < 0 || obj.x_ >= 64 || obj.y_ < 0 || obj.y_ >= 64) {
73 result.errors.push_back(absl::StrFormat(
74 "Object 0x%02X out of bounds at (%d, %d)", obj.id_, obj.x_, obj.y_));
75 result.is_valid = false;
76 }
77 }
78
79 if (bg3_count > kMaxBg3Objects) {
80 result.errors.push_back(absl::StrFormat(
81 "Too many BG3 objects (%d > %d). Reduce background-layer object count.",
82 bg3_count, kMaxBg3Objects));
83 result.is_valid = false;
84 }
85
86 return result;
87}
88
89} // namespace zelda3
90} // namespace yaze
ValidationResult ValidateRoom(const Room &room)
const std::vector< zelda3::Sprite > & GetSprites() const
Definition room.h:214
const std::vector< RoomObject > & GetTileObjects() const
Definition room.h:314
ObjectLayerSemantics GetObjectLayerSemantics(const RoomObject &object)
constexpr size_t kMaxBg3Objects
constexpr size_t kMaxTileObjects
constexpr size_t kMaxChests
constexpr size_t kMaxTotalSprites
std::vector< std::string > errors
std::vector< std::string > warnings