yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_editor_system.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_DUNGEON_EDITOR_SYSTEM_H
2#define YAZE_APP_ZELDA3_DUNGEON_DUNGEON_EDITOR_SYSTEM_H
3
4#include <functional>
5#include <memory>
6#include <optional>
7#include <unordered_map>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "app/gfx/core/bitmap.h"
14#include "app/platform/window.h"
16#include "rom/rom.h"
17#include "zelda3/dungeon/room.h"
19#include "zelda3/game_data.h"
21
22namespace yaze {
23namespace zelda3 {
24
39 public:
40 // Editor modes
41 enum class EditorMode {
42 kObjects, // Object editing mode
43 kSprites, // Sprite editing mode
44 kItems, // Item placement mode
45 kEntrances, // Entrance/exit editing mode
46 kDoors, // Door configuration mode
47 kChests, // Chest management mode
48 kProperties, // Room properties mode
49 kGlobal // Dungeon-wide settings mode
50 };
51
52 // Sprite types and categories
53 enum class SpriteType {
54 kEnemy, // Hostile entities
55 kNPC, // Non-player characters
56 kInteractive, // Interactive objects
57 kDecoration, // Decorative sprites
58 kBoss, // Boss entities
59 kSpecial // Special purpose sprites
60 };
61
62 // Item types
63 enum class ItemType {
64 kWeapon, // Swords, bows, etc.
65 kTool, // Hookshot, bombs, etc.
66 kKey, // Keys and key items
67 kHeart, // Heart containers and pieces
68 kRupee, // Currency
69 kBottle, // Bottles and contents
70 kUpgrade, // Capacity upgrades
71 kSpecial // Special items
72 };
73
74 // Entrance/exit types
75 enum class EntranceType {
76 kNormal, // Standard room entrance
77 kStairs, // Staircase connection
78 kDoor, // Door connection
79 kCave, // Cave entrance
80 kWarp, // Warp/teleport
81 kBoss, // Boss room entrance
82 kSpecial // Special entrance type
83 };
84
85 // Editor state
86 struct EditorState {
89 bool is_dirty = false; // Has unsaved changes
90 bool auto_save_enabled = true;
91 std::chrono::steady_clock::time_point last_save_time;
92 };
93
94 // Sprite editing data
95 struct SpriteData {
97 std::string name;
99 int x, y;
100 int layer;
101 std::unordered_map<std::string, std::string> properties;
102 bool is_active = true;
103 };
104
105 // Item placement data
106 struct ItemData {
109 std::string name;
110 int x, y;
112 bool is_hidden = false;
113 std::unordered_map<std::string, std::string> properties;
114 };
115
116 // Entrance/exit data
120 std::string name;
125 bool is_bidirectional = true;
126 std::unordered_map<std::string, std::string> properties;
127 };
128
129 // Door configuration data
130 struct DoorData {
132 std::string name;
134 int x, y;
135 int direction; // 0=up, 1=right, 2=down, 3=left
138 bool requires_key = false;
139 int key_type = 0;
140 bool is_locked = false;
141 std::unordered_map<std::string, std::string> properties;
142 };
143
144 // Chest data
145 struct ChestData {
148 int x, y;
149 bool is_big_chest = false;
152 bool is_opened = false;
153 std::unordered_map<std::string, std::string> properties;
154 };
155
156 explicit DungeonEditorSystem(Rom* rom, GameData* game_data = nullptr);
158
159 void SetGameData(GameData* game_data) { game_data_ = game_data; }
160
161 // System initialization and management
162 absl::Status Initialize();
163 absl::Status LoadDungeon(int dungeon_id);
164 absl::Status SaveDungeon();
165 absl::Status SaveRoom(int room_id);
166 absl::Status ReloadRoom(int room_id);
167
168 // Mode management
169 void SetEditorMode(EditorMode mode);
171
172 // Room management
173 absl::Status SetCurrentRoom(int room_id);
174 int GetCurrentRoom() const;
175 absl::StatusOr<Room> GetRoom(int room_id);
176 absl::Status CreateRoom(int room_id, const std::string& name = "");
177 absl::Status DeleteRoom(int room_id);
178 absl::Status DuplicateRoom(int source_room_id, int target_room_id);
179
180 // Object editing (delegated to DungeonObjectEditor)
181 std::shared_ptr<DungeonObjectEditor> GetObjectEditor();
182 absl::Status SetObjectEditorMode();
183
184 // Sprite management
185 absl::Status AddSprite(const SpriteData& sprite_data);
186 absl::Status RemoveSprite(int sprite_id);
187 absl::Status UpdateSprite(int sprite_id, const SpriteData& sprite_data);
188 absl::StatusOr<SpriteData> GetSprite(int sprite_id);
189 absl::StatusOr<std::vector<SpriteData>> GetSpritesByRoom(int room_id);
190 absl::StatusOr<std::vector<SpriteData>> GetSpritesByType(
192 absl::Status MoveSprite(int sprite_id, int new_x, int new_y);
193 absl::Status SetSpriteActive(int sprite_id, bool active);
194
195 // Item management
196 absl::Status AddItem(const ItemData& item_data);
197 absl::Status RemoveItem(int item_id);
198 absl::Status UpdateItem(int item_id, const ItemData& item_data);
199 absl::StatusOr<ItemData> GetItem(int item_id);
200 absl::StatusOr<std::vector<ItemData>> GetItemsByRoom(int room_id);
201 absl::StatusOr<std::vector<ItemData>> GetItemsByType(
203 absl::Status MoveItem(int item_id, int new_x, int new_y);
204 absl::Status SetItemHidden(int item_id, bool hidden);
205
206 // Entrance/exit management
207 absl::Status AddEntrance(const EntranceData& entrance_data);
208 absl::Status RemoveEntrance(int entrance_id);
209 absl::Status UpdateEntrance(int entrance_id,
210 const EntranceData& entrance_data);
211 absl::StatusOr<EntranceData> GetEntrance(int entrance_id);
212 absl::StatusOr<std::vector<EntranceData>> GetEntrancesByRoom(int room_id);
213 absl::StatusOr<std::vector<EntranceData>> GetEntrancesByType(
215 absl::Status ConnectRooms(int room1_id, int room2_id, int x1, int y1, int x2,
216 int y2);
217 absl::Status DisconnectRooms(int room1_id, int room2_id);
218
219 // Door management
220 absl::Status AddDoor(const DoorData& door_data);
221 absl::Status RemoveDoor(int door_id);
222 absl::Status UpdateDoor(int door_id, const DoorData& door_data);
223 absl::StatusOr<DoorData> GetDoor(int door_id);
224 absl::StatusOr<std::vector<DoorData>> GetDoorsByRoom(int room_id);
225 absl::Status SetDoorLocked(int door_id, bool locked);
226 absl::Status SetDoorKeyRequirement(int door_id, bool requires_key,
227 int key_type);
228
229 // Chest management
230 absl::Status AddChest(const ChestData& chest_data);
231 absl::Status RemoveChest(int chest_id);
232 absl::Status UpdateChest(int chest_id, const ChestData& chest_data);
233 absl::StatusOr<ChestData> GetChest(int chest_id);
234 absl::StatusOr<std::vector<ChestData>> GetChestsByRoom(int room_id);
235 absl::Status SetChestItem(int chest_id, int item_id, int quantity);
236 absl::Status SetChestOpened(int chest_id, bool opened);
237
238 // Room properties and metadata
241 std::string name;
242 std::string description;
245 bool is_boss_room = false;
246 bool is_save_room = false;
247 bool is_shop_room = false;
248 int music_id = 0;
250 std::unordered_map<std::string, std::string> custom_properties;
251 };
252
253 absl::Status SetRoomProperties(int room_id, const RoomProperties& properties);
254 absl::StatusOr<RoomProperties> GetRoomProperties(int room_id);
255
256 // Dungeon-wide settings
259 std::string name;
260 std::string description;
266 bool has_map = true;
267 bool has_compass = true;
268 bool has_big_key = true;
269 std::unordered_map<std::string, std::string> custom_settings;
270 };
271
272 absl::Status SetDungeonSettings(const DungeonSettings& settings);
273 absl::StatusOr<DungeonSettings> GetDungeonSettings();
274
275 // Validation and error checking
276 absl::Status ValidateRoom(int room_id);
277 absl::Status ValidateDungeon();
278 std::vector<std::string> GetValidationErrors(int room_id);
279 std::vector<std::string> GetDungeonValidationErrors();
280
281 // Rendering and preview
282 absl::StatusOr<gfx::Bitmap> RenderRoom(int room_id);
283 absl::StatusOr<gfx::Bitmap> RenderRoomPreview(int room_id, EditorMode mode);
284 absl::StatusOr<gfx::Bitmap> RenderDungeonMap();
285
286 // Import/Export functionality
287 absl::Status ImportRoomFromFile(const std::string& file_path, int room_id);
288 absl::Status ExportRoomToFile(int room_id, const std::string& file_path);
289 absl::Status ImportDungeonFromFile(const std::string& file_path);
290 absl::Status ExportDungeonToFile(const std::string& file_path);
291
292 // Undo/Redo system
293 absl::Status Undo();
294 absl::Status Redo();
295 bool CanUndo() const;
296 bool CanRedo() const;
297 void ClearHistory();
298
299 // Event callbacks
300 using RoomChangedCallback = std::function<void(int room_id)>;
301 using SpriteChangedCallback = std::function<void(int sprite_id)>;
302 using ItemChangedCallback = std::function<void(int item_id)>;
303 using EntranceChangedCallback = std::function<void(int entrance_id)>;
304 using DoorChangedCallback = std::function<void(int door_id)>;
305 using ChestChangedCallback = std::function<void(int chest_id)>;
306 using ModeChangedCallback = std::function<void(EditorMode mode)>;
308 std::function<void(const std::vector<std::string>& errors)>;
309
318
319 // Getters
321 Rom* GetROM() const;
322 bool IsDirty() const;
323 bool HasUnsavedChanges() const;
324
325 // ROM management
326 void SetROM(Rom* rom);
327 void SetExternalRoom(Room* room);
328
329 private:
330 // Internal helper methods
333 absl::Status InitializeItemSystem();
335 absl::Status InitializeDoorSystem();
336 absl::Status InitializeChestSystem();
337
338 // Data management
339 absl::Status LoadRoomData(int room_id);
340 absl::Status SaveRoomData(int room_id);
341 absl::Status LoadSpriteData();
342 absl::Status SaveSpriteData();
343 absl::Status LoadItemData();
344 absl::Status SaveItemData();
345 absl::Status LoadEntranceData();
346 absl::Status SaveEntranceData();
347 absl::Status LoadDoorData();
348 absl::Status SaveDoorData();
349 absl::Status LoadChestData();
350 absl::Status SaveChestData();
351
352 // Validation helpers
353 absl::Status ValidateSprite(const SpriteData& sprite);
354 absl::Status ValidateItem(const ItemData& item);
355 absl::Status ValidateEntrance(const EntranceData& entrance);
356 absl::Status ValidateDoor(const DoorData& door);
357 absl::Status ValidateChest(const ChestData& chest);
358
359 // ID generation
360 int GenerateSpriteId();
361 int GenerateItemId();
362 int GenerateEntranceId();
363 int GenerateDoorId();
364 int GenerateChestId();
365
366 // Member variables
369 std::shared_ptr<DungeonObjectEditor> object_editor_;
370
373
374 // Data storage
375 std::unordered_map<int, Room> rooms_;
376 std::unordered_map<int, SpriteData> sprites_;
377 std::unordered_map<int, ItemData> items_;
378 std::unordered_map<int, EntranceData> entrances_;
379 std::unordered_map<int, DoorData> doors_;
380 std::unordered_map<int, ChestData> chests_;
381 std::unordered_map<int, RoomProperties> room_properties_;
382
383 // ID counters
389
390 // Event callbacks
399
400 // Undo/Redo system
401 struct UndoPoint {
403 std::unordered_map<int, Room> rooms;
404 std::unordered_map<int, SpriteData> sprites;
405 std::unordered_map<int, ItemData> items;
406 std::unordered_map<int, EntranceData> entrances;
407 std::unordered_map<int, DoorData> doors;
408 std::unordered_map<int, ChestData> chests;
409 std::chrono::steady_clock::time_point timestamp;
410 };
411
412 std::vector<UndoPoint> undo_history_;
413 std::vector<UndoPoint> redo_history_;
414 static constexpr size_t kMaxUndoHistory = 100;
415};
416
420std::unique_ptr<DungeonEditorSystem> CreateDungeonEditorSystem(
421 Rom* rom, GameData* game_data = nullptr);
422
426namespace SpriteTypes {
427
432 int id;
433 std::string name;
435 std::string description;
437 std::vector<std::pair<std::string, std::string>> default_properties;
441};
442
443absl::StatusOr<SpriteInfo> GetSpriteInfo(int sprite_id);
444std::vector<SpriteInfo> GetAllSpriteInfos();
446absl::StatusOr<std::string> GetSpriteCategory(int sprite_id);
447
448} // namespace SpriteTypes
449
453namespace ItemTypes {
454
458struct ItemInfo {
459 int id;
460 std::string name;
462 std::string description;
464 int value;
465 std::vector<std::pair<std::string, std::string>> default_properties;
468};
469
470absl::StatusOr<ItemInfo> GetItemInfo(int item_id);
471std::vector<ItemInfo> GetAllItemInfos();
473absl::StatusOr<std::string> GetItemCategory(int item_id);
474
475} // namespace ItemTypes
476
480namespace EntranceTypes {
481
486 int id;
487 std::string name;
489 std::string description;
490 std::vector<std::pair<std::string, std::string>> default_properties;
494};
495
496absl::StatusOr<EntranceInfo> GetEntranceInfo(int entrance_id);
497std::vector<EntranceInfo> GetAllEntranceInfos();
498std::vector<EntranceInfo> GetEntrancesByType(
500
501} // namespace EntranceTypes
502
503} // namespace zelda3
504} // namespace yaze
505
506#endif // YAZE_APP_ZELDA3_DUNGEON_DUNGEON_EDITOR_SYSTEM_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:24
Comprehensive dungeon editing system.
absl::StatusOr< DungeonSettings > GetDungeonSettings()
void SetSpriteChangedCallback(SpriteChangedCallback callback)
absl::Status UpdateItem(int item_id, const ItemData &item_data)
absl::Status DuplicateRoom(int source_room_id, int target_room_id)
absl::Status UpdateDoor(int door_id, const DoorData &door_data)
absl::StatusOr< EntranceData > GetEntrance(int entrance_id)
std::unordered_map< int, DoorData > doors_
absl::Status ExportRoomToFile(int room_id, const std::string &file_path)
std::function< void(const std::vector< std::string > &errors)> ValidationCallback
std::unordered_map< int, EntranceData > entrances_
absl::StatusOr< std::vector< SpriteData > > GetSpritesByType(DungeonEditorSystem::SpriteType type)
absl::Status SetRoomProperties(int room_id, const RoomProperties &properties)
absl::Status RemoveEntrance(int entrance_id)
absl::Status SetChestOpened(int chest_id, bool opened)
std::function< void(int sprite_id)> SpriteChangedCallback
std::unordered_map< int, SpriteData > sprites_
absl::StatusOr< std::vector< DoorData > > GetDoorsByRoom(int room_id)
std::function< void(int door_id)> DoorChangedCallback
absl::StatusOr< SpriteData > GetSprite(int sprite_id)
absl::Status MoveSprite(int sprite_id, int new_x, int new_y)
absl::Status ValidateChest(const ChestData &chest)
EntranceChangedCallback entrance_changed_callback_
absl::Status SetDoorKeyRequirement(int door_id, bool requires_key, int key_type)
void SetRoomChangedCallback(RoomChangedCallback callback)
absl::Status ValidateEntrance(const EntranceData &entrance)
void SetEntranceChangedCallback(EntranceChangedCallback callback)
std::vector< std::string > GetValidationErrors(int room_id)
absl::StatusOr< RoomProperties > GetRoomProperties(int room_id)
std::shared_ptr< DungeonObjectEditor > object_editor_
absl::Status AddSprite(const SpriteData &sprite_data)
EditorState GetEditorState() const
DungeonEditorSystem(Rom *rom, GameData *game_data=nullptr)
std::shared_ptr< DungeonObjectEditor > GetObjectEditor()
absl::Status SetSpriteActive(int sprite_id, bool active)
void SetChestChangedCallback(ChestChangedCallback callback)
absl::Status SetCurrentRoom(int room_id)
absl::StatusOr< std::vector< ItemData > > GetItemsByType(DungeonEditorSystem::ItemType type)
absl::Status ConnectRooms(int room1_id, int room2_id, int x1, int y1, int x2, int y2)
absl::StatusOr< gfx::Bitmap > RenderRoomPreview(int room_id, EditorMode mode)
absl::Status ValidateDoor(const DoorData &door)
std::vector< std::string > GetDungeonValidationErrors()
std::unordered_map< int, ChestData > chests_
std::unordered_map< int, ItemData > items_
absl::Status AddDoor(const DoorData &door_data)
std::function< void(int item_id)> ItemChangedCallback
absl::Status ValidateItem(const ItemData &item)
absl::StatusOr< std::vector< EntranceData > > GetEntrancesByRoom(int room_id)
absl::Status SetDungeonSettings(const DungeonSettings &settings)
absl::Status ValidateSprite(const SpriteData &sprite)
std::unordered_map< int, Room > rooms_
absl::Status ImportDungeonFromFile(const std::string &file_path)
absl::StatusOr< gfx::Bitmap > RenderRoom(int room_id)
absl::Status UpdateEntrance(int entrance_id, const EntranceData &entrance_data)
void SetModeChangedCallback(ModeChangedCallback callback)
absl::StatusOr< gfx::Bitmap > RenderDungeonMap()
absl::Status DisconnectRooms(int room1_id, int room2_id)
std::unordered_map< int, RoomProperties > room_properties_
absl::Status ExportDungeonToFile(const std::string &file_path)
std::function< void(EditorMode mode)> ModeChangedCallback
absl::Status RemoveSprite(int sprite_id)
absl::StatusOr< std::vector< ChestData > > GetChestsByRoom(int room_id)
absl::Status LoadDungeon(int dungeon_id)
absl::StatusOr< std::vector< ItemData > > GetItemsByRoom(int room_id)
std::function< void(int room_id)> RoomChangedCallback
absl::Status MoveItem(int item_id, int new_x, int new_y)
absl::StatusOr< ChestData > GetChest(int chest_id)
absl::StatusOr< DoorData > GetDoor(int door_id)
absl::Status SetChestItem(int chest_id, int item_id, int quantity)
absl::StatusOr< std::vector< SpriteData > > GetSpritesByRoom(int room_id)
absl::Status UpdateChest(int chest_id, const ChestData &chest_data)
void SetDoorChangedCallback(DoorChangedCallback callback)
std::function< void(int chest_id)> ChestChangedCallback
absl::Status UpdateSprite(int sprite_id, const SpriteData &sprite_data)
absl::StatusOr< std::vector< EntranceData > > GetEntrancesByType(DungeonEditorSystem::EntranceType type)
absl::Status SetItemHidden(int item_id, bool hidden)
void SetItemChangedCallback(ItemChangedCallback callback)
absl::Status CreateRoom(int room_id, const std::string &name="")
absl::Status AddEntrance(const EntranceData &entrance_data)
absl::Status ImportRoomFromFile(const std::string &file_path, int room_id)
absl::StatusOr< ItemData > GetItem(int item_id)
absl::Status AddChest(const ChestData &chest_data)
absl::StatusOr< Room > GetRoom(int room_id)
absl::Status SetDoorLocked(int door_id, bool locked)
void SetValidationCallback(ValidationCallback callback)
std::function< void(int entrance_id)> EntranceChangedCallback
absl::Status AddItem(const ItemData &item_data)
absl::StatusOr< EntranceInfo > GetEntranceInfo(int entrance_id)
std::vector< EntranceInfo > GetEntrancesByType(DungeonEditorSystem::EntranceType type)
std::vector< EntranceInfo > GetAllEntranceInfos()
absl::StatusOr< std::string > GetItemCategory(int item_id)
std::vector< ItemInfo > GetItemsByType(DungeonEditorSystem::ItemType type)
absl::StatusOr< ItemInfo > GetItemInfo(int item_id)
std::vector< ItemInfo > GetAllItemInfos()
std::vector< SpriteInfo > GetAllSpriteInfos()
std::vector< SpriteInfo > GetSpritesByType(DungeonEditorSystem::SpriteType type)
absl::StatusOr< SpriteInfo > GetSpriteInfo(int sprite_id)
absl::StatusOr< std::string > GetSpriteCategory(int sprite_id)
std::unique_ptr< DungeonEditorSystem > CreateDungeonEditorSystem(Rom *rom, GameData *game_data)
Factory function to create dungeon editor system.
Legacy chest data structure.
Definition zelda.h:438
Treasure chest.
Definition zelda.h:425
std::unordered_map< std::string, std::string > properties
std::unordered_map< std::string, std::string > properties
std::unordered_map< std::string, std::string > custom_settings
std::chrono::steady_clock::time_point last_save_time
std::unordered_map< std::string, std::string > properties
std::unordered_map< std::string, std::string > properties
std::unordered_map< std::string, std::string > custom_properties
std::unordered_map< std::string, std::string > properties
std::unordered_map< int, DoorData > doors
std::chrono::steady_clock::time_point timestamp
std::unordered_map< int, ChestData > chests
std::unordered_map< int, SpriteData > sprites
std::unordered_map< int, EntranceData > entrances
std::unordered_map< int, ItemData > items
std::vector< std::pair< std::string, std::string > > default_properties
std::vector< std::pair< std::string, std::string > > default_properties
DungeonEditorSystem::ItemType type
DungeonEditorSystem::SpriteType type
std::vector< std::pair< std::string, std::string > > default_properties