yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
automation.cc
Go to the documentation of this file.
2
8
9namespace yaze {
10namespace editor {
11
12// ============================================================================
13// Canvas Automation API Integration (Phase 4)
14// ============================================================================
15
17 auto* api = ow_map_canvas_.GetAutomationAPI();
18
19 // Set tile paint callback
20 api->SetTilePaintCallback([this](int x, int y, int tile_id) {
21 return AutomationSetTile(x, y, tile_id);
22 });
23
24 // Set tile query callback
25 api->SetTileQueryCallback(
26 [this](int x, int y) { return AutomationGetTile(x, y); });
27}
28
29bool OverworldEditor::AutomationSetTile(int x, int y, int tile_id) {
30 if (!overworld_.is_loaded()) {
31 return false;
32 }
33
34 // Bounds check
35 if (x < 0 || y < 0 || x >= 512 || y >= 512) {
36 return false;
37 }
38
39 // Set current world based on current_map_
42
43 // Set the tile in the overworld data structure
44 overworld_.SetTile(x, y, static_cast<uint16_t>(tile_id));
45
46 // Update the bitmap
47 auto tile_data = gfx::GetTilemapData(tile16_blockset_, tile_id);
48 if (!tile_data.empty()) {
49 tile_painting_->RenderUpdatedMapBitmap(
50 ImVec2(static_cast<float>(x * 16), static_cast<float>(y * 16)),
51 tile_data);
52 return true;
53 }
54
55 return false;
56}
57
59 if (!overworld_.is_loaded()) {
60 return -1;
61 }
62
63 // Bounds check
64 if (x < 0 || y < 0 || x >= 512 || y >= 512) {
65 return -1;
66 }
67
68 // Set current world
71
72 return overworld_.GetTile(x, y);
73}
74
75void OverworldEditor::HandleEntityInsertion(const std::string& entity_type) {
76 // Store for deferred processing outside context menu
77 // This is needed because ImGui::OpenPopup() doesn't work correctly when
78 // called from within another popup's callback (the context menu)
79 pending_insert_type_ = entity_type;
81
82 LOG_DEBUG("OverworldEditor",
83 "HandleEntityInsertion: queued type='%s' at pos=(%.0f,%.0f)",
84 entity_type.c_str(), pending_insert_pos_.x, pending_insert_pos_.y);
85}
86
88 if (pending_insert_type_.empty()) {
89 return;
90 }
91
92 if (!overworld_.is_loaded()) {
93 LOG_ERROR("OverworldEditor", "Cannot insert entity: overworld not loaded");
95 return;
96 }
97
98 const std::string& entity_type = pending_insert_type_;
99 ImVec2 mouse_pos = pending_insert_pos_;
100
101 LOG_DEBUG(
102 "OverworldEditor",
103 "ProcessPendingEntityInsertion: type='%s' at pos=(%.0f,%.0f) map=%d",
104 entity_type.c_str(), mouse_pos.x, mouse_pos.y, current_map_);
105
106 if (entity_type == "entrance") {
107 auto result = InsertEntrance(&overworld_, mouse_pos, current_map_, false);
108 if (result.ok()) {
109 auto* entrance = result.value();
110 edit_entrance_ = *entrance;
111 current_entity_ = entrance;
114 .c_str());
115 rom_->set_dirty(true);
116 LOG_DEBUG("OverworldEditor", "Entrance inserted successfully at map=%d",
118 } else {
120 "Cannot insert entrance: " + std::string(result.status().message());
121 ImGui::OpenPopup("Entity Insert Error");
122 LOG_ERROR("OverworldEditor", "Failed to insert entrance: %s",
123 result.status().message().data());
124 }
125
126 } else if (entity_type == "hole") {
127 auto result = InsertEntrance(&overworld_, mouse_pos, current_map_, true);
128 if (result.ok()) {
129 auto* entrance = result.value();
130 edit_entrance_ = *entrance;
131 current_entity_ = entrance;
134 .c_str());
135 rom_->set_dirty(true);
136 LOG_DEBUG("OverworldEditor", "Hole inserted successfully at map=%d",
138 } else {
140 "Cannot insert hole: " + std::string(result.status().message());
141 ImGui::OpenPopup("Entity Insert Error");
142 LOG_ERROR("OverworldEditor", "Failed to insert hole: %s",
143 result.status().message().data());
144 }
145
146 } else if (entity_type == "exit") {
147 auto result = InsertExit(&overworld_, mouse_pos, current_map_);
148 if (result.ok()) {
149 auto* exit = result.value();
150 edit_exit_ = *exit;
151 current_entity_ = exit;
154 .c_str());
155 rom_->set_dirty(true);
156 LOG_DEBUG("OverworldEditor", "Exit inserted successfully at map=%d",
158 } else {
160 "Cannot insert exit: " + std::string(result.status().message());
161 ImGui::OpenPopup("Entity Insert Error");
162 LOG_ERROR("OverworldEditor", "Failed to insert exit: %s",
163 result.status().message().data());
164 }
165
166 } else if (entity_type == "item") {
167 auto result = InsertItem(&overworld_, mouse_pos, current_map_, 0x00);
168 if (result.ok()) {
169 auto* item = result.value();
173 .c_str());
174 rom_->set_dirty(true);
175 LOG_DEBUG("OverworldEditor", "Item inserted successfully at map=%d",
177 } else {
179 "Cannot insert item: " + std::string(result.status().message());
180 ImGui::OpenPopup("Entity Insert Error");
181 LOG_ERROR("OverworldEditor", "Failed to insert item: %s",
182 result.status().message().data());
183 }
184
185 } else if (entity_type == "sprite") {
186 auto result =
187 InsertSprite(&overworld_, mouse_pos, current_map_, game_state_, 0x00);
188 if (result.ok()) {
189 auto* sprite = result.value();
190 edit_sprite_ = *sprite;
191 current_entity_ = sprite;
194 .c_str());
195 rom_->set_dirty(true);
196 LOG_DEBUG("OverworldEditor", "Sprite inserted successfully at map=%d",
198 } else {
200 "Cannot insert sprite: " + std::string(result.status().message());
201 ImGui::OpenPopup("Entity Insert Error");
202 LOG_ERROR("OverworldEditor", "Failed to insert sprite: %s",
203 result.status().message().data());
204 }
205
206 } else {
207 LOG_WARN("OverworldEditor", "Unknown entity type: %s", entity_type.c_str());
208 }
209
210 // Clear the pending state after processing
211 pending_insert_type_.clear();
212}
213
216 LOG_ERROR("OverworldEditor",
217 "Cannot edit tile16: overworld or blockset not loaded");
218 return;
219 }
220
221 // Simply open the tile16 editor - don't try to switch tiles here
222 // The tile16 editor will use its current tile, user can select a different one
225 }
226}
227
228} // namespace editor
229
230} // namespace yaze
void set_dirty(bool dirty)
Definition rom.h:134
EditorDependencies dependencies_
Definition editor.h:316
void HandleTile16Edit()
Handle tile16 editing from context menu (MOUSE mode) Gets the tile16 under the cursor and opens the T...
zelda3::OverworldEntrance edit_entrance_
void ProcessPendingEntityInsertion()
Process any pending entity insertion request Called from Update() - needed because ImGui::OpenPopup()...
Definition automation.cc:87
void HandleEntityInsertion(const std::string &entity_type)
Handle entity insertion from context menu.
Definition automation.cc:75
bool AutomationSetTile(int x, int y, int tile_id)
Definition automation.cc:29
std::unique_ptr< TilePaintingManager > tile_painting_
zelda3::GameEntity * current_entity_
zelda3::OverworldExit edit_exit_
int AutomationGetTile(int x, int y)
Definition automation.cc:58
bool SelectItemByIdentity(const zelda3::OverworldItem &item_identity)
Select an overworld item using value identity matching.
bool OpenWindow(size_t session_id, const std::string &base_window_id)
void SetTilePaintCallback(TilePaintCallback callback)
CanvasAutomationAPI * GetAutomationAPI()
Definition canvas.cc:2147
auto hover_mouse_pos() const
Definition canvas.h:555
void set_current_world(int world)
Definition overworld.h:604
auto is_loaded() const
Definition overworld.h:597
void set_current_map(int i)
Definition overworld.h:603
uint16_t GetTile(int x, int y) const
Definition overworld.h:605
void SetTile(int x, int y, uint16_t tile_id)
Definition overworld.h:614
#define LOG_DEBUG(category, format,...)
Definition log.h:103
#define LOG_ERROR(category, format,...)
Definition log.h:109
#define LOG_WARN(category, format,...)
Definition log.h:107
absl::StatusOr< zelda3::OverworldItem * > InsertItem(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, uint8_t item_id)
Insert a new item at the specified position.
absl::StatusOr< zelda3::OverworldEntrance * > InsertEntrance(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, bool is_hole)
Flat helper functions for entity insertion/manipulation.
absl::StatusOr< zelda3::OverworldExit * > InsertExit(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map)
Insert a new exit at the specified position.
absl::StatusOr< zelda3::Sprite * > InsertSprite(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, int game_state, uint8_t sprite_id)
Insert a new sprite at the specified position.
std::vector< uint8_t > GetTilemapData(Tilemap &tilemap, int tile_id)
Definition tilemap.cc:268
constexpr const char * kOverworld
Definition popup_id.h:53
constexpr const char * kSpriteEditor
Definition popup_id.h:71
constexpr const char * kItemEditor
Definition popup_id.h:70
constexpr const char * kExitEditor
Definition popup_id.h:69
constexpr const char * kEntranceEditor
Definition popup_id.h:68
std::string MakePopupId(size_t session_id, const std::string &editor_name, const std::string &popup_name)
Generate session-aware popup IDs to prevent conflicts in multi-editor layouts.
Definition popup_id.h:23
WorkspaceWindowManager * window_manager
Definition editor.h:176
static constexpr const char * kTile16Editor