6#include "absl/strings/str_format.h"
14 if (
rom_ ==
nullptr) {
15 return absl::InvalidArgumentError(
"ROM is null");
31 return absl::OkStatus();
41 return absl::OkStatus();
49 return absl::OkStatus();
54 return absl::OkStatus();
59 return absl::OkStatus();
72 return absl::InvalidArgumentError(
"Invalid room ID");
76 return absl::OkStatus();
85 return absl::InvalidArgumentError(
"Invalid room ID");
94 return absl::OkStatus();
99 return absl::OkStatus();
104 return absl::OkStatus();
116 return absl::OkStatus();
129 return absl::OkStatus();
135 return absl::NotFoundError(
"Sprite not found");
139 return absl::OkStatus();
145 return absl::NotFoundError(
"Sprite not found");
148 it->second = sprite_data;
155 return absl::OkStatus();
161 return absl::NotFoundError(
"Sprite not found");
168 std::vector<SpriteData> room_sprites;
170 for (
const auto& [
id, sprite] :
sprites_) {
171 if (sprite.x >= 0 && sprite.y >= 0) {
172 room_sprites.push_back(sprite);
180 std::vector<SpriteData> typed_sprites;
182 for (
const auto& [
id, sprite] :
sprites_) {
183 if (sprite.type == type) {
184 typed_sprites.push_back(sprite);
188 return typed_sprites;
194 return absl::NotFoundError(
"Sprite not found");
197 it->second.x = new_x;
198 it->second.y = new_y;
204 return absl::OkStatus();
210 return absl::NotFoundError(
"Sprite not found");
213 it->second.is_active = active;
219 return absl::OkStatus();
225 items_[item_id] = item_data;
232 return absl::OkStatus();
236 auto it =
items_.find(item_id);
238 return absl::NotFoundError(
"Item not found");
242 return absl::OkStatus();
246 auto it =
items_.find(item_id);
248 return absl::NotFoundError(
"Item not found");
251 it->second = item_data;
258 return absl::OkStatus();
262 auto it =
items_.find(item_id);
264 return absl::NotFoundError(
"Item not found");
271 std::vector<ItemData> room_items;
273 for (
const auto& [
id, item] :
items_) {
274 if (item.room_id == room_id) {
275 room_items.push_back(item);
283 std::vector<ItemData> typed_items;
285 for (
const auto& [
id, item] :
items_) {
286 if (item.type == type) {
287 typed_items.push_back(item);
295 auto it =
items_.find(item_id);
297 return absl::NotFoundError(
"Item not found");
300 it->second.x = new_x;
301 it->second.y = new_y;
307 return absl::OkStatus();
311 auto it =
items_.find(item_id);
313 return absl::NotFoundError(
"Item not found");
316 it->second.is_hidden = hidden;
322 return absl::OkStatus();
335 return absl::OkStatus();
341 return absl::NotFoundError(
"Entrance not found");
345 return absl::OkStatus();
351 return absl::NotFoundError(
"Entrance not found");
354 it->second = entrance_data;
361 return absl::OkStatus();
367 return absl::NotFoundError(
"Entrance not found");
374 std::vector<EntranceData> room_entrances;
376 for (
const auto& [
id, entrance] :
entrances_) {
377 if (entrance.source_room_id == room_id || entrance.target_room_id == room_id) {
378 room_entrances.push_back(entrance);
382 return room_entrances;
386 std::vector<EntranceData> typed_entrances;
388 for (
const auto& [
id, entrance] :
entrances_) {
389 if (entrance.type == type) {
390 typed_entrances.push_back(entrance);
394 return typed_entrances;
414 const auto& entrance = it->second;
415 if ((entrance.source_room_id == room1_id && entrance.target_room_id == room2_id) ||
416 (entrance.source_room_id == room2_id && entrance.target_room_id == room1_id)) {
423 return absl::OkStatus();
429 doors_[door_id] = door_data;
436 return absl::OkStatus();
440 auto it =
doors_.find(door_id);
442 return absl::NotFoundError(
"Door not found");
446 return absl::OkStatus();
450 auto it =
doors_.find(door_id);
452 return absl::NotFoundError(
"Door not found");
455 it->second = door_data;
462 return absl::OkStatus();
466 auto it =
doors_.find(door_id);
468 return absl::NotFoundError(
"Door not found");
475 std::vector<DoorData> room_doors;
477 for (
const auto& [
id, door] :
doors_) {
478 if (door.room_id == room_id) {
479 room_doors.push_back(door);
487 auto it =
doors_.find(door_id);
489 return absl::NotFoundError(
"Door not found");
492 it->second.is_locked = locked;
498 return absl::OkStatus();
502 auto it =
doors_.find(door_id);
504 return absl::NotFoundError(
"Door not found");
507 it->second.requires_key = requires_key;
508 it->second.key_type = key_type;
514 return absl::OkStatus();
521 chests_[chest_id].chest_id = chest_id;
527 return absl::OkStatus();
531 auto it =
chests_.find(chest_id);
533 return absl::NotFoundError(
"Chest not found");
537 return absl::OkStatus();
541 auto it =
chests_.find(chest_id);
543 return absl::NotFoundError(
"Chest not found");
547 it->second.chest_id = chest_id;
553 return absl::OkStatus();
557 auto it =
chests_.find(chest_id);
559 return absl::NotFoundError(
"Chest not found");
566 std::vector<ChestData> room_chests;
569 if (
chest.room_id == room_id) {
570 room_chests.push_back(
chest);
578 auto it =
chests_.find(chest_id);
580 return absl::NotFoundError(
"Chest not found");
583 it->second.item_id = item_id;
584 it->second.item_quantity = quantity;
590 return absl::OkStatus();
594 auto it =
chests_.find(chest_id);
596 return absl::NotFoundError(
"Chest not found");
599 it->second.is_opened = opened;
605 return absl::OkStatus();
616 return absl::OkStatus();
624 default_properties.
room_id = room_id;
625 default_properties.
name = absl::StrFormat(
"Room %d", room_id);
634 return default_properties;
643 return absl::OkStatus();
653 return absl::OkStatus();
658 return absl::OkStatus();
690 return absl::OkStatus();
695 return absl::OkStatus();
700 return absl::OkStatus();
705 return absl::OkStatus();
711 return absl::FailedPreconditionError(
"Nothing to undo");
715 return absl::OkStatus();
720 return absl::FailedPreconditionError(
"Nothing to redo");
724 return absl::OkStatus();
812 return std::make_unique<DungeonEditorSystem>(rom);
The Rom class is used to load, save, and modify Rom data.
Represents a bitmap image optimized for SNES ROM hacking.
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)
int GetCurrentRoom() const
absl::StatusOr< EntranceData > GetEntrance(int entrance_id)
absl::Status SaveRoom(int room_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::Status ValidateRoom(int room_id)
absl::StatusOr< std::vector< SpriteData > > GetSpritesByType(DungeonEditorSystem::SpriteType type)
DungeonEditorSystem(Rom *rom)
absl::Status SetRoomProperties(int room_id, const RoomProperties &properties)
absl::Status RemoveEntrance(int entrance_id)
RoomChangedCallback room_changed_callback_
absl::Status SetChestOpened(int chest_id, bool opened)
std::function< void(int sprite_id)> SpriteChangedCallback
std::unordered_map< int, SpriteData > sprites_
absl::Status SaveDungeon()
absl::StatusOr< std::vector< DoorData > > GetDoorsByRoom(int room_id)
std::function< void(int door_id)> DoorChangedCallback
absl::Status RemoveItem(int item_id)
absl::StatusOr< SpriteData > GetSprite(int sprite_id)
void SetEditorMode(EditorMode mode)
DungeonSettings dungeon_settings_
SpriteChangedCallback sprite_changed_callback_
absl::Status MoveSprite(int sprite_id, int new_x, int new_y)
EntranceChangedCallback entrance_changed_callback_
absl::Status SetDoorKeyRequirement(int door_id, bool requires_key, int key_type)
void SetRoomChangedCallback(RoomChangedCallback callback)
void SetEntranceChangedCallback(EntranceChangedCallback callback)
std::vector< std::string > GetValidationErrors(int room_id)
ModeChangedCallback mode_changed_callback_
absl::StatusOr< RoomProperties > GetRoomProperties(int room_id)
std::shared_ptr< DungeonObjectEditor > object_editor_
absl::Status AddSprite(const SpriteData &sprite_data)
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::Status ValidateDungeon()
absl::StatusOr< gfx::Bitmap > RenderRoomPreview(int room_id, EditorMode mode)
absl::Status DeleteRoom(int room_id)
absl::Status RemoveDoor(int door_id)
std::vector< std::string > GetDungeonValidationErrors()
std::unordered_map< int, ChestData > chests_
std::unordered_map< int, ItemData > items_
absl::Status AddDoor(const DoorData &door_data)
absl::Status RemoveChest(int chest_id)
EditorMode GetEditorMode() const
std::function< void(int item_id)> ItemChangedCallback
absl::StatusOr< std::vector< EntranceData > > GetEntrancesByRoom(int room_id)
absl::Status SetDungeonSettings(const DungeonSettings &settings)
absl::Status ImportDungeonFromFile(const std::string &file_path)
absl::StatusOr< gfx::Bitmap > RenderRoom(int room_id)
ItemChangedCallback item_changed_callback_
EditorState editor_state_
absl::Status UpdateEntrance(int entrance_id, const EntranceData &entrance_data)
std::vector< UndoPoint > redo_history_
void SetModeChangedCallback(ModeChangedCallback callback)
absl::Status Initialize()
absl::StatusOr< gfx::Bitmap > RenderDungeonMap()
absl::Status SetObjectEditorMode()
absl::Status DisconnectRooms(int room1_id, int room2_id)
ValidationCallback validation_callback_
std::unordered_map< int, RoomProperties > room_properties_
absl::Status ExportDungeonToFile(const std::string &file_path)
absl::Status ReloadRoom(int room_id)
DoorChangedCallback door_changed_callback_
std::vector< UndoPoint > undo_history_
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)
ChestChangedCallback chest_changed_callback_
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)
constexpr int NumberOfRooms
std::unique_ptr< DungeonEditorSystem > CreateDungeonEditorSystem(Rom *rom)
Factory function to create dungeon editor system.
Main namespace for the application.
Legacy chest data structure.
std::chrono::steady_clock::time_point last_save_time
DungeonEditorSystem::EntranceType type