yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
entity_workbench.cc
Go to the documentation of this file.
2
8#include "imgui/imgui.h"
9
10namespace yaze {
11namespace editor {
12
13namespace {
14
16 switch (type) {
18 return "Exit";
20 return "Entrance";
22 return "Item";
24 return "Sprite";
26 return "Transport";
28 return "Music";
30 return "Tilemap";
32 return "Properties";
34 return "Dungeon Sprite";
35 default:
36 return "Unknown";
37 }
38}
39
40} // namespace
41
43 (void)p_open;
44 const auto ctx = CurrentOverworldWindowContext();
45 if (!ctx)
46 return;
47
48 auto* editor = ctx.editor;
49
50 auto* active_entity = editor->current_entity();
51 if (active_entity == nullptr) {
52 ImGui::TextDisabled("No entity selected");
53 return;
54 }
55
56 ImGui::Text("Type: %s", GetEntityTypeLabel(active_entity->entity_type_));
57 ImGui::Separator();
58
59 if (ImGui::Button(ICON_MD_SETTINGS " Open Popup Editor")) {
60 OpenEditorFor(active_entity);
61 }
62}
63
65 const auto ctx = CurrentOverworldWindowContext();
66 if (ctx) {
67 ctx.editor->SetCurrentEntity(entity);
68 }
69}
70
72 const auto ctx = CurrentOverworldWindowContext();
73 if (!ctx || !entity)
74 return;
75
76 auto* editor = ctx.editor;
77 editor->SetCurrentEntity(entity);
78 editing_entity_ = entity;
79
80 switch (entity->entity_type_) {
82 editor->edit_exit() = *static_cast<zelda3::OverworldExit*>(entity);
83 ImGui::OpenPopup(
85 .c_str());
86 break;
88 editor->edit_entrance() =
89 *static_cast<zelda3::OverworldEntrance*>(entity);
90 ImGui::OpenPopup(
92 .c_str());
93 break;
95 editor->edit_item() = *static_cast<zelda3::OverworldItem*>(entity);
96 ImGui::OpenPopup(
98 .c_str());
99 break;
101 editor->edit_sprite() = *static_cast<zelda3::Sprite*>(entity);
102 ImGui::OpenPopup(
104 .c_str());
105 break;
106 default:
107 break;
108 }
109}
110
112 const auto ctx = CurrentOverworldWindowContext();
113 if (!ctx || !entity) {
114 return;
115 }
116 ctx.editor->SetCurrentEntity(entity);
117 ImGui::OpenPopup(kContextMenuPopupId);
118}
119
121 const auto ctx = CurrentOverworldWindowContext();
122 if (!ctx)
123 return;
124
125 auto* editor = ctx.editor;
126 auto* editing_entity = editing_entity_;
127
128 if (ImGui::BeginPopup(kContextMenuPopupId)) {
130 ImGui::EndPopup();
131 }
132
133 if (ImGui::BeginPopupModal("Entity Insert Error", nullptr,
134 ImGuiWindowFlags_AlwaysAutoResize)) {
135 ImGui::TextWrapped("%s", editor->insert_error().c_str());
136 ImGui::Spacing();
137 if (ImGui::Button("OK", ImVec2(120.0f, 0.0f))) {
138 editor->insert_error().clear();
139 ImGui::CloseCurrentPopup();
140 }
141 ImGui::EndPopup();
142 }
143
144 if (DrawExitEditorPopup(editor->edit_exit())) {
145 if (editing_entity &&
146 editing_entity->entity_type_ == zelda3::GameEntity::EntityType::kExit) {
147 *static_cast<zelda3::OverworldExit*>(editing_entity) =
148 editor->edit_exit();
149 editor->NotifyEntityModified(editing_entity);
150 }
151 }
152 if (DrawOverworldEntrancePopup(editor->edit_entrance())) {
153 if (editing_entity && editing_entity->entity_type_ ==
155 *static_cast<zelda3::OverworldEntrance*>(editing_entity) =
156 editor->edit_entrance();
157 editor->NotifyEntityModified(editing_entity);
158 }
159 }
160 if (DrawItemEditorPopup(editor->edit_item())) {
161 if (editing_entity &&
162 editing_entity->entity_type_ == zelda3::GameEntity::EntityType::kItem) {
163 if (editor->edit_item().deleted) {
164 (void)editor->DeleteSelectedItem();
165 } else {
166 *static_cast<zelda3::OverworldItem*>(editing_entity) =
167 editor->edit_item();
168 editor->NotifyEntityModified(editing_entity);
169 }
170 }
171 }
172 if (DrawSpriteEditorPopup(editor->edit_sprite())) {
173 if (editing_entity && editing_entity->entity_type_ ==
175 *static_cast<zelda3::Sprite*>(editing_entity) = editor->edit_sprite();
176 editor->NotifyEntityModified(editing_entity);
177 }
178 }
179
180 const bool exit_popup_open = ImGui::IsPopupOpen(
181 gui::MakePopupId(gui::EditorNames::kOverworld, "Exit Editor").c_str());
182 const bool entrance_popup_open = ImGui::IsPopupOpen(
184 .c_str());
185 const bool item_popup_open = ImGui::IsPopupOpen(
186 gui::MakePopupId(gui::EditorNames::kOverworld, "Item Editor").c_str());
187 const bool sprite_popup_open = ImGui::IsPopupOpen(
188 gui::MakePopupId(gui::EditorNames::kOverworld, "Sprite Editor").c_str());
189 if (!exit_popup_open && !entrance_popup_open && !item_popup_open &&
190 !sprite_popup_open) {
191 editing_entity_ = nullptr;
192 }
193}
194
196 ImVec2 pos) {
197 const auto ctx = CurrentOverworldWindowContext();
198 if (!ctx)
199 return;
200 ctx.editor->pending_insert_type() = type;
201 ctx.editor->pending_insert_pos() = pos;
202}
203
205 EntityMutationService* mutation_service, int current_map, int game_state) {
206 const auto ctx = CurrentOverworldWindowContext();
207 if (!ctx || !mutation_service)
208 return;
209
210 auto* editor = ctx.editor;
211 if (editor->pending_insert_type().empty())
212 return;
213
214 auto res = mutation_service->InsertEntity(editor->pending_insert_type(),
215 editor->pending_insert_pos(),
216 current_map, game_state);
217
218 if (res.ok()) {
219 OpenEditorFor(res.entity);
220 editor->NotifyEntityModified(res.entity);
221 } else {
222 editor->insert_error() = res.error_message;
223 ImGui::OpenPopup("Entity Insert Error");
224 }
225
226 editor->pending_insert_type().clear();
227}
228
230 const auto ctx = CurrentOverworldWindowContext();
231 if (!ctx)
232 return;
233
234 auto* editor = ctx.editor;
235 auto* active_entity = editor->current_entity();
236 if (!active_entity)
237 return;
238
239 if (ImGui::Selectable(ICON_MD_EDIT " Edit Properties")) {
240 OpenEditorFor(active_entity);
241 ImGui::CloseCurrentPopup();
242 }
243
244 if (active_entity->entity_type_ == zelda3::GameEntity::EntityType::kExit) {
245 auto* exit = static_cast<zelda3::OverworldExit*>(active_entity);
246 if (ImGui::Selectable(ICON_MD_LINK " Jump to Room")) {
247 editor->RequestJumpToRoom(exit->room_id_);
248 ImGui::CloseCurrentPopup();
249 }
250 } else if (active_entity->entity_type_ ==
252 auto* entrance = static_cast<zelda3::OverworldEntrance*>(active_entity);
253 if (ImGui::Selectable(ICON_MD_LINK " Jump to Entrance")) {
254 editor->RequestJumpToEntrance(entrance->entrance_id_);
255 ImGui::CloseCurrentPopup();
256 }
257 }
258}
259
261
262} // namespace editor
263} // namespace yaze
Editor-level service responsible for overworld entity mutations.
MutationResult InsertEntity(const std::string &type, ImVec2 pos, int map_id, int game_state)
Dispatches entity insertion based on type string.
Authoritative component for entity editing state and UI.
void SetPendingInsertion(const std::string &type, ImVec2 pos)
void OpenEditorFor(zelda3::GameEntity *entity)
static constexpr const char * kContextMenuPopupId
void Draw(bool *p_open) override
Draw the panel content.
void ProcessPendingInsertion(EntityMutationService *mutation_service, int current_map, int game_state)
void OpenContextMenuFor(zelda3::GameEntity *entity)
void SetActiveEntity(zelda3::GameEntity *entity)
Base class for all overworld and dungeon entities.
Definition common.h:31
enum yaze::zelda3::GameEntity::EntityType entity_type_
Represents an overworld exit that transitions from dungeon to overworld.
A class for managing sprites in the overworld and underworld.
Definition sprite.h:35
#define ICON_MD_SETTINGS
Definition icons.h:1699
#define ICON_MD_LINK
Definition icons.h:1090
#define ICON_MD_EDIT
Definition icons.h:645
const char * GetEntityTypeLabel(zelda3::GameEntity::EntityType type)
bool DrawSpriteEditorPopup(zelda3::Sprite &sprite)
Definition entity.cc:533
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance)
Definition entity.cc:114
bool DrawItemEditorPopup(zelda3::OverworldItem &item)
Definition entity.cc:401
OverworldWindowContext CurrentOverworldWindowContext()
bool DrawExitEditorPopup(zelda3::OverworldExit &exit)
Definition entity.cc:199
constexpr const char * kOverworld
Definition popup_id.h:53
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
#define REGISTER_PANEL(PanelClass)
Auto-registration macro for panels with default constructors.