55 auto* editor = ctx.editor;
56 if (editor->is_lyra_preview()) {
57 ImGui::TextDisabled(
"Lyra preview: entity editing unavailable");
63 const Rom* rom = editor->rom();
72 :
"Inspect special entrances")) {
74 rom ? std::optional<zelda3::SpecialEntranceInspection>(
76 editor->current_map_id()))
84 if (!inspection.available) {
85 ImGui::TextWrapped(
"%s", inspection.provenance.c_str());
87 ImGui::Text(
"%zu matching positions", inspection.matches.size());
88 for (
size_t i = 0; i < inspection.matches.size(); ++i) {
89 const auto& match = inspection.matches[i];
90 const auto& row = inspection.rows[match.row_index];
92 const std::string name =
97 :
"Unresolved destination";
98 ImGui::PushID(
static_cast<int>(i));
99 if (ImGui::Button(absl::StrFormat(
"%s ($%02X) - tile (%d,%d)", name,
103 editor->LocateOverworldTile(match.screen_id, match.world_x,
108 if (ImGui::TreeNode(
"Technical details and provenance")) {
109 ImGui::TextWrapped(
"%s", inspection.provenance.c_str());
110 ImGui::TextWrapped(
"%s", inspection.limitation.c_str());
111 if (inspection.overlay_may_replace_tiles) {
113 "This area has an overlay; the runtime sampled "
114 "tile may depend on overlay state.");
116 for (
const auto& match : inspection.matches) {
117 const auto& row = inspection.rows[match.row_index];
119 "Screen $%02X parent $%02X at (%d,%d): Map16 $%03X, "
120 "word $%04X, mask $%03X -> fake exit $%04X "
121 "(arrival direction $%04X)",
122 match.screen_id, match.parent_area, match.tile_x, match.tile_y,
123 match.tile16_id, match.first_word, match.masked_trigger,
124 row.destination_marker, row.direction);
126 if (ImGui::Button(
"Copy special entrance details")) {
127 std::string details = inspection.provenance +
"\n";
128 for (
const auto& match : inspection.matches) {
129 const auto& row = inspection.rows[match.row_index];
130 details += absl::StrFormat(
131 "screen=$%02X parent=$%02X tile=(%d,%d) map16=$%03X "
132 "word=$%04X mask=$%03X marker=$%04X\n",
133 match.screen_id, match.parent_area, match.tile_x, match.tile_y,
134 match.tile16_id, match.first_word, match.masked_trigger,
135 row.destination_marker);
137 ImGui::SetClipboardText(details.c_str());
145 auto* active_entity = editor->current_entity();
146 if (active_entity ==
nullptr) {
147 ImGui::TextDisabled(tr(
"No entity selected"));
151 ImGui::Text(tr(
"Type: %s"), GetEntityTypeLabel(active_entity->entity_type_));
220 auto* editor = ctx.editor;
228 if (entity_to_edit) {
232 if (ImGui::BeginPopupModal(
"Entity Insert Error",
nullptr,
233 ImGuiWindowFlags_AlwaysAutoResize)) {
234 ImGui::TextWrapped(
"%s", editor->insert_error().c_str());
236 if (ImGui::Button(tr(
"OK"), ImVec2(120.0f, 0.0f))) {
237 editor->insert_error().clear();
238 ImGui::CloseCurrentPopup();
244 if (editing_entity &&
248 editor->NotifyEntityModified(editing_entity);
252 if (editing_entity && editing_entity->entity_type_ ==
255 editor->edit_entrance();
256 editor->NotifyEntityModified(editing_entity);
260 if (editing_entity &&
262 if (editor->edit_item().deleted) {
263 (void)editor->DeleteSelectedItem();
267 editor->NotifyEntityModified(editing_entity);
272 if (editing_entity && editing_entity->entity_type_ ==
274 *
static_cast<zelda3::Sprite*
>(editing_entity) = editor->edit_sprite();
275 editor->NotifyEntityModified(editing_entity);
279 const bool exit_popup_open = ImGui::IsPopupOpen(
281 const bool entrance_popup_open = ImGui::IsPopupOpen(
284 const bool item_popup_open = ImGui::IsPopupOpen(
286 const bool sprite_popup_open = ImGui::IsPopupOpen(
288 if (!exit_popup_open && !entrance_popup_open && !item_popup_open &&
289 !sprite_popup_open) {
322 auto* editor = ctx.editor;
323 auto* active_entity = editor->current_entity();
328 std::vector<gui::MenuItemSpec> items;
331 [&entity_to_edit, active_entity]() { entity_to_edit = active_entity; });
335 items.emplace_back(
"Jump to Room",
ICON_MD_LINK, [editor, exit]() {
336 editor->RequestJumpToRoom(exit->room_id_);
338 }
else if (active_entity->entity_type_ ==
341 items.emplace_back(
"Jump to Entrance",
ICON_MD_LINK, [editor, entrance]() {
342 editor->RequestJumpToEntrance(entrance->entrance_id_);
346 return entity_to_edit;
MutationResult InsertEntity(const std::string &type, ImVec2 pos, int map_id, int game_state, uint8_t item_id=0)
Dispatches entity insertion based on type string.
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.