From 14d55710fc9756f8d22a6ee2467c92ecdd2f9f1e Mon Sep 17 00:00:00 2001 From: gbsierra Date: Tue, 15 Apr 2025 10:52:28 -0700 Subject: [PATCH 1/5] implement DIALOG_ANIMAL for imgui --- src/ui_imgui.hh | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/ui_imgui.hh b/src/ui_imgui.hh index 48e0fd63..f1d09dda 100644 --- a/src/ui_imgui.hh +++ b/src/ui_imgui.hh @@ -233,6 +233,7 @@ namespace UiSave { static void open(); static void layout(); } namespace UiNewLevel { static void open(); static void layout(); } namespace UiFrequency { static void open(bool is_range, entity *e = G->selection.e); static void layout(); } namespace UiConfirm { void open(const char* text, const char* button1, principia_action action1, const char* button2, principia_action action2, const char* button3, principia_action action3, struct confirm_data _confirm_data); void layout(); } +namespace UiAnimal { static void open(); static void layout(); } //On debug builds, open imgui demo window by pressing Shift+F9 #ifdef DEBUG @@ -2734,6 +2735,36 @@ namespace UiConfirm { } } +namespace UiAnimal { + static bool do_open = false; + + static void open() { + do_open = true; + } + + static void layout() { + handle_do_open(&do_open, "animal_select"); + if (ImGui::BeginPopup("animal_select", POPUP_FLAGS)) { + ImGui::SeparatorText("Select animal type:"); + for (int i = 0; i < NUM_ANIMAL_TYPES; ++i) { + if (ImGui::MenuItem(animal_data[i].name)) { + entity* e = G->selection.e; + + if (e && e->g_id == O_ANIMAL) { + W->add_action(e->id, ACTION_SET_ANIMAL_TYPE, UINT_TO_VOID((uint32_t)i)); + + P.add_action(ACTION_HIGHLIGHT_SELECTED, 0); + P.add_action(ACTION_RESELECT, 0); + } + } + } + + ImGui::EndPopup(); + } + } + +} + static void ui_init() { UiLevelManager::init(); UiLuaEditor::init(); @@ -2763,6 +2794,7 @@ static void ui_layout() { UiNewLevel::layout(); UiFrequency::layout(); UiConfirm::layout(); + UiAnimal::layout(); } //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* @@ -2932,6 +2964,9 @@ void ui::open_dialog(int num, void *data) { case DIALOG_LEVEL_INFO: UiMessage::open((char *)data, MessageType::LevelInfo); break; + case DIALOG_ANIMAL: + UiAnimal::open(); + break; default: tms_errorf("dialog %d not implemented yet", num); } From aa6cd38c35d45ef322f83c996bddb497828025de Mon Sep 17 00:00:00 2001 From: gbsierra Date: Tue, 15 Apr 2025 12:53:39 -0700 Subject: [PATCH 2/5] switch DIALOG_ANIMAL to PopupModal --- src/ui_imgui.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui_imgui.hh b/src/ui_imgui.hh index f1d09dda..54982324 100644 --- a/src/ui_imgui.hh +++ b/src/ui_imgui.hh @@ -2743,9 +2743,9 @@ namespace UiAnimal { } static void layout() { - handle_do_open(&do_open, "animal_select"); - if (ImGui::BeginPopup("animal_select", POPUP_FLAGS)) { - ImGui::SeparatorText("Select animal type:"); + handle_do_open(&do_open, "Select Animal Type:"); + ImGui::SetNextWindowSize(ImVec2(200, .0)); + if (ImGui::BeginPopupModal("Select Animal Type:", REF_TRUE, MODAL_FLAGS)) { for (int i = 0; i < NUM_ANIMAL_TYPES; ++i) { if (ImGui::MenuItem(animal_data[i].name)) { entity* e = G->selection.e; From fed31db590055dcbc058c928de75128aa975f7fa Mon Sep 17 00:00:00 2001 From: ROllerozxa Date: Thu, 17 Apr 2025 14:20:33 +0200 Subject: [PATCH 3/5] Update ui_imgui.hh --- src/ui_imgui.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui_imgui.hh b/src/ui_imgui.hh index 54982324..453912aa 100644 --- a/src/ui_imgui.hh +++ b/src/ui_imgui.hh @@ -2743,9 +2743,9 @@ namespace UiAnimal { } static void layout() { - handle_do_open(&do_open, "Select Animal Type:"); + handle_do_open(&do_open, "Animal type"); ImGui::SetNextWindowSize(ImVec2(200, .0)); - if (ImGui::BeginPopupModal("Select Animal Type:", REF_TRUE, MODAL_FLAGS)) { + if (ImGui::BeginPopupModal("Animal type", REF_TRUE, MODAL_FLAGS)) { for (int i = 0; i < NUM_ANIMAL_TYPES; ++i) { if (ImGui::MenuItem(animal_data[i].name)) { entity* e = G->selection.e; From 3b62d7fd800adbcfd9bc461a31d16838a91b7ee8 Mon Sep 17 00:00:00 2001 From: gbsierra Date: Thu, 17 Apr 2025 13:31:31 -0700 Subject: [PATCH 4/5] implement DIALOG_TREASURE_CHEST for imgui --- src/ui_imgui.hh | 197 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) diff --git a/src/ui_imgui.hh b/src/ui_imgui.hh index 453912aa..f69fbee2 100644 --- a/src/ui_imgui.hh +++ b/src/ui_imgui.hh @@ -234,6 +234,7 @@ namespace UiNewLevel { static void open(); static void layout(); } namespace UiFrequency { static void open(bool is_range, entity *e = G->selection.e); static void layout(); } namespace UiConfirm { void open(const char* text, const char* button1, principia_action action1, const char* button2, principia_action action2, const char* button3, principia_action action3, struct confirm_data _confirm_data); void layout(); } namespace UiAnimal { static void open(); static void layout(); } +namespace UiTreasureChest { static void open(); static void layout(); } //On debug builds, open imgui demo window by pressing Shift+F9 #ifdef DEBUG @@ -2765,6 +2766,198 @@ namespace UiAnimal { } +namespace UiTreasureChest { + static bool do_open = false; + static int selected_index = -1; + static int selected_entity = 0; + static int selected_sub_entity = 0; + static int selected_count = 1; + + struct ChestItem { + int g_id; + int sub_id; + int count; + }; + + static std::vector chest_items = {}; + + static void open() { + do_open = true; + } + + static void layout() { // ISSUE - keeps previous properties on new chest. however new chest seems to be random until modified. + handle_do_open(&do_open, "Treasure chest"); + if (ImGui::BeginPopupModal("Treasure chest", REF_TRUE, MODAL_FLAGS)) { + entity* e = G->selection.e; + + // Entities + std::vector entity_labels; + std::vector entity_label_ptrs; + for (const auto& obj : menu_objects) { + if (obj.e != nullptr) { + entity_labels.push_back(obj.e->get_name()); + } + } + for (auto& label : entity_labels) { + entity_label_ptrs.push_back(label.c_str()); + } + if (!entity_label_ptrs.empty()) { + static int prev_selected_entity = -1; + if (ImGui::Combo("##Entity", &selected_entity, entity_label_ptrs.data(), (int)entity_label_ptrs.size())) { + selected_sub_entity = 0; + prev_selected_entity = selected_entity; + } + } + else { + ImGui::TextDisabled("No entities"); + } + + // Sub-Entities + std::vector sub_entity_labels; + std::vector sub_entity_ptrs; + if (selected_entity >= 0 && selected_entity < menu_objects.size()) { + entity* selected_entity_ptr = menu_objects[selected_entity].e; + if (selected_entity_ptr) { + int g_id = selected_entity_ptr->g_id; + + if (g_id == O_ITEM) { + for (int i = 0; i < NUM_ITEMS; ++i) { + sub_entity_labels.emplace_back(item_options[i].name); + } + } else if (g_id == O_RESOURCE) { + for (int i = 0; i < NUM_RESOURCES; ++i) { + sub_entity_labels.emplace_back(resource_data[i].name); + } + } + + for (auto& label : sub_entity_labels) { + sub_entity_ptrs.push_back(label.c_str()); + } + + if (!sub_entity_ptrs.empty()) { + ImGui::Combo("##SubEntity", &selected_sub_entity, sub_entity_ptrs.data(), (int)sub_entity_ptrs.size()); + } else { + ImGui::TextDisabled("No sub-entities"); + } + } + } + + // (consider adding amount limit) + ImGui::InputInt("Amount", &selected_count); + if (selected_count < 1){ + selected_count = 1; + } + + static std::vector parsed_items; + parsed_items.clear(); + if (e && e->g_id == O_TREASURE_CHEST) { + char* str = strdup(e->properties[0].v.s.buf); + parsed_items = treasure_chest::parse_items(str); + free(str); + } + + ImGui::Separator(); + if (ImGui::Button("Add entity")) { + if (selected_entity >= 0 && selected_entity < menu_objects.size()) { + entity* selected_entity_ptr = menu_objects[selected_entity].e; + if (selected_entity_ptr) { + chest_items.push_back({ selected_entity_ptr->g_id, selected_sub_entity, selected_count }); + } + } + } + ImGui::SameLine(); + if (ImGui::Button("Remove selected")) { + if (selected_index >= 0 && selected_index < chest_items.size()) { + chest_items.erase(chest_items.begin() + selected_index); + selected_index = -1; + } + } + + // Table + ImGui::Separator(); + if (ImGui::BeginTable("ChestItems", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) { + ImGui::TableSetupColumn("Entity"); + ImGui::TableSetupColumn("Sub-Entity"); + ImGui::TableSetupColumn("Count"); + ImGui::TableHeadersRow(); + + for (int i = 0; i < chest_items.size(); ++i) { + auto& item = chest_items[i]; + ImGui::TableNextRow(); + + const char* g_name = "Unknown"; + const char* sub_name = "-"; + + switch (item.g_id) { + case O_ITEM: + g_name = "Item"; + if (item.sub_id >= 0 && item.sub_id < NUM_ITEMS) { + sub_name = item_options[item.sub_id].name; + } + break; + + case O_RESOURCE: + g_name = "Resource"; + if (item.sub_id >= 0 && item.sub_id < NUM_RESOURCES) { + sub_name = resource_data[item.sub_id].name; + } + break; + + default: { + // (no sub-entity) + entity* e = of::create(item.g_id); + if (e) { + g_name = e->get_name(); + delete e; + } + break; + } + } + + ImGui::TableSetColumnIndex(0); + ImGui::PushID(i); + bool is_selected = (i == selected_index); + if (ImGui::RadioButton(g_name, is_selected)) { + selected_index = i; + } + ImGui::PopID(); + ImGui::TableSetColumnIndex(1); + ImGui::TextUnformatted(sub_name); + + ImGui::TableSetColumnIndex(2); + ImGui::Text("%d", item.count); + } + + ImGui::EndTable(); + } + + + ImGui::Separator(); + if (ImGui::Button("Accept")) { + if (e && e->g_id == O_TREASURE_CHEST) { + treasure_chest* tc = static_cast(e); + std::stringstream ss; + for (size_t i = 0; i < chest_items.size(); ++i) { + if (i > 0) ss << ";"; + ss << chest_items[i].g_id << ":" << chest_items[i].sub_id << ":" << chest_items[i].count; + } + tc->set_property(0, ss.str().c_str()); + P.add_action(ACTION_HIGHLIGHT_SELECTED, 0); + P.add_action(ACTION_RESELECT, 0); + } + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel")) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + } + +} + static void ui_init() { UiLevelManager::init(); UiLuaEditor::init(); @@ -2795,6 +2988,7 @@ static void ui_layout() { UiFrequency::layout(); UiConfirm::layout(); UiAnimal::layout(); + UiTreasureChest::layout(); } //*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* @@ -2967,6 +3161,9 @@ void ui::open_dialog(int num, void *data) { case DIALOG_ANIMAL: UiAnimal::open(); break; + case DIALOG_TREASURE_CHEST: + UiTreasureChest::open(); + break; default: tms_errorf("dialog %d not implemented yet", num); } From 8e093e8e6cc1a124a88ab9398e97764fb14b96c9 Mon Sep 17 00:00:00 2001 From: gbsierra Date: Thu, 17 Apr 2025 15:50:57 -0700 Subject: [PATCH 5/5] read existing properties on open --- src/ui_imgui.hh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ui_imgui.hh b/src/ui_imgui.hh index f69fbee2..ce09f339 100644 --- a/src/ui_imgui.hh +++ b/src/ui_imgui.hh @@ -2783,9 +2783,21 @@ namespace UiTreasureChest { static void open() { do_open = true; + entity* e = G->selection.e; + chest_items.clear(); + selected_index = -1; + + if (e && e->g_id == O_TREASURE_CHEST) { + char* str = strdup(e->properties[0].v.s.buf); + std::vector parsed_items = treasure_chest::parse_items(str); + free(str); + for (const auto& item : parsed_items) { + chest_items.push_back({ item.g_id, item.sub_id, item.count }); + } + } } - static void layout() { // ISSUE - keeps previous properties on new chest. however new chest seems to be random until modified. + static void layout() { handle_do_open(&do_open, "Treasure chest"); if (ImGui::BeginPopupModal("Treasure chest", REF_TRUE, MODAL_FLAGS)) { entity* e = G->selection.e;