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 <memory>
5#include <vector>
6#include <unordered_map>
7#include <functional>
8#include <optional>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "app/core/window.h"
13#include "app/gfx/bitmap.h"
15#include "app/rom.h"
20
21namespace yaze {
22namespace zelda3 {
23
38 public:
39 // Editor modes
40 enum class EditorMode {
41 kObjects, // Object editing mode
42 kSprites, // Sprite editing mode
43 kItems, // Item placement mode
44 kEntrances, // Entrance/exit editing mode
45 kDoors, // Door configuration mode
46 kChests, // Chest management mode
47 kProperties, // Room properties mode
48 kGlobal // Dungeon-wide settings mode
49 };
50
51 // Sprite types and categories
52 enum class SpriteType {
53 kEnemy, // Hostile entities
54 kNPC, // Non-player characters
55 kInteractive, // Interactive objects
56 kDecoration, // Decorative sprites
57 kBoss, // Boss entities
58 kSpecial // Special purpose sprites
59 };
60
61 // Item types
62 enum class ItemType {
63 kWeapon, // Swords, bows, etc.
64 kTool, // Hookshot, bombs, etc.
65 kKey, // Keys and key items
66 kHeart, // Heart containers and pieces
67 kRupee, // Currency
68 kBottle, // Bottles and contents
69 kUpgrade, // Capacity upgrades
70 kSpecial // Special items
71 };
72
73 // Entrance/exit types
74 enum class EntranceType {
75 kNormal, // Standard room entrance
76 kStairs, // Staircase connection
77 kDoor, // Door connection
78 kCave, // Cave entrance
79 kWarp, // Warp/teleport
80 kBoss, // Boss room entrance
81 kSpecial // Special entrance type
82 };
83
84 // Editor state
85 struct EditorState {
88 bool is_dirty = false; // Has unsaved changes
89 bool auto_save_enabled = true;
90 std::chrono::steady_clock::time_point last_save_time;
91 };
92
93 // Sprite editing data
94 struct SpriteData {
96 std::string name;
98 int x, y;
99 int layer;
100 std::unordered_map<std::string, std::string> properties;
101 bool is_active = true;
102 };
103
104 // Item placement data
105 struct ItemData {
108 std::string name;
109 int x, y;
111 bool is_hidden = false;
112 std::unordered_map<std::string, std::string> properties;
113 };
114
115 // Entrance/exit data
119 std::string name;
124 bool is_bidirectional = true;
125 std::unordered_map<std::string, std::string> properties;
126 };
127
128 // Door configuration data
129 struct DoorData {
131 std::string name;
133 int x, y;
134 int direction; // 0=up, 1=right, 2=down, 3=left
137 bool requires_key = false;
138 int key_type = 0;
139 bool is_locked = false;
140 std::unordered_map<std::string, std::string> properties;
141 };
142
143 // Chest data
144 struct ChestData {
147 int x, y;
148 bool is_big_chest = false;
151 bool is_opened = false;
152 std::unordered_map<std::string, std::string> properties;
153 };
154
155 explicit DungeonEditorSystem(Rom* rom);
157
158 // System initialization and management
159 absl::Status Initialize();
160 absl::Status LoadDungeon(int dungeon_id);
161 absl::Status SaveDungeon();
162 absl::Status SaveRoom(int room_id);
163 absl::Status ReloadRoom(int room_id);
164
165 // Mode management
166 void SetEditorMode(EditorMode mode);
168
169 // Room management
170 absl::Status SetCurrentRoom(int room_id);
171 int GetCurrentRoom() const;
172 absl::StatusOr<Room> GetRoom(int room_id);
173 absl::Status CreateRoom(int room_id, const std::string& name = "");
174 absl::Status DeleteRoom(int room_id);
175 absl::Status DuplicateRoom(int source_room_id, int target_room_id);
176
177 // Object editing (delegated to DungeonObjectEditor)
178 std::shared_ptr<DungeonObjectEditor> GetObjectEditor();
179 absl::Status SetObjectEditorMode();
180
181 // Sprite management
182 absl::Status AddSprite(const SpriteData& sprite_data);
183 absl::Status RemoveSprite(int sprite_id);
184 absl::Status UpdateSprite(int sprite_id, const SpriteData& sprite_data);
185 absl::StatusOr<SpriteData> GetSprite(int sprite_id);
186 absl::StatusOr<std::vector<SpriteData>> GetSpritesByRoom(int room_id);
187 absl::StatusOr<std::vector<SpriteData>> GetSpritesByType(DungeonEditorSystem::SpriteType type);
188 absl::Status MoveSprite(int sprite_id, int new_x, int new_y);
189 absl::Status SetSpriteActive(int sprite_id, bool active);
190
191 // Item management
192 absl::Status AddItem(const ItemData& item_data);
193 absl::Status RemoveItem(int item_id);
194 absl::Status UpdateItem(int item_id, const ItemData& item_data);
195 absl::StatusOr<ItemData> GetItem(int item_id);
196 absl::StatusOr<std::vector<ItemData>> GetItemsByRoom(int room_id);
197 absl::StatusOr<std::vector<ItemData>> GetItemsByType(DungeonEditorSystem::ItemType type);
198 absl::Status MoveItem(int item_id, int new_x, int new_y);
199 absl::Status SetItemHidden(int item_id, bool hidden);
200
201 // Entrance/exit management
202 absl::Status AddEntrance(const EntranceData& entrance_data);
203 absl::Status RemoveEntrance(int entrance_id);
204 absl::Status UpdateEntrance(int entrance_id, const EntranceData& entrance_data);
205 absl::StatusOr<EntranceData> GetEntrance(int entrance_id);
206 absl::StatusOr<std::vector<EntranceData>> GetEntrancesByRoom(int room_id);
207 absl::StatusOr<std::vector<EntranceData>> GetEntrancesByType(DungeonEditorSystem::EntranceType type);
208 absl::Status ConnectRooms(int room1_id, int room2_id, int x1, int y1, int x2, int y2);
209 absl::Status DisconnectRooms(int room1_id, int room2_id);
210
211 // Door management
212 absl::Status AddDoor(const DoorData& door_data);
213 absl::Status RemoveDoor(int door_id);
214 absl::Status UpdateDoor(int door_id, const DoorData& door_data);
215 absl::StatusOr<DoorData> GetDoor(int door_id);
216 absl::StatusOr<std::vector<DoorData>> GetDoorsByRoom(int room_id);
217 absl::Status SetDoorLocked(int door_id, bool locked);
218 absl::Status SetDoorKeyRequirement(int door_id, bool requires_key, int key_type);
219
220 // Chest management
221 absl::Status AddChest(const ChestData& chest_data);
222 absl::Status RemoveChest(int chest_id);
223 absl::Status UpdateChest(int chest_id, const ChestData& chest_data);
224 absl::StatusOr<ChestData> GetChest(int chest_id);
225 absl::StatusOr<std::vector<ChestData>> GetChestsByRoom(int room_id);
226 absl::Status SetChestItem(int chest_id, int item_id, int quantity);
227 absl::Status SetChestOpened(int chest_id, bool opened);
228
229 // Room properties and metadata
232 std::string name;
233 std::string description;
236 bool is_boss_room = false;
237 bool is_save_room = false;
238 bool is_shop_room = false;
239 int music_id = 0;
241 std::unordered_map<std::string, std::string> custom_properties;
242 };
243
244 absl::Status SetRoomProperties(int room_id, const RoomProperties& properties);
245 absl::StatusOr<RoomProperties> GetRoomProperties(int room_id);
246
247 // Dungeon-wide settings
250 std::string name;
251 std::string description;
257 bool has_map = true;
258 bool has_compass = true;
259 bool has_big_key = true;
260 std::unordered_map<std::string, std::string> custom_settings;
261 };
262
263 absl::Status SetDungeonSettings(const DungeonSettings& settings);
264 absl::StatusOr<DungeonSettings> GetDungeonSettings();
265
266 // Validation and error checking
267 absl::Status ValidateRoom(int room_id);
268 absl::Status ValidateDungeon();
269 std::vector<std::string> GetValidationErrors(int room_id);
270 std::vector<std::string> GetDungeonValidationErrors();
271
272 // Rendering and preview
273 absl::StatusOr<gfx::Bitmap> RenderRoom(int room_id);
274 absl::StatusOr<gfx::Bitmap> RenderRoomPreview(int room_id, EditorMode mode);
275 absl::StatusOr<gfx::Bitmap> RenderDungeonMap();
276
277 // Import/Export functionality
278 absl::Status ImportRoomFromFile(const std::string& file_path, int room_id);
279 absl::Status ExportRoomToFile(int room_id, const std::string& file_path);
280 absl::Status ImportDungeonFromFile(const std::string& file_path);
281 absl::Status ExportDungeonToFile(const std::string& file_path);
282
283 // Undo/Redo system
284 absl::Status Undo();
285 absl::Status Redo();
286 bool CanUndo() const;
287 bool CanRedo() const;
288 void ClearHistory();
289
290 // Event callbacks
291 using RoomChangedCallback = std::function<void(int room_id)>;
292 using SpriteChangedCallback = std::function<void(int sprite_id)>;
293 using ItemChangedCallback = std::function<void(int item_id)>;
294 using EntranceChangedCallback = std::function<void(int entrance_id)>;
295 using DoorChangedCallback = std::function<void(int door_id)>;
296 using ChestChangedCallback = std::function<void(int chest_id)>;
297 using ModeChangedCallback = std::function<void(EditorMode mode)>;
298 using ValidationCallback = std::function<void(const std::vector<std::string>& errors)>;
299
308
309 // Getters
311 Rom* GetROM() const;
312 bool IsDirty() const;
313 bool HasUnsavedChanges() const;
314
315 // ROM management
316 void SetROM(Rom* rom);
317
318 private:
319 // Internal helper methods
322 absl::Status InitializeItemSystem();
324 absl::Status InitializeDoorSystem();
325 absl::Status InitializeChestSystem();
326
327 // Data management
328 absl::Status LoadRoomData(int room_id);
329 absl::Status SaveRoomData(int room_id);
330 absl::Status LoadSpriteData();
331 absl::Status SaveSpriteData();
332 absl::Status LoadItemData();
333 absl::Status SaveItemData();
334 absl::Status LoadEntranceData();
335 absl::Status SaveEntranceData();
336 absl::Status LoadDoorData();
337 absl::Status SaveDoorData();
338 absl::Status LoadChestData();
339 absl::Status SaveChestData();
340
341 // Validation helpers
342 absl::Status ValidateSprite(const SpriteData& sprite);
343 absl::Status ValidateItem(const ItemData& item);
344 absl::Status ValidateEntrance(const EntranceData& entrance);
345 absl::Status ValidateDoor(const DoorData& door);
346 absl::Status ValidateChest(const ChestData& chest);
347
348 // ID generation
349 int GenerateSpriteId();
350 int GenerateItemId();
351 int GenerateEntranceId();
352 int GenerateDoorId();
353 int GenerateChestId();
354
355 // Member variables
357 std::shared_ptr<DungeonObjectEditor> object_editor_;
358
361
362 // Data storage
363 std::unordered_map<int, Room> rooms_;
364 std::unordered_map<int, SpriteData> sprites_;
365 std::unordered_map<int, ItemData> items_;
366 std::unordered_map<int, EntranceData> entrances_;
367 std::unordered_map<int, DoorData> doors_;
368 std::unordered_map<int, ChestData> chests_;
369 std::unordered_map<int, RoomProperties> room_properties_;
370
371 // ID counters
377
378 // Event callbacks
387
388 // Undo/Redo system
389 struct UndoPoint {
391 std::unordered_map<int, Room> rooms;
392 std::unordered_map<int, SpriteData> sprites;
393 std::unordered_map<int, ItemData> items;
394 std::unordered_map<int, EntranceData> entrances;
395 std::unordered_map<int, DoorData> doors;
396 std::unordered_map<int, ChestData> chests;
397 std::chrono::steady_clock::time_point timestamp;
398 };
399
400 std::vector<UndoPoint> undo_history_;
401 std::vector<UndoPoint> redo_history_;
402 static constexpr size_t kMaxUndoHistory = 100;
403};
404
408std::unique_ptr<DungeonEditorSystem> CreateDungeonEditorSystem(Rom* rom);
409
413namespace SpriteTypes {
414
419 int id;
420 std::string name;
422 std::string description;
424 std::vector<std::pair<std::string, std::string>> default_properties;
428};
429
430absl::StatusOr<SpriteInfo> GetSpriteInfo(int sprite_id);
431std::vector<SpriteInfo> GetAllSpriteInfos();
433absl::StatusOr<std::string> GetSpriteCategory(int sprite_id);
434
435} // namespace SpriteTypes
436
440namespace ItemTypes {
441
445struct ItemInfo {
446 int id;
447 std::string name;
449 std::string description;
451 int value;
452 std::vector<std::pair<std::string, std::string>> default_properties;
455};
456
457absl::StatusOr<ItemInfo> GetItemInfo(int item_id);
458std::vector<ItemInfo> GetAllItemInfos();
460absl::StatusOr<std::string> GetItemCategory(int item_id);
461
462} // namespace ItemTypes
463
467namespace EntranceTypes {
468
473 int id;
474 std::string name;
476 std::string description;
477 std::vector<std::pair<std::string, std::string>> default_properties;
481};
482
483absl::StatusOr<EntranceInfo> GetEntranceInfo(int entrance_id);
484std::vector<EntranceInfo> GetAllEntranceInfos();
486
487} // namespace EntranceTypes
488
489} // namespace zelda3
490} // namespace yaze
491
492#endif // YAZE_APP_ZELDA3_DUNGEON_DUNGEON_EDITOR_SYSTEM_H
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
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)
absl::Status SaveRoomData(int room_id)
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
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)
absl::Status LoadRoomData(int room_id)
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)
Factory function to create dungeon editor system.
Main namespace for the application.
Legacy chest data structure.
Definition zelda.h:437
Treasure chest.
Definition zelda.h:424
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