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()) {
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_entity_insert_type_ = entity_type;
81
82 LOG_DEBUG("OverworldEditor",
83 "HandleEntityInsertion: queued type='%s' at pos=(%.0f,%.0f)",
84 entity_type.c_str(), pending_entity_insert_pos_.x,
86}
87
89 if (pending_entity_insert_type_.empty()) {
90 return;
91 }
92
93 if (!overworld_.is_loaded()) {
94 LOG_ERROR("OverworldEditor", "Cannot insert entity: overworld not loaded");
96 return;
97 }
98
99 const std::string& entity_type = pending_entity_insert_type_;
100 ImVec2 mouse_pos = pending_entity_insert_pos_;
101
102 LOG_DEBUG("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 current_entrance_ = **result;
110 current_entity_ = *result;
111 ImGui::OpenPopup(
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 current_entrance_ = **result;
130 current_entity_ = *result;
131 ImGui::OpenPopup(
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 current_exit_ = **result;
150 current_entity_ = *result;
151 ImGui::OpenPopup(
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 current_item_ = **result;
170 current_entity_ = *result;
171 ImGui::OpenPopup(
174 .c_str());
175 rom_->set_dirty(true);
176 LOG_DEBUG("OverworldEditor", "Item inserted successfully at map=%d",
178 } else {
180 "Cannot insert item: " + std::string(result.status().message());
181 ImGui::OpenPopup("Entity Insert Error");
182 LOG_ERROR("OverworldEditor", "Failed to insert item: %s",
183 result.status().message().data());
184 }
185
186 } else if (entity_type == "sprite") {
187 auto result =
188 InsertSprite(&overworld_, mouse_pos, current_map_, game_state_, 0x00);
189 if (result.ok()) {
190 current_sprite_ = **result;
191 current_entity_ = *result;
192 ImGui::OpenPopup(
195 .c_str());
196 rom_->set_dirty(true);
197 LOG_DEBUG("OverworldEditor", "Sprite inserted successfully at map=%d",
199 } else {
201 "Cannot insert sprite: " + std::string(result.status().message());
202 ImGui::OpenPopup("Entity Insert Error");
203 LOG_ERROR("OverworldEditor", "Failed to insert sprite: %s",
204 result.status().message().data());
205 }
206
207 } else {
208 LOG_WARN("OverworldEditor", "Unknown entity type: %s", entity_type.c_str());
209 }
210
211 // Clear the pending state after processing
213}
214
217 LOG_ERROR("OverworldEditor", "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 yaze::editor
229
230}
void set_dirty(bool dirty)
Definition rom.h:130
EditorDependencies dependencies_
Definition editor.h:237
zelda3::OverworldItem current_item_
zelda3::OverworldEntrance current_entrance_
void HandleTile16Edit()
Handle tile16 editing from context menu (MOUSE mode) Gets the tile16 under the cursor and opens the T...
void ProcessPendingEntityInsertion()
Process any pending entity insertion request Called from Update() - needed because ImGui::OpenPopup()...
Definition automation.cc:88
void HandleEntityInsertion(const std::string &entity_type)
Handle entity insertion from context menu.
Definition automation.cc:75
zelda3::OverworldExit current_exit_
void RenderUpdatedMapBitmap(const ImVec2 &click_position, const std::vector< uint8_t > &tile_data)
bool AutomationSetTile(int x, int y, int tile_id)
Definition automation.cc:29
zelda3::GameEntity * current_entity_
int AutomationGetTile(int x, int y)
Definition automation.cc:58
bool ShowPanel(size_t session_id, const std::string &base_card_id)
void SetTilePaintCallback(TilePaintCallback callback)
CanvasAutomationAPI * GetAutomationAPI()
Definition canvas.cc:2065
auto hover_mouse_pos() const
Definition canvas.h:558
void set_current_world(int world)
Definition overworld.h:535
auto is_loaded() const
Definition overworld.h:528
void set_current_map(int i)
Definition overworld.h:534
uint16_t GetTile(int x, int y) const
Definition overworld.h:536
void SetTile(int x, int y, uint16_t tile_id)
Definition overworld.h:545
#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:270
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
static constexpr const char * kTile16Editor