yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_context_actions.cc
Go to the documentation of this file.
2
7#include "util/i18n/tr.h"
9
10namespace yaze::editor {
11
13 const ImVec2& screen_position) {
14 auto& canvas = editor_->ow_map_canvas_;
15 canvas.ClearContextMenuItems();
17 return false;
18 }
19 // Select tool: plain right-click. Paint tools: right-click samples, so
20 // only Shift+right-click opens the menu.
21 const bool menu_gesture =
22 editor_->current_mode == EditingMode::MOUSE || ImGui::GetIO().KeyShift;
23 if (!editor_->rom_ || !editor_->rom_->is_loaded() ||
25 !menu_gesture ||
27 editor_->entity_renderer_->hovered_entity() != nullptr)) {
28 return false;
29 }
31 editor_->current_world_, editor_->game_state_, screen_position,
32 canvas.zero_point(), canvas.scrolling(), canvas.global_scale(),
34 if (!target) {
35 return false;
36 }
37 const auto* map = editor_->overworld_.overworld_map(target->map_id);
38 if (!map) {
39 if (editor_->IsProjectTerrainMap(target->map_id)) {
40 target->parent_map_id = target->map_id;
41 } else {
42 return false;
43 }
44 } else {
45 target->parent_map_id =
46 map->parent() == 0xFF ? target->map_id : map->parent();
47 }
48 if (!target->valid(editor_->DisplayedMapCount())) {
49 return false;
50 }
51 const auto* tiles = editor_->overworld_.mutable_map_tiles();
52 const auto& world_tiles = target->world == 0 ? tiles->light_world
53 : target->world == 1 ? tiles->dark_world
54 : tiles->special_world;
55 const int x = static_cast<int>(target->world_position.x) / 16;
56 const int y = static_cast<int>(target->world_position.y) / 16;
57 if (editor_->IsProjectTerrainMap(target->map_id) &&
59 auto project_tile = editor_->lyra_canvas_.document()->tile(x, y - 128);
60 if (project_tile.ok()) {
61 target->tile16_id = *project_tile;
62 }
63 } else if (x < static_cast<int>(world_tiles.size()) &&
64 y < static_cast<int>(world_tiles[x].size())) {
65 target->tile16_id = world_tiles[x][y];
66 }
67 editor_->map_properties_system_->SetupCanvasContextMenu(
68 canvas, *target, editor_->current_map_lock_,
71 return true;
72}
73
75 const std::string& entity_type, const OverworldContextTarget& target) {
76 if (!target.valid()) {
77 return;
78 }
79 if (entity_type == "item") {
81 return;
82 }
84 OverworldEntityInsertionRequest{entity_type, target, 0};
85}
86
88 const OverworldContextTarget& target) {
89 if (!target.valid() || !overworld_.is_loaded() || !map_blockset_loaded_ ||
90 target.tile16_id < 0 ||
91 target.tile16_id >= static_cast<int>(overworld_.tiles16().size())) {
92 return false;
93 }
94 // Use the existing switch guard so pending Tile16 edits are preserved.
97 return true;
98}
99
101 const OverworldContextTarget& target) {
102 if (!target.valid() || !overworld_.is_loaded() || target.tile16_id < 0 ||
103 target.tile16_id >= static_cast<int>(overworld_.tiles16().size())) {
104 return absl::InvalidArgumentError("The clicked Tile16 is unavailable");
105 }
106 // Explicit source navigation uses the clicked screen even when another map
107 // is pinned. The context target was captured before menu hover can change it.
108 const int previous_map = current_map_;
109 SelectMapForEditing(target.map_id, /*respect_pin=*/false);
110 if (!status_.ok()) {
111 const auto failure = status_;
112 SelectMapForEditing(previous_map, /*respect_pin=*/false);
113 return failure;
114 }
115 const int quadrant =
116 (static_cast<int>(target.world_position.x) % 16 >= 8 ? 1 : 0) +
117 (static_cast<int>(target.world_position.y) % 16 >= 8 ? 2 : 0);
118 const auto result = OpenGraphicsForTile16Quadrant(target.tile16_id, quadrant);
119 if (!result.ok()) {
120 // A floating paste or unsupported source must not leave navigation on the
121 // clicked map when the Graphics editor refused the new context.
122 SelectMapForEditing(previous_map, /*respect_pin=*/false);
123 }
124 return result;
125}
126
128 const std::optional<OverworldContextTarget>& target) {
129 item_insert_target_ = target;
131}
132
135 ImGui::OpenPopup("Insert Item");
137 }
138 if (!ImGui::BeginPopup("Insert Item")) {
139 return;
140 }
141 if (current_map_ >= 0xA0 && current_map_ < 0xC0) {
142 ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f),
143 "Item Placement Unavailable ($%02X)", current_map_);
144 ImGui::TextWrapped(
145 "Persistent event storage (SRAM $7EF000-$7EF4FF) is not yet allocated "
146 "for maps $A0-$BF.");
147 if (ImGui::Button("Close")) {
148 ImGui::CloseCurrentPopup();
149 }
150 ImGui::EndPopup();
151 return;
152 }
153 ImGui::TextUnformatted(tr("Choose an item"));
154 ImGui::BeginChild("##ItemInsertList", ImVec2(220.0f, 220.0f),
155 ImGuiChildFlags_Borders);
156 for (size_t i = 0; i < zelda3::kSecretItemNames.size(); ++i) {
157 if (ImGui::Selectable(zelda3::kSecretItemNames[i].c_str())) {
158 const auto item_id = static_cast<uint8_t>(i);
161 "item", *item_insert_target_, item_id};
162 item_placement_armed_ = false;
163 } else {
164 armed_item_id_ = item_id;
167 }
168 item_insert_target_.reset();
169 ImGui::CloseCurrentPopup();
170 }
171 }
172 ImGui::EndChild();
173 if (!item_insert_target_) {
174 ImGui::TextDisabled(tr("Click the map to place the item."));
175 }
176 ImGui::EndPopup();
177}
178
181 !ImGui::IsMouseClicked(ImGuiMouseButton_Left) ||
183 return false;
184 }
185 if (entity_renderer_ && entity_renderer_->hovered_entity() != nullptr) {
186 return false;
187 }
188 const float scale = ow_map_canvas_.global_scale() > 0.0f
190 : 1.0f;
191 auto target = ResolveOverworldContextTarget(
193 ImVec2(0.0f, 0.0f), ImVec2(0.0f, 0.0f), scale);
194 if (!target) {
195 return false;
196 }
197 const auto* map = overworld_.overworld_map(target->map_id);
198 if (!map) {
199 return false;
200 }
201 target->parent_map_id =
202 map->parent() == 0xFF ? target->map_id : map->parent();
203 if (!target->valid()) {
204 return false;
205 }
208 item_placement_armed_ = false;
209 return true;
210}
211
225
226} // namespace yaze::editor
bool is_loaded() const
Definition rom.h:199
absl::StatusOr< uint16_t > tile(int global_x, int global_y) const
EditorDependencies dependencies_
Definition editor.h:382
const core::LyraTerrainDocument * document() const
OverworldEditor * editor_
Non-owning pointer to the parent editor.
bool PrepareContextMenu(const ImVec2 &screen_position)
bool IsProjectTerrainMap(int map_id) const
std::unique_ptr< MapPropertiesSystem > map_properties_system_
void RequestItemInsertPopup(const std::optional< OverworldContextTarget > &target)
void HandleEntityInsertion(const std::string &entity_type, const OverworldContextTarget &target)
Handle entity insertion from context menu.
bool SampleContextTile16(const OverworldContextTarget &target)
std::optional< OverworldContextTarget > item_insert_target_
void HandleTile16Edit(const OverworldContextTarget &target)
Handle tile16 editing from context menu (MOUSE mode) Opens the Tile16 captured at menu-open through t...
std::unique_ptr< OverworldEntityRenderer > entity_renderer_
std::optional< OverworldEntityInsertionRequest > pending_entity_insertion_
absl::Status OpenGraphicsForTile16Quadrant(int tile16_id, int quadrant)
absl::Status OpenGraphicsForContextTile16(const OverworldContextTarget &target)
void ScrollBlocksetCanvasToCurrentTile()
Scroll the blockset canvas to show the current selected tile16.
void SelectMapForEditing(int map_id, bool respect_pin=true)
void SetEntityEditMode(EntityEditMode mode)
Entity focus (entrances/exits/items/sprites); NONE = all entities.
bool OpenWindowFloating(size_t session_id, const std::string &base_window_id)
void MarkWindowRecentlyUsed(const std::string &window_id)
auto global_scale() const
Definition canvas.h:413
auto hover_mouse_pos() const
Definition canvas.h:476
void ClearContextMenuItems()
Definition canvas.cc:995
bool IsMouseHovering() const
Definition canvas.h:354
const std::vector< gfx::Tile16 > & tiles16() const
Definition overworld.h:784
bool is_lyra_preview() const
Definition overworld.h:444
auto is_loaded() const
Definition overworld.h:836
auto overworld_map(int i) const
Definition overworld.h:770
Editors are the view controllers for the application.
std::optional< OverworldContextTarget > ResolveOverworldContextTarget(int world, int game_state, ImVec2 screen_position, ImVec2 canvas_origin, ImVec2 scrolling, float scale, int map_count=zelda3::kNumOverworldMaps)
const std::vector< std::string > kSecretItemNames
project::YazeProject * project
Definition editor.h:174
SharedClipboard * shared_clipboard
Definition editor.h:187
WorkspaceWindowManager * window_manager
Definition editor.h:182
bool valid(int map_count=zelda3::kNumOverworldMaps) const
static constexpr const char * kTile16Editor