yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_limits.h
Go to the documentation of this file.
1#ifndef YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
2#define YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
3
4// Canonical dungeon entity limits for ALTTP.
5//
6// All interaction handlers, validators, and tests should reference these
7// constants instead of defining their own copies.
8
9#include <cstddef>
10#include <limits>
11#include <map>
12#include <vector>
13
14namespace yaze::zelda3 {
15
16// Active sprites rendered per frame (SNES hardware/engine constraint).
17inline constexpr size_t kMaxActiveSprites = 16;
18
19// Total sprites in a room's sprite list (safety limit for ROM encoding).
20inline constexpr size_t kMaxTotalSprites = 64;
21
22// Maximum chests per room (item collection flag constraint).
23inline constexpr size_t kMaxChests = 6;
24
25// Maximum door objects per room (practical ROM encoding limit).
26inline constexpr size_t kMaxDoors = 16;
27
28// Maximum tile objects before processing lag on original hardware.
29inline constexpr size_t kMaxTileObjects = 400;
30
31// Sentinel for categories that are counted but intentionally not hard-limited.
32inline constexpr int kNoHardLimit = std::numeric_limits<int>::max();
33
34// Entity limit category for room validation queries.
35enum class DungeonLimit {
38 kDoors,
39 kChests,
40 // Extended categories used by Room::GetLimitedObjectCounts().
44 Blocks,
45 Torches,
51};
52
53// User-facing label for a limit category.
54inline constexpr const char* GetDungeonLimitLabel(DungeonLimit limit) {
55 switch (limit) {
57 return "Tile Objects";
59 return "Sprites";
61 return "Doors";
63 return "Chests";
65 return "Overlords";
67 return "Special Doors";
69 return "Stairs (Transition)";
71 return "Blocks";
73 return "Torches";
75 return "Star Tiles";
77 return "Somaria Line";
79 return "Stairs North";
81 return "Stairs South";
83 return "General Manipulable";
84 }
85 return "Unknown";
86}
87
88// Info about a specific exceeded limit (for UI display).
95
96// Get the maximum for a given limit category.
97inline constexpr int GetDungeonLimitMax(DungeonLimit limit) {
98 switch (limit) {
100 return static_cast<int>(kMaxTileObjects);
102 return static_cast<int>(kMaxTotalSprites);
104 return static_cast<int>(kMaxDoors);
106 return static_cast<int>(kMaxChests);
117 return kNoHardLimit;
118 }
119 return kNoHardLimit;
120}
121
122// Create a zero-initialized limit counter map.
123inline std::map<DungeonLimit, int> CreateLimitCounter() {
124 return {
129 };
130}
131
132// Check if any limit in the counter map is exceeded.
133inline bool HasExceededLimits(const std::map<DungeonLimit, int>& counts) {
134 for (const auto& [limit, count] : counts) {
135 const int max_val = GetDungeonLimitMax(limit);
136 if (max_val == kNoHardLimit) {
137 continue;
138 }
139 if (count > max_val) {
140 return true;
141 }
142 }
143 return false;
144}
145
146// Get details for all exceeded limits.
147inline std::vector<DungeonLimitInfo> GetExceededLimits(
148 const std::map<DungeonLimit, int>& counts) {
149 std::vector<DungeonLimitInfo> result;
150 for (const auto& [limit, count] : counts) {
151 const int max_val = GetDungeonLimitMax(limit);
152 if (max_val == kNoHardLimit) {
153 continue;
154 }
155 if (count > max_val) {
156 result.push_back({limit, count, max_val, GetDungeonLimitLabel(limit)});
157 }
158 }
159 return result;
160}
161
162} // namespace yaze::zelda3
163
164#endif // YAZE_SRC_ZELDA3_DUNGEON_DUNGEON_LIMITS_H_
Zelda 3 specific classes and functions.
std::vector< DungeonLimitInfo > GetExceededLimits(const std::map< DungeonLimit, int > &counts)
constexpr int kNoHardLimit
constexpr size_t kMaxTileObjects
constexpr int GetDungeonLimitMax(DungeonLimit limit)
bool HasExceededLimits(const std::map< DungeonLimit, int > &counts)
constexpr size_t kMaxDoors
constexpr size_t kMaxActiveSprites
constexpr const char * GetDungeonLimitLabel(DungeonLimit limit)
std::map< DungeonLimit, int > CreateLimitCounter()
constexpr size_t kMaxChests
constexpr size_t kMaxTotalSprites