yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_editor_v2.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
2#define YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
3
4#include <array>
5#include <cstdint>
6#include <deque>
7#include <functional>
8#include <memory>
9#include <optional>
10#include <string>
11#include <unordered_map>
12#include <utility>
13#include <vector>
14
15#include "absl/status/status.h"
16#include "absl/strings/str_format.h"
17#include "app/editor/editor.h"
25#include "dungeon_room_loader.h"
27#include "dungeon_room_store.h"
29#include "imgui/imgui.h"
32#include "rom/rom.h"
34#include "util/lru_cache.h"
37#include "zelda3/dungeon/room.h"
41#include "zelda3/game_data.h"
42
43namespace yaze {
44namespace editor {
45
46class CustomCollisionPanel;
47class DungeonEditorPaletteRefreshTestPeer;
48class DungeonEditorV2MinecartTrackTestPeer;
49class DungeonEditorV2ObjectTileEditorTestPeer;
50class DungeonEditorV2RegularEntranceTestPeer;
51class DungeonEditorV2ReloadTestPeer;
52class DungeonEditorV2ShortcutTestPeer;
53class DungeonEditorV2SpawnPointTestPeer;
54class DungeonEditorV2SpawnRejectionTestPeer;
55class MinecartTrackEditorPanel;
56class ObjectTileEditorPanel;
57class OverlayManagerPanel;
58class PaletteEditorContent;
59class RoomTagEditorPanel;
60class WaterFillPanel;
61
102class DungeonEditorV2 : public Editor {
103 public:
104 explicit DungeonEditorV2(Rom* rom = nullptr);
105
106 ~DungeonEditorV2() override;
107 void PrepareForSessionTeardown() override;
108
111 dependencies_.game_data = game_data; // Also set base class dependency
115 }
117 dungeon_editor_system_->SetGameData(game_data);
118 }
120 // Note: Canvas viewer game data is set lazily in GetViewerForRoom
121 // but we should update existing viewers
122 room_viewers_.ForEach(
123 [game_data](int, std::unique_ptr<DungeonCanvasViewer>& viewer) {
124 if (viewer)
125 viewer->SetGameData(game_data);
126 });
127 if (workbench_viewer_) {
128 workbench_viewer_->SetGameData(game_data);
129 }
132 }
133 }
134
135 // Editor interface
136 void SetDependencies(const EditorDependencies& deps) override;
137 void Initialize() override;
138 absl::Status Load() override;
139 absl::Status Update() override;
140 absl::Status Undo() override;
141 absl::Status Redo() override;
142 absl::Status Cut() override;
143 absl::Status Copy() override;
144 absl::Status Paste() override;
145 absl::Status Find() override { return absl::UnimplementedError("Find"); }
146 absl::Status Save() override;
147 absl::Status BeginSaveTransaction() override;
148 void RollbackSaveTransaction() override;
149 void CommitSaveTransaction() override;
150 void ContributeStatus(StatusBar* status_bar) override;
151 absl::Status SaveRoom(int room_id);
152 int LoadedRoomCount() const;
153 // Room-specific pending state used by room counts and room-level UI.
154 int PendingRoomCount() const;
155 bool HasPendingRoomChanges() const;
156 // All dungeon save domains plus unapplied editor-local work.
157 bool HasPendingDungeonChanges() const;
159 absl::Status PrepareProjectSave();
160 bool CurrentRoomHasPendingChanges() const;
161 int TotalRoomCount() const { return static_cast<int>(rooms_.size()); }
162
163 // Collect PC write ranges for all dirty/loaded rooms (for write conflict
164 // analysis). Returns pairs of (start_pc, end_pc) covering header and object
165 // regions that would be written during save.
166 std::vector<std::pair<uint32_t, uint32_t>> CollectWriteRanges() const;
167
168 // ROM management
169 void SetRom(Rom* rom) {
170 const bool rom_changed = rom_ != rom;
171 rom_ = rom;
175
176 // Propagate ROM to all rooms
178 // Reset viewers on ROM change
179 if (rom_changed) {
180 rooms_.Clear();
181 room_viewers_.Clear();
182 workbench_viewer_.reset();
184 }
185 }
186 // Reloads same-address ROM state in place so rooms, viewers, and workspace
187 // panel bindings retain stable addresses.
188 absl::Status RefreshRomBackedState();
189 Rom* rom() const { return rom_; }
190
191 // Room management
192 void add_room(int room_id);
193 void FocusRoom(int room_id);
194
195 // Agent/Automation controls
196 void SelectObject(int obj_id);
197 void SetAgentMode(bool enabled);
198
199 // ROM state
200 bool IsRomLoaded() const override { return rom_ && rom_->is_loaded(); }
201 std::string GetRomStatus() const override {
202 if (!rom_)
203 return "No ROM loaded";
204 if (!rom_->is_loaded())
205 return "ROM failed to load";
206 return absl::StrFormat("ROM loaded: %s", rom_->title());
207 }
208
209 // Open a workspace window by its id using WorkspaceWindowManager.
210 void OpenWindow(const std::string& window_id) {
213 }
214 }
215
216 // Create and register the project-only Minecart Tracks surface on demand.
217 // This supports enabling custom objects after the Dungeon editor has loaded.
218 absl::Status EnsureMinecartTrackEditorPanel();
219
220 // Explicit workflow toggle between integrated Workbench and standalone panels.
221 void SetWorkbenchWorkflowMode(bool enabled, bool show_toast = true);
222 // Queue a workflow mode change to run at a safe point in the next update.
223 void QueueWorkbenchWorkflowMode(bool enabled, bool show_toast = true);
224 // Queue a mode flip (Workbench <-> Standalone) for next update.
225 void ToggleWorkbenchWorkflowMode(bool show_toast = true);
226 bool IsWorkbenchWorkflowEnabled() const;
227
228 // ShortcutManager runs before this editor draws. Queue destructive keyboard
229 // actions so the room canvas can establish ownership for the current frame
230 // before the action is evaluated.
232
233 // Panel card IDs for programmatic access
234 static constexpr const char* kRoomSelectorId = "dungeon.room_selector";
235 static constexpr const char* kEntranceListId = "dungeon.entrance_list";
236 static constexpr const char* kRoomMatrixId = "dungeon.room_matrix";
237 static constexpr const char* kRoomGraphicsId = "dungeon.room_graphics";
238 static constexpr const char* kObjectSelectorId = "dungeon.object_selector";
239 static constexpr const char* kObjectToolsId = kObjectSelectorId;
240 static constexpr const char* kDoorEditorId = "dungeon.door_editor";
241 static constexpr const char* kPaletteEditorId = "dungeon.palette_editor";
242 static constexpr const char* kMinecartTrackEditorId =
243 "dungeon.minecart_tracks";
244
245 // Public accessors for WASM API and automation
248 const ImVector<int>& active_rooms() const {
250 }
252 const DungeonRoomStore& rooms() const { return rooms_; }
253 gfx::IRenderer* renderer() const { return renderer_; }
264
269 const std::deque<int>& GetRecentRooms() const { return recent_rooms_; }
270
271 private:
282 friend class
285 friend class
287 friend class
289 friend class
291 friend class
293 friend class
295 friend class
297 friend class
299 friend class
301
303
304 // Draw the Room Panels
305 void DrawRoomPanels();
306 void DrawRoomTab(int room_id);
307
308 // Texture processing (critical for rendering)
311
312 // Room selection callback
313 void OnRoomSelected(int room_id, bool request_focus = true);
314 void OnRoomSelected(int room_id, RoomSelectionIntent intent);
315 void OnEntranceSelected(int entrance_id);
316 int ResolveEntranceRoomId(int entrance_id) const;
317
318 // Sync all sub-panels to the current room configuration
319 void SyncPanelsToRoom(int room_id);
321 void HandleArenaPaletteChanged(const std::string& group_name,
322 int palette_index);
325 uint8_t ResolveSelectedEntranceBlocksetForRoom(int room_id) const;
326 void ApplyEntranceRenderContext(int room_id);
327 void ConfigureViewerRenderContext(DungeonCanvasViewer* viewer, int room_id);
331
332 // Show or create a standalone room panel
333 void ShowRoomPanel(int room_id);
334
335 // Convenience action for Settings panel.
336 void SaveAllRooms();
337
338 // Object placement callback
339 void HandleObjectPlaced(const zelda3::RoomObject& obj);
340 void OpenGraphicsEditorForObject(int room_id,
341 const zelda3::RoomObject& object);
342 absl::Status OpenObjectTileEditorForObject(int room_id,
343 const zelda3::RoomObject& object);
344
345 // Helper to get or create a viewer for a specific room
350 int room_id);
353 void TouchViewerLru(int room_id);
354 void RemoveViewerFromLru(int room_id);
355
356 absl::Status SaveRoomData(int room_id);
357 absl::Status RunWithSaveTransaction(
358 const std::function<absl::Status()>& operation);
359
360 // Data
364 std::array<zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots> entrances_;
365 std::array<zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints>
367
369 std::vector<std::pair<int, zelda3::Room::SaveDirtySnapshot>> room_states;
370 std::array<bool, zelda3::kNumDungeonEntranceSlots> entrance_dirty_states{};
371 std::array<bool, zelda3::kNumDungeonSpawnPoints> spawn_dirty_states{};
373 bool pit_damage_dirty = false;
375 };
376 std::optional<SaveTransactionSnapshot> save_transaction_snapshot_;
377
379
380 // Current selection state
382
383 // Active room tabs and card tracking for jump-to
384 ImVector<int> active_rooms_;
386
387 // Recent rooms history for quick navigation (most recent first, max 10)
388 static constexpr size_t kMaxRecentRooms = 10;
389 std::deque<int> recent_rooms_;
390 std::vector<int> pinned_rooms_;
391
392 // Workbench panel pointer (owned by WorkspaceWindowManager, stored for notifications).
394
395 // Palette management
401
402 // Components - these do all the work
405 static constexpr int kMaxCachedViewers = 20;
408 std::unique_ptr<DungeonCanvasViewer> workbench_viewer_;
409 std::unique_ptr<DungeonCanvasViewer> workbench_compare_viewer_;
410
412 // Panel pointers. WorkspaceWindowManager owns these when available; fallback
413 // unique_ptrs keep non-workspace tests and direct embedding paths alive.
414 // Workbench mode embeds room-local utilities in the Tools inspector. Their
415 // standalone entries remain discoverable, but one content instance has only
416 // one active presentation owner at a time.
430
431 // Object editor is retained as the non-window backend for inspector actions.
432 // Other owned_* fields are fallbacks for tests without WorkspaceWindowManager.
433 std::unique_ptr<ObjectSelectorContent> owned_object_selector_panel_;
434 std::unique_ptr<ObjectEditorContent> owned_object_editor_content_;
435 std::unique_ptr<DoorEditorContent> owned_door_editor_panel_;
436 std::unique_ptr<RoomTagEditorPanel> owned_room_tag_editor_panel_;
437 std::unique_ptr<CustomCollisionPanel> owned_custom_collision_panel_;
438 std::unique_ptr<WaterFillPanel> owned_water_fill_panel_;
439 std::unique_ptr<MinecartTrackEditorPanel> owned_minecart_track_editor_panel_;
440 std::unique_ptr<zelda3::DungeonEditorSystem> dungeon_editor_system_;
441 std::unique_ptr<emu::render::EmulatorRenderService> render_service_;
442
443 bool is_loaded_ = false;
446
447 // Docking class for room windows to dock together
448 ImGuiWindowClass room_window_class_;
449
450 // Shared dock ID for all room panels to auto-dock together
451 ImGuiID room_dock_id_ = 0;
452
453 // Dynamic room cards - created per open room
454 std::unordered_map<int, std::shared_ptr<gui::PanelWindow>> room_cards_;
455
456 // Stable window slot mapping: room_id -> slot_id.
457 // Slot IDs are used in the "###" part of the window title so ImGui treats the
458 // window as the same entity even when its displayed room changes.
460 std::unordered_map<int, int> room_panel_slot_ids_;
461
462 // Pending undo snapshot: captured on mutation callback (before edit),
463 // finalized on cache invalidation callback (after edit) by pushing an undo
464 // action to the inherited undo_manager_.
465 struct PendingUndo {
466 int room_id = -1;
467 std::vector<zelda3::RoomObject> before_objects;
468 std::vector<size_t> before_selection;
469 };
471 bool has_pending_undo_ = false;
473
479
485
486 // Pending room swap (deferred until after draw phase completes)
487 struct PendingSwap {
488 int old_room_id = -1;
489 int new_room_id = -1;
490 bool pending = false;
491 };
493
495 bool enabled = false;
496 bool show_toast = true;
497 bool pending = false;
498 };
500
501 // Opening or focusing a standalone tool mutates WorkspaceWindowManager and
502 // Dear ImGui focus state. Workbench buttons are drawn inside child windows,
503 // so defer that mutation to the next Update() safe point. Capture the
504 // originating session so a session switch cannot redirect the request.
506 size_t session_id = 0;
507 std::string window_id;
508 bool pending = false;
509 };
511
512 // Unpinned room-navigation panels hidden by the most recent transition into
513 // the integrated Workbench. Standalone editing tools remain user-owned and
514 // are never added to this restoration set.
516
517 // Two-phase undo capture: BeginUndoSnapshot saves state before mutation,
518 // FinalizeUndoAction captures state after mutation and pushes the action.
519 void BeginUndoSnapshot(int room_id);
520 void FinalizeUndoAction(int room_id);
521 void RestoreRoomObjects(int room_id,
522 const std::vector<zelda3::RoomObject>& objects,
523 const std::vector<size_t>& selected_indices);
524
525 void BeginCollisionUndoSnapshot(int room_id);
526 void FinalizeCollisionUndoAction(int room_id);
527 void RestoreRoomCustomCollision(int room_id,
528 const zelda3::CustomCollisionMap& map);
529 absl::Status ApplyMinecartCollisionBatch(
530 const std::vector<zelda3::TrackCollisionResult>& preview,
531 const zelda3::GeneratorOptions& options);
533 const std::vector<DungeonCustomCollisionSnapshot>& snapshots);
534
535 void BeginWaterFillUndoSnapshot(int room_id);
536 void FinalizeWaterFillUndoAction(int room_id);
537 void RestoreRoomWaterFill(int room_id, const WaterFillSnapshot& snap);
538 void SwapRoomInPanel(int old_room_id, int new_room_id);
539 void ProcessPendingSwap(); // Process deferred swap after draw
542
543 // Room panel slot IDs provide stable ImGui window IDs across "swap room in
544 // panel" navigation. This keeps the window position/dock state when the room
545 // changes via the directional arrows.
546 int GetOrCreateRoomPanelSlotId(int room_id);
547 void ReleaseRoomPanelSlotId(int room_id);
548
549 // Defensive guard: returns true iff room_id is within the valid range
550 // [0, kNumberOfRooms). Use this instead of open-coded range checks.
551 static bool IsValidRoomId(int room_id) {
552 return room_id >= 0 && room_id < zelda3::kNumberOfRooms;
553 }
554};
555
556} // namespace editor
557} // namespace yaze
558
559#endif // YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
bool is_loaded() const
Definition rom.h:155
auto title() const
Definition rom.h:167
DungeonEditorV2 - Simplified dungeon editor using component delegation.
class MinecartTrackEditorPanel * minecart_track_editor_panel_
friend class DungeonEditorV2SpawnRejectionTestPeer
std::unique_ptr< CustomCollisionPanel > owned_custom_collision_panel_
friend class DungeonEditorV2MinecartTrackTestPeer
class CustomCollisionPanel * custom_collision_panel_
std::optional< int > room_canvas_delete_shortcut_frame_
friend class DungeonEditorV2RegularEntranceTestPeer
friend class DungeonEditorV2RomSafetyTest_SaveAllRoomsRollsBackEarlierWritesOnLateFailure_Test
friend class DungeonEditorPaletteRefreshTest_CachedRoomRefreshesThroughViewerCompositePreparation_Test
void ToggleWorkbenchWorkflowMode(bool show_toast=true)
friend class DungeonEditorPaletteRefreshTest_SharedHudEditRefreshesRoomUsingDifferentDungeonPalette_Test
void RestoreRoomWaterFill(int room_id, const WaterFillSnapshot &snap)
void ContributeStatus(StatusBar *status_bar) override
void OpenGraphicsEditorForObject(int room_id, const zelda3::RoomObject &object)
absl::Status OpenObjectTileEditorForObject(int room_id, const zelda3::RoomObject &object)
class ItemEditorPanel * item_editor_panel_
std::unique_ptr< RoomTagEditorPanel > owned_room_tag_editor_panel_
void SetDependencies(const EditorDependencies &deps) override
ObjectSelectorContent * object_selector_panel() const
util::LruCache< int, std::unique_ptr< DungeonCanvasViewer > > room_viewers_
gfx::PaletteGroup current_palette_group_
void OnEntranceSelected(int entrance_id)
static constexpr const char * kEntranceListId
PendingStandaloneToolWindow pending_standalone_tool_window_
class SpriteEditorPanel * sprite_editor_panel_
void HandleObjectPlaced(const zelda3::RoomObject &obj)
std::string GetRomStatus() const override
DoorEditorContent * door_editor_panel() const
std::unique_ptr< zelda3::DungeonEditorSystem > dungeon_editor_system_
std::array< zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots > entrances_
void OpenWindow(const std::string &window_id)
friend class DungeonEditorV2ObjectTileEditorTestPeer
DoorEditorContent * door_editor_panel_
std::unordered_map< int, int > room_panel_slot_ids_
friend class DungeonEditorV2RomSafetyTest_UndoSnapshotLeakDetection_Test
void RestoreRoomObjects(int room_id, const std::vector< zelda3::RoomObject > &objects, const std::vector< size_t > &selected_indices)
class DungeonWorkbenchContent * workbench_panel_
int ResolveEntranceRoomId(int entrance_id) const
friend class DungeonEditorV2RomSafetyTest_ViewerCacheLRUEviction_Test
void OnRoomSelected(int room_id, bool request_focus=true)
friend class DungeonEditorV2RomSafetyTest_ViewerCacheNeverEvictsActiveRooms_Test
ObjectEditorContent * object_editor_content() const
PendingCollisionUndo pending_collision_undo_
ObjectTileEditorPanel * object_tile_editor_panel_
ObjectSelectorContent * object_selector_panel_
OverlayManagerPanel * overlay_manager_panel_
uint8_t ResolveSelectedEntranceBlocksetForRoom(int room_id) const
DungeonCanvasViewer * GetWorkbenchCompareViewer(int room_id)
void WireViewerPanelCallbacks(DungeonCanvasViewer *viewer)
gfx::IRenderer * renderer() const
std::unique_ptr< DungeonCanvasViewer > workbench_compare_viewer_
PendingWaterFillUndo pending_water_fill_undo_
std::unique_ptr< MinecartTrackEditorPanel > owned_minecart_track_editor_panel_
bool IsRomLoaded() const override
gui::PaletteEditorWidget palette_editor_
std::unique_ptr< ObjectEditorContent > owned_object_editor_content_
std::unique_ptr< DoorEditorContent > owned_door_editor_panel_
const std::deque< int > & GetRecentRooms() const
Get the list of recently visited room IDs.
bool ConsumeRoomCanvasDeleteShortcut(DungeonCanvasViewer &viewer)
static bool IsValidRoomId(int room_id)
void SwapRoomInPanel(int old_room_id, int new_room_id)
RoomGraphicsContent * room_graphics_panel_
absl::Status RunWithSaveTransaction(const std::function< absl::Status()> &operation)
const DungeonRoomStore & rooms() const
static constexpr int kMaxCachedViewers
static constexpr size_t kMaxRecentRooms
std::array< zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints > spawn_points_
void SetWorkbenchWorkflowMode(bool enabled, bool show_toast=true)
class RoomTagEditorPanel * room_tag_editor_panel_
std::optional< SaveTransactionSnapshot > save_transaction_snapshot_
std::unique_ptr< ObjectSelectorContent > owned_object_selector_panel_
friend class DungeonEditorV2RomSafetyTest_ViewerCacheLRUAccessOrderUpdate_Test
friend class DungeonEditorPaletteRefreshTest_CompareViewerScopesEntranceContextToRequestedRoom_Test
static constexpr const char * kDoorEditorId
friend class DungeonEditorV2RomSafetyTest_LateCoordinatorRollbackRestoresEntranceDirtyState_Test
static constexpr const char * kObjectToolsId
DungeonCanvasViewer * GetViewerForRoom(int room_id)
class WaterFillPanel * water_fill_panel_
void RefreshWorkbenchViewerRuntimeContext(DungeonCanvasViewer *viewer, int room_id)
absl::Status RestoreRoomCustomCollisionBatch(const std::vector< DungeonCustomCollisionSnapshot > &snapshots)
absl::Status Find() override
friend class DungeonEditorPaletteRefreshTest_DungeonMainEditRefreshesResolvedAliasesOnly_Test
ObjectSelectorContent * object_editor_panel() const
std::unique_ptr< emu::render::EmulatorRenderService > render_service_
DungeonCanvasViewer * GetWorkbenchViewer()
std::unordered_map< int, std::shared_ptr< gui::PanelWindow > > room_cards_
void ApplyEntranceRenderContext(int room_id)
void SetGameData(zelda3::GameData *game_data) override
friend class DungeonEditorV2RomSafetyTest_ObjectStreamUndoRedoRestoresSelectionIdentity_Test
static constexpr const char * kObjectSelectorId
void ConfigureViewerRenderContext(DungeonCanvasViewer *viewer, int room_id)
static constexpr const char * kRoomGraphicsId
void QueueWorkbenchWorkflowMode(bool enabled, bool show_toast=true)
ObjectEditorContent * object_editor_content_
static constexpr const char * kRoomMatrixId
void HandleDungeonPaletteChanged(gui::DungeonPaletteChange change)
static constexpr const char * kRoomSelectorId
const ImVector< int > & active_rooms() const
PaletteEditorContent * palette_editor_panel_
static constexpr const char * kMinecartTrackEditorId
std::unique_ptr< DungeonCanvasViewer > workbench_viewer_
void RestoreRoomCustomCollision(int room_id, const zelda3::CustomCollisionMap &map)
std::vector< std::pair< uint32_t, uint32_t > > CollectWriteRanges() const
std::unique_ptr< WaterFillPanel > owned_water_fill_panel_
absl::Status ApplyMinecartCollisionBatch(const std::vector< zelda3::TrackCollisionResult > &preview, const zelda3::GeneratorOptions &options)
static constexpr const char * kPaletteEditorId
PendingWorkflowMode pending_workflow_mode_
void InvalidateDungeonPaletteUsers(gui::DungeonPaletteChange change)
void HandleArenaPaletteChanged(const std::string &group_name, int palette_index)
std::vector< std::string > workbench_suspended_navigation_window_ids_
Manages loading and saving of dungeon room data.
void SetGameData(zelda3::GameData *game_data)
Handles room and entrance selection UI.
const ImVector< int > & active_rooms() const
void SetGameData(zelda3::GameData *game_data)
Interface for editor classes.
Definition editor.h:245
zelda3::GameData * game_data() const
Definition editor.h:325
EditorDependencies dependencies_
Definition editor.h:338
WindowContent for placing and managing dungeon pot items.
Browse and place dungeon objects.
void SetGameData(zelda3::GameData *game_data)
Panel for editing the tile8 composition of dungeon objects.
WindowContent wrapper for PaletteEditorWidget in dungeon context.
WindowContent for displaying room graphics blocks.
WindowContent showing all room tag slots and their usage across rooms.
WindowContent for placing and managing dungeon sprites.
A session-aware status bar displayed at the bottom of the application.
Definition status_bar.h:57
bool OpenWindow(size_t session_id, const std::string &base_window_id)
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
RoomSelectionIntent
Intent for room selection in the dungeon editor.
constexpr int kNumberOfRooms
std::vector< zelda3::RoomObject > before_objects
std::vector< std::pair< int, zelda3::Room::SaveDirtySnapshot > > room_states
std::array< bool, zelda3::kNumDungeonSpawnPoints > spawn_dirty_states
std::array< bool, zelda3::kNumDungeonEntranceSlots > entrance_dirty_states
Unified dependency container for all editor types.
Definition editor.h:169
zelda3::GameData * game_data
Definition editor.h:172
WorkspaceWindowManager * window_manager
Definition editor.h:181
Represents a group of palettes.