refactor: enhance overworld entity properties and version handling
- Updated `UpdateMapProperties` methods across various entities (entrances, exits, items, sprites) to include an optional context parameter for improved area size detection. - Introduced `OverworldVersionHelper` for centralized ROM version detection and feature gating, replacing scattered inline checks. - Refactored coordinate calculations to utilize normalized map IDs, ensuring consistency and preventing data corruption. - Enhanced exit properties to sync player positions and calculate scroll/camera values based on the overworld context. Benefits: - Streamlines entity property updates and improves compatibility with different ROM versions. - Reduces code duplication and enhances maintainability by centralizing version checks. - Ensures accurate coordinate calculations for overworld entities, improving overall functionality.
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
#include "app/gui/core/icons.h"
|
||||
#include "app/gui/core/input.h"
|
||||
#include "app/gui/core/style.h"
|
||||
#include "imgui.h"
|
||||
#include "util/hex.h"
|
||||
#include "zelda3/common.h"
|
||||
#include "zelda3/overworld/overworld_item.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
@@ -26,11 +29,8 @@ bool IsMouseHoveringOverEntity(const zelda3::GameEntity &entity,
|
||||
const ImVec2 mouse_pos(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
|
||||
|
||||
// Check if the mouse is hovering over the entity
|
||||
if (mouse_pos.x >= entity.x_ && mouse_pos.x <= entity.x_ + 16 &&
|
||||
mouse_pos.y >= entity.y_ && mouse_pos.y <= entity.y_ + 16) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return mouse_pos.x >= entity.x_ && mouse_pos.x <= entity.x_ + 16 &&
|
||||
mouse_pos.y >= entity.y_ && mouse_pos.y <= entity.y_ + 16;
|
||||
}
|
||||
|
||||
void MoveEntityOnGrid(zelda3::GameEntity *entity, ImVec2 canvas_p0,
|
||||
@@ -154,6 +154,7 @@ bool DrawExitEditorPopup(zelda3::OverworldExit &exit) {
|
||||
static bool set_done = false;
|
||||
if (set_done) {
|
||||
set_done = false;
|
||||
return true;
|
||||
}
|
||||
if (ImGui::BeginPopupModal("Exit editor", NULL,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
@@ -207,7 +208,9 @@ bool DrawExitEditorPopup(zelda3::OverworldExit &exit) {
|
||||
if (show_properties) {
|
||||
Text("Deleted? %s", exit.deleted_ ? "true" : "false");
|
||||
Text("Hole? %s", exit.is_hole_ ? "true" : "false");
|
||||
Text("Large Map? %s", exit.large_map_ ? "true" : "false");
|
||||
Text("Auto-calc scroll/camera? %s", exit.is_automatic_ ? "true" : "false");
|
||||
Text("Map ID: 0x%02X", exit.map_id_);
|
||||
Text("Game coords: (%d, %d)", exit.game_x_, exit.game_y_);
|
||||
}
|
||||
|
||||
gui::TextWithSeparators("Unimplemented below");
|
||||
@@ -260,19 +263,21 @@ bool DrawExitEditorPopup(zelda3::OverworldExit &exit) {
|
||||
}
|
||||
|
||||
if (Button(ICON_MD_DONE)) {
|
||||
set_done = true; // FIX: Save changes when Done is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
SameLine();
|
||||
|
||||
if (Button(ICON_MD_CANCEL)) {
|
||||
set_done = true;
|
||||
// FIX: Discard changes - don't set set_done
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DELETE)) {
|
||||
exit.deleted_ = true;
|
||||
set_done = true; // FIX: Save deletion when Delete is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
@@ -316,6 +321,7 @@ bool DrawItemEditorPopup(zelda3::OverworldItem &item) {
|
||||
static bool set_done = false;
|
||||
if (set_done) {
|
||||
set_done = false;
|
||||
return true;
|
||||
}
|
||||
if (ImGui::BeginPopupModal("Item editor", NULL,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
@@ -325,20 +331,26 @@ bool DrawItemEditorPopup(zelda3::OverworldItem &item) {
|
||||
for (size_t i = 0; i < zelda3::kSecretItemNames.size(); i++) {
|
||||
if (Selectable(zelda3::kSecretItemNames[i].c_str(), item.id_ == i)) {
|
||||
item.id_ = i;
|
||||
item.entity_id_ = i;
|
||||
item.UpdateMapProperties(item.map_id_, nullptr);
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
EndChild();
|
||||
|
||||
if (Button(ICON_MD_DONE)) ImGui::CloseCurrentPopup();
|
||||
if (Button(ICON_MD_DONE)) {
|
||||
set_done = true; // FIX: Save changes when Done is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SameLine();
|
||||
if (Button(ICON_MD_CLOSE)) {
|
||||
set_done = true;
|
||||
// FIX: Discard changes - don't set set_done
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DELETE)) {
|
||||
item.deleted = true;
|
||||
set_done = true; // FIX: Save deletion when Delete is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
@@ -437,6 +449,7 @@ bool DrawSpriteEditorPopup(zelda3::Sprite &sprite) {
|
||||
static bool set_done = false;
|
||||
if (set_done) {
|
||||
set_done = false;
|
||||
return true;
|
||||
}
|
||||
if (ImGui::BeginPopupModal("Sprite editor", NULL,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
@@ -447,20 +460,24 @@ bool DrawSpriteEditorPopup(zelda3::Sprite &sprite) {
|
||||
|
||||
DrawSpriteTable([&sprite](int selected_id) {
|
||||
sprite.set_id(selected_id);
|
||||
sprite.UpdateMapProperties(sprite.map_id());
|
||||
sprite.UpdateMapProperties(sprite.map_id(), nullptr);
|
||||
});
|
||||
ImGui::EndGroup();
|
||||
EndChild();
|
||||
|
||||
if (Button(ICON_MD_DONE)) ImGui::CloseCurrentPopup();
|
||||
if (Button(ICON_MD_DONE)) {
|
||||
set_done = true; // FIX: Save changes when Done is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SameLine();
|
||||
if (Button(ICON_MD_CLOSE)) {
|
||||
set_done = true;
|
||||
// FIX: Discard changes - don't set set_done
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
SameLine();
|
||||
if (Button(ICON_MD_DELETE)) {
|
||||
sprite.set_deleted(true);
|
||||
set_done = true; // FIX: Save deletion when Delete is clicked
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,33 +34,33 @@ absl::StatusOr<zelda3::OverworldEntrance*> InsertEntrance(
|
||||
holes[i].entrance_id_ = 0; // Default, user configures in popup
|
||||
holes[i].is_hole_ = true;
|
||||
|
||||
// Update map properties (ZScream: EntranceMode.cs:90)
|
||||
holes[i].UpdateMapProperties(map_id);
|
||||
|
||||
LOG_DEBUG("EntityOps", "Inserted hole at slot %zu: pos=(%d,%d) map=0x%02X",
|
||||
i, holes[i].x_, holes[i].y_, map_id);
|
||||
|
||||
return &holes[i];
|
||||
}
|
||||
// Update map properties (ZScream: EntranceMode.cs:90)
|
||||
holes[i].UpdateMapProperties(map_id, overworld);
|
||||
|
||||
LOG_DEBUG("EntityOps", "Inserted hole at slot %zu: pos=(%d,%d) map=0x%02X",
|
||||
i, holes[i].x_, holes[i].y_, map_id);
|
||||
|
||||
return &holes[i];
|
||||
}
|
||||
return absl::ResourceExhaustedError(
|
||||
"No space available for new hole. Delete one first.");
|
||||
|
||||
} else {
|
||||
// Search for first deleted entrance slot (ZScream: EntranceMode.cs:104-130)
|
||||
auto* entrances = overworld->mutable_entrances();
|
||||
for (size_t i = 0; i < entrances->size(); ++i) {
|
||||
if (entrances->at(i).deleted) {
|
||||
// Reuse deleted slot
|
||||
entrances->at(i).deleted = false;
|
||||
entrances->at(i).map_id_ = map_id;
|
||||
entrances->at(i).x_ = static_cast<int>(snapped_pos.x);
|
||||
entrances->at(i).y_ = static_cast<int>(snapped_pos.y);
|
||||
entrances->at(i).entrance_id_ = 0; // Default, user configures in popup
|
||||
entrances->at(i).is_hole_ = false;
|
||||
|
||||
// Update map properties (ZScream: EntranceMode.cs:120)
|
||||
entrances->at(i).UpdateMapProperties(map_id);
|
||||
}
|
||||
return absl::ResourceExhaustedError(
|
||||
"No space available for new hole. Delete one first.");
|
||||
|
||||
} else {
|
||||
// Search for first deleted entrance slot (ZScream: EntranceMode.cs:104-130)
|
||||
auto* entrances = overworld->mutable_entrances();
|
||||
for (size_t i = 0; i < entrances->size(); ++i) {
|
||||
if (entrances->at(i).deleted) {
|
||||
// Reuse deleted slot
|
||||
entrances->at(i).deleted = false;
|
||||
entrances->at(i).map_id_ = map_id;
|
||||
entrances->at(i).x_ = static_cast<int>(snapped_pos.x);
|
||||
entrances->at(i).y_ = static_cast<int>(snapped_pos.y);
|
||||
entrances->at(i).entrance_id_ = 0; // Default, user configures in popup
|
||||
entrances->at(i).is_hole_ = false;
|
||||
|
||||
// Update map properties (ZScream: EntranceMode.cs:120)
|
||||
entrances->at(i).UpdateMapProperties(map_id, overworld);
|
||||
|
||||
LOG_DEBUG("EntityOps", "Inserted entrance at slot %zu: pos=(%d,%d) map=0x%02X",
|
||||
i, entrances->at(i).x_, entrances->at(i).y_, map_id);
|
||||
@@ -111,8 +111,8 @@ absl::StatusOr<zelda3::OverworldExit*> InsertExit(
|
||||
exits[i].door_type_1_ = 0;
|
||||
exits[i].door_type_2_ = 0;
|
||||
|
||||
// Update map properties
|
||||
exits[i].UpdateMapProperties(map_id);
|
||||
// Update map properties with overworld context for area size detection
|
||||
exits[i].UpdateMapProperties(map_id, overworld);
|
||||
|
||||
LOG_DEBUG("EntityOps", "Inserted exit at slot %zu: pos=(%d,%d) map=0x%02X",
|
||||
i, exits[i].x_, exits[i].y_, map_id);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "app/gui/core/input.h"
|
||||
#include "app/gui/core/layout_helpers.h"
|
||||
#include "zelda3/overworld/overworld_map.h"
|
||||
#include "zelda3/overworld/overworld_version_helper.h"
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
namespace yaze {
|
||||
@@ -60,15 +61,15 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings(
|
||||
ImGui::Text("%d (0x%02X)", current_map, current_map);
|
||||
|
||||
TableNextColumn();
|
||||
// IMPORTANT: Don't cache - read fresh to reflect ROM upgrades
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
// Use centralized version detection
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
// ALL ROMs support Small/Large. Only v3+ supports Wide/Tall.
|
||||
int current_area_size =
|
||||
static_cast<int>(overworld_->overworld_map(current_map)->area_size());
|
||||
ImGui::SetNextItemWidth(kComboAreaSizeWidth);
|
||||
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version)) {
|
||||
// v3+ ROM: Show all 4 area size options
|
||||
if (ImGui::Combo("##AreaSize", ¤t_area_size, kAreaSizeNames, 4)) {
|
||||
auto status = overworld_->ConfigureMultiAreaMap(
|
||||
@@ -95,7 +96,8 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings(
|
||||
}
|
||||
}
|
||||
|
||||
if (asm_version == 0xFF || asm_version < 3) {
|
||||
if (rom_version == zelda3::OverworldVersion::kVanilla ||
|
||||
!zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version)) {
|
||||
HOVER_HINT("Small (1x1) and Large (2x2) maps. Wide/Tall require v3+");
|
||||
}
|
||||
}
|
||||
@@ -223,9 +225,9 @@ void MapPropertiesSystem::DrawMapPropertiesPanel(
|
||||
}
|
||||
|
||||
// Custom Overworld Features Tab
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version != 0xFF && ImGui::BeginTabItem("Custom Features")) {
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (rom_version != zelda3::OverworldVersion::kVanilla &&
|
||||
ImGui::BeginTabItem("Custom Features")) {
|
||||
DrawCustomFeaturesTab(current_map);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
@@ -254,9 +256,8 @@ void MapPropertiesSystem::DrawCustomBackgroundColorEditor(
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version < 2) {
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (!zelda3::OverworldVersionHelper::SupportsCustomBGColors(rom_version)) {
|
||||
Text("Custom background colors require ZSCustomOverworld v2+");
|
||||
return;
|
||||
}
|
||||
@@ -309,15 +310,14 @@ void MapPropertiesSystem::DrawOverlayEditor(int current_map,
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
|
||||
ICON_MD_LAYERS " Visual Effects Configuration");
|
||||
ImGui::Text("Map: 0x%02X", current_map);
|
||||
Separator();
|
||||
|
||||
if (asm_version < 1) {
|
||||
if (rom_version == zelda3::OverworldVersion::kVanilla) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.4f, 1.0f),
|
||||
ICON_MD_WARNING " Subscreen overlays require ZSCustomOverworld v1+");
|
||||
ImGui::Separator();
|
||||
@@ -491,9 +491,8 @@ void MapPropertiesSystem::SetupCanvasContextMenu(
|
||||
canvas.AddContextMenuItem(properties_item);
|
||||
|
||||
// Custom overworld features (only show if v3+)
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version)) {
|
||||
// Custom Background Color
|
||||
gui::CanvasMenuItem bg_color_item;
|
||||
bg_color_item.label = ICON_MD_FORMAT_COLOR_FILL " Custom Background Color";
|
||||
@@ -589,9 +588,8 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) {
|
||||
}
|
||||
HOVER_HINT("Sprite graphics sheet for current game state");
|
||||
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 3) {
|
||||
auto rom_version_gfx = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (zelda3::OverworldVersionHelper::SupportsAnimatedGFX(rom_version_gfx)) {
|
||||
if (gui::InputHexByte(ICON_MD_ANIMATION " Animated GFX",
|
||||
overworld_->mutable_overworld_map(current_map)
|
||||
->mutable_animated_gfx(),
|
||||
@@ -605,7 +603,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) {
|
||||
}
|
||||
|
||||
// Custom Tile Graphics - Only available for v1+ ROMs
|
||||
if (asm_version >= 1 && asm_version != 0xFF) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsExpandedSpace(rom_version_gfx)) {
|
||||
ImGui::Separator();
|
||||
ImGui::Text(ICON_MD_GRID_VIEW " Custom Tile Graphics");
|
||||
ImGui::Separator();
|
||||
@@ -631,7 +629,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) {
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
} else if (asm_version == 0xFF) {
|
||||
} else if (rom_version_gfx == zelda3::OverworldVersion::kVanilla) {
|
||||
ImGui::Separator();
|
||||
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f),
|
||||
ICON_MD_INFO " Custom Tile Graphics");
|
||||
@@ -672,8 +670,8 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state,
|
||||
HOVER_HINT("Main color palette for background tiles");
|
||||
|
||||
// Read fresh to reflect ROM upgrades
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 2) {
|
||||
auto rom_version_pal = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (zelda3::OverworldVersionHelper::SupportsCustomBGColors(rom_version_pal)) {
|
||||
if (gui::InputHexByte(ICON_MD_COLOR_LENS " Main Palette",
|
||||
overworld_->mutable_overworld_map(current_map)
|
||||
->mutable_main_palette(),
|
||||
@@ -1037,14 +1035,13 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) {
|
||||
ImGui::Text(ICON_MD_PHOTO_SIZE_SELECT_LARGE " Area Size");
|
||||
TableNextColumn();
|
||||
// ALL ROMs support Small/Large. Only v3+ supports Wide/Tall.
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
auto rom_version_basic = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
int current_area_size =
|
||||
static_cast<int>(overworld_->overworld_map(current_map)->area_size());
|
||||
ImGui::SetNextItemWidth(130.f);
|
||||
|
||||
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version_basic)) {
|
||||
// v3+ ROM: Show all 4 area size options
|
||||
static const char* all_sizes[] = {"Small (1x1)", "Large (2x2)",
|
||||
"Wide (2x1)", "Tall (1x2)"};
|
||||
@@ -1079,7 +1076,7 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) {
|
||||
}
|
||||
}
|
||||
|
||||
if (asm_version >= 2) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsCustomBGColors(rom_version_basic)) {
|
||||
TableNextColumn();
|
||||
ImGui::Text(ICON_MD_COLOR_LENS " Main Palette");
|
||||
TableNextColumn();
|
||||
@@ -1096,7 +1093,7 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) {
|
||||
}
|
||||
}
|
||||
|
||||
if (asm_version >= 3) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsAnimatedGFX(rom_version_basic)) {
|
||||
TableNextColumn();
|
||||
ImGui::Text(ICON_MD_ANIMATION " Animated GFX");
|
||||
TableNextColumn();
|
||||
@@ -1131,10 +1128,10 @@ void MapPropertiesSystem::DrawCustomFeaturesTab(int current_map) {
|
||||
}
|
||||
|
||||
void MapPropertiesSystem::DrawTileGraphicsTab(int current_map) {
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
// Only show custom tile graphics for v1+ ROMs
|
||||
if (asm_version >= 1 && asm_version != 0xFF) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsExpandedSpace(rom_version)) {
|
||||
ImGui::Text(ICON_MD_GRID_VIEW " Custom Tile Graphics (8 sheets)");
|
||||
Separator();
|
||||
|
||||
@@ -1350,9 +1347,8 @@ void MapPropertiesSystem::RefreshSiblingMapGraphics(int map_index, bool include_
|
||||
}
|
||||
|
||||
void MapPropertiesSystem::DrawMosaicControls(int current_map) {
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
if (asm_version >= 2) {
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
if (zelda3::OverworldVersionHelper::SupportsCustomBGColors(rom_version)) {
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Mosaic Effects (per direction):");
|
||||
|
||||
@@ -1379,8 +1375,7 @@ void MapPropertiesSystem::DrawMosaicControls(int current_map) {
|
||||
|
||||
void MapPropertiesSystem::DrawOverlayControls(int current_map,
|
||||
bool& show_overlay_preview) {
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
|
||||
// Determine if this is a special overworld map (0x80-0x9F)
|
||||
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
||||
@@ -1491,7 +1486,7 @@ void MapPropertiesSystem::DrawOverlayControls(int current_map,
|
||||
ImGui::Separator();
|
||||
|
||||
// Interactive/Dynamic Map Overlay Section (for vanilla ROMs)
|
||||
if (asm_version == 0xFF) {
|
||||
if (rom_version == zelda3::OverworldVersion::kVanilla) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f),
|
||||
ICON_MD_EDIT_NOTE " Map Overlay (Interactive)");
|
||||
ImGui::SameLine();
|
||||
@@ -1537,16 +1532,17 @@ void MapPropertiesSystem::DrawOverlayControls(int current_map,
|
||||
|
||||
// Show version and capability info
|
||||
ImGui::Separator();
|
||||
if (asm_version == 0xFF) {
|
||||
if (rom_version == zelda3::OverworldVersion::kVanilla) {
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f),
|
||||
ICON_MD_INFO " Vanilla ROM");
|
||||
ImGui::BulletText("Visual effects use maps 0x80-0x9F");
|
||||
ImGui::BulletText("Map overlays are read-only");
|
||||
} else {
|
||||
const char* version_name = zelda3::OverworldVersionHelper::GetVersionName(rom_version);
|
||||
ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f),
|
||||
ICON_MD_UPGRADE " ZSCustomOverworld v%d", asm_version);
|
||||
ICON_MD_UPGRADE " %s", version_name);
|
||||
ImGui::BulletText("Enhanced visual effect control");
|
||||
if (asm_version >= 3) {
|
||||
if (zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version)) {
|
||||
ImGui::BulletText("Extended overlay system");
|
||||
ImGui::BulletText("Custom area sizes support");
|
||||
}
|
||||
@@ -1592,8 +1588,6 @@ void MapPropertiesSystem::DrawOverlayPreviewOnMap(int current_map,
|
||||
uint16_t overlay_id = 0x00FF;
|
||||
bool has_subscreen_overlay = false;
|
||||
|
||||
uint8_t asm_version =
|
||||
(*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0);
|
||||
|
||||
if (is_special_overworld_map) {
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "zelda3/overworld/overworld_exit.h"
|
||||
#include "zelda3/overworld/overworld_item.h"
|
||||
#include "zelda3/overworld/overworld_map.h"
|
||||
#include "zelda3/overworld/overworld_version_helper.h"
|
||||
#include "zelda3/sprite/sprite.h"
|
||||
|
||||
namespace yaze::editor {
|
||||
@@ -491,8 +492,9 @@ void OverworldEditor::DrawToolset() {
|
||||
// Modern adaptive toolbar with inline mode switching and properties
|
||||
static gui::Toolset toolbar;
|
||||
|
||||
// IMPORTANT: Don't make asm_version static - it needs to update after ROM upgrade
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
// IMPORTANT: Don't cache version - it needs to update after ROM upgrade
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; // Still needed for badge display
|
||||
|
||||
// Don't use WidgetIdScope here - it conflicts with ImGui::Begin/End ID stack in cards
|
||||
// Widgets register themselves individually instead
|
||||
@@ -1256,9 +1258,9 @@ absl::Status OverworldEditor::CheckForCurrentMap() {
|
||||
|
||||
const int current_highlighted_map = current_map_;
|
||||
|
||||
// Check if ZSCustomOverworld v3 is present
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
bool use_v3_area_sizes = (asm_version >= 3);
|
||||
// Use centralized version detection
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
bool use_v3_area_sizes = zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version);
|
||||
|
||||
// Get area size for v3+ ROMs, otherwise use legacy logic
|
||||
if (use_v3_area_sizes) {
|
||||
@@ -1622,7 +1624,8 @@ void OverworldEditor::DrawOverworldCanvas() {
|
||||
MoveEntityOnGrid(dragged_entity_, ow_map_canvas_.zero_point(),
|
||||
ow_map_canvas_.scrolling(),
|
||||
dragged_entity_free_movement_);
|
||||
dragged_entity_->UpdateMapProperties(dragged_entity_->map_id_);
|
||||
// Pass overworld context for proper area size detection
|
||||
dragged_entity_->UpdateMapProperties(dragged_entity_->map_id_, &overworld_);
|
||||
rom_->set_dirty(true);
|
||||
}
|
||||
is_dragging_entity_ = false;
|
||||
@@ -2118,9 +2121,9 @@ void OverworldEditor::RefreshChildMapOnDemand(int map_index) {
|
||||
}
|
||||
|
||||
// Handle multi-area maps (large, wide, tall) with safe coordination
|
||||
// Check if ZSCustomOverworld v3 is present
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
bool use_v3_area_sizes = (asm_version >= 3 && asm_version != 0xFF);
|
||||
// Use centralized version detection
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
bool use_v3_area_sizes = zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version);
|
||||
|
||||
if (use_v3_area_sizes) {
|
||||
// Use v3 multi-area coordination
|
||||
@@ -2302,9 +2305,9 @@ absl::Status OverworldEditor::RefreshMapPalette() {
|
||||
overworld_.mutable_overworld_map(current_map_)->LoadPalette());
|
||||
const auto current_map_palette = overworld_.current_area_palette();
|
||||
|
||||
// Check if ZSCustomOverworld v3 is present
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
bool use_v3_area_sizes = (asm_version >= 3 && asm_version != 0xFF);
|
||||
// Use centralized version detection
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
bool use_v3_area_sizes = zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version);
|
||||
|
||||
if (use_v3_area_sizes) {
|
||||
// Use v3 area size system
|
||||
@@ -2444,9 +2447,9 @@ void OverworldEditor::RefreshSiblingMapGraphics(int map_index,
|
||||
void OverworldEditor::RefreshMapProperties() {
|
||||
const auto& current_ow_map = *overworld_.mutable_overworld_map(current_map_);
|
||||
|
||||
// Check if ZSCustomOverworld v3 is present
|
||||
uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied];
|
||||
bool use_v3_area_sizes = (asm_version >= 3);
|
||||
// Use centralized version detection
|
||||
auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
|
||||
bool use_v3_area_sizes = zelda3::OverworldVersionHelper::SupportsAreaEnum(rom_version);
|
||||
|
||||
if (use_v3_area_sizes) {
|
||||
// Use v3 area size system
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "overworld_entity_renderer.h"
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "core/features.h"
|
||||
@@ -7,6 +8,7 @@
|
||||
#include "zelda3/common.h"
|
||||
#include "util/hex.h"
|
||||
#include "imgui/imgui.h"
|
||||
#include "zelda3/overworld/overworld_item.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
@@ -24,7 +26,7 @@ ImVec4 GetSpriteColor() { return ImVec4{1.0f, 0.0f, 1.0f, 1.0f}; } // So
|
||||
void OverworldEntityRenderer::DrawEntrances(ImVec2 canvas_p0, ImVec2 scrolling,
|
||||
int current_world,
|
||||
int current_mode) {
|
||||
hovered_entity_ = nullptr;
|
||||
// Don't reset hovered_entity_ here - DrawExits resets it (called first)
|
||||
int i = 0;
|
||||
for (auto& each : overworld_->entrances()) {
|
||||
if (each.map_id_ < 0x40 + (current_world * 0x40) &&
|
||||
@@ -56,11 +58,15 @@ void OverworldEntityRenderer::DrawEntrances(ImVec2 canvas_p0, ImVec2 scrolling,
|
||||
void OverworldEntityRenderer::DrawExits(ImVec2 canvas_p0, ImVec2 scrolling,
|
||||
int current_world,
|
||||
int current_mode) {
|
||||
// Reset hover state at the start of entity rendering (DrawExits is called first)
|
||||
hovered_entity_ = nullptr;
|
||||
|
||||
int i = 0;
|
||||
for (auto& each : *overworld_->mutable_exits()) {
|
||||
if (each.map_id_ < 0x40 + (current_world * 0x40) &&
|
||||
each.map_id_ >= (current_world * 0x40) && !each.deleted_) {
|
||||
canvas_->DrawRect(each.x_, each.y_, 16, 16, GetExitColor());
|
||||
|
||||
if (IsMouseHoveringOverEntity(each, canvas_p0, scrolling)) {
|
||||
hovered_entity_ = &each;
|
||||
}
|
||||
@@ -91,7 +97,7 @@ void OverworldEntityRenderer::DrawItems(int current_world, int current_mode) {
|
||||
}
|
||||
|
||||
|
||||
std::string item_name = "";
|
||||
std::string item_name = "";
|
||||
if (item.id_ < zelda3::kSecretItemNames.size()) {
|
||||
item_name = zelda3::kSecretItemNames[item.id_];
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user