diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 2e7910f2..2bd0946b 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -25,6 +25,7 @@ ${CMAKE_CURRENT_LIST_DIR}/editor.h
${CMAKE_CURRENT_LIST_DIR}/editor_tabs.h
${CMAKE_CURRENT_LIST_DIR}/extension.h
${CMAKE_CURRENT_LIST_DIR}/extension_window.h
+${CMAKE_CURRENT_LIST_DIR}/find_item_window.h
${CMAKE_CURRENT_LIST_DIR}/filehandle.h
${CMAKE_CURRENT_LIST_DIR}/graphics.h
${CMAKE_CURRENT_LIST_DIR}/ground_brush.h
@@ -125,6 +126,7 @@ ${CMAKE_CURRENT_LIST_DIR}/editor_tabs.cpp
${CMAKE_CURRENT_LIST_DIR}/eraser_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/extension.cpp
${CMAKE_CURRENT_LIST_DIR}/extension_window.cpp
+${CMAKE_CURRENT_LIST_DIR}/find_item_window.cpp
${CMAKE_CURRENT_LIST_DIR}/filehandle.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics.cpp
${CMAKE_CURRENT_LIST_DIR}/ground_brush.cpp
diff --git a/source/common_windows.cpp b/source/common_windows.cpp
index f5f38a53..c46c7104 100644
--- a/source/common_windows.cpp
+++ b/source/common_windows.cpp
@@ -773,113 +773,6 @@ void FindDialog::RefreshContents()
RefreshContentsInternal();
}
-// ============================================================================
-// Find Item Dialog (Jump to item)
-
-FindItemDialog::FindItemDialog(wxWindow* parent, wxString title) : FindDialog(parent, title)
-{
- extra_condition = nullptr;
- RefreshContents();
-}
-
-FindItemDialog::~FindItemDialog()
-{
- ////
-}
-
-void FindItemDialog::setCondition(bool condition(const ItemType&)) {
- extra_condition = condition;
-}
-
-void FindItemDialog::OnClickListInternal(wxCommandEvent& event)
-{
- Brush* brush = item_list->GetSelectedBrush();
- if(brush && brush->isRaw()) {
- result_brush = brush;
- result_id = brush->asRaw()->getItemID();
- EndModal(result_id);
- }
-}
-
-void FindItemDialog::OnClickOKInternal()
-{
- // This is kind of stupid as it would fail unless the "Please enter a search string" wasn't there
- if(item_list->GetItemCount() > 0) {
- if(item_list->GetSelection() == wxNOT_FOUND) {
- item_list->SetSelection(0);
- }
-
- Brush* brush = item_list->GetSelectedBrush();
- if (brush && brush->isRaw()) {
- result_brush = brush;
- result_id = brush->asRaw()->getItemID();
- } else {
- // It's either "Please enter a search string" or "No matches"
- // Perhaps we can refresh now?
- std::string search_string = as_lower_str(nstr(search_field->GetValue()));
- bool do_search = (search_string.size() >= 2);
-
- if(do_search) {
- for(int id = 0; id <= g_items.getMaxID(); ++id) {
- ItemType& it = g_items[id];
- if(it.id == 0 || (extra_condition && !extra_condition(it)))
- continue;
-
- RAWBrush* raw_brush = it.raw_brush;
- if(!raw_brush)
- continue;
-
- if(as_lower_str(raw_brush->getName()).find(search_string) == std::string::npos)
- continue;
-
- // Found one!
- result_brush = raw_brush;
- result_id = raw_brush->getItemID();
- break;
- }
- }
- }
- }
- EndModal(result_id);
-}
-
-void FindItemDialog::RefreshContentsInternal()
-{
- item_list->Clear();
-
- std::string search_string = as_lower_str(nstr(search_field->GetValue()));
- bool do_search = (search_string.size() >= 2);
-
- if(do_search) {
-
- bool found_search_results = false;
-
- for(int id = 0; id <= g_items.getMaxID(); ++id) {
- ItemType& it = g_items[id];
- if(it.id == 0 || (extra_condition && !extra_condition(it)))
- continue;
-
- RAWBrush* raw_brush = it.raw_brush;
- if(!raw_brush)
- continue;
-
- if(as_lower_str(raw_brush->getName()).find(search_string) == std::string::npos)
- continue;
-
- found_search_results = true;
- item_list->AddBrush(raw_brush);
- }
-
-
- if(found_search_results)
- item_list->SetSelection(0);
- else
- item_list->SetNoMatches();
-
- }
- item_list->Refresh();
-}
-
// ============================================================================
// Find Brush Dialog (Jump to brush)
diff --git a/source/common_windows.h b/source/common_windows.h
index 14af129e..1301805a 100644
--- a/source/common_windows.h
+++ b/source/common_windows.h
@@ -240,26 +240,6 @@ class FindBrushDialog : public FindDialog
virtual void OnClickOKInternal();
};
-/**
- * Select an item dialog
- * Find out what item was selected through return value of ShowModal() or getResultID
- */
-class FindItemDialog : public FindDialog
-{
-public:
- FindItemDialog(wxWindow* parent, wxString title = "Jump to Item");
- virtual ~FindItemDialog();
-
- void setCondition(bool condition(const ItemType&));
-
- virtual void RefreshContentsInternal();
- virtual void OnClickListInternal(wxCommandEvent&);
- virtual void OnClickOKInternal();
-
-protected:
- bool (*extra_condition)(const ItemType&);
-};
-
/**
* Select two items
* Will return the two selected items through GetResultFindID() and GetResultWithID()
diff --git a/source/container_properties_window.cpp b/source/container_properties_window.cpp
index 14c602bd..ce65b4c3 100644
--- a/source/container_properties_window.cpp
+++ b/source/container_properties_window.cpp
@@ -8,6 +8,7 @@
#include "old_properties_window.h"
#include "properties_window.h"
+#include "find_item_window.h"
#include "gui.h"
#include "complexitem.h"
#include "map.h"
@@ -70,32 +71,23 @@ void ContainerItemButton::OnMouseRightRelease(wxMouseEvent& WXUNUSED(event))
void ContainerItemButton::OnAddItem(wxCommandEvent& WXUNUSED(event))
{
- FindItemDialog* itemDialog = newd FindItemDialog(GetParent(), "Choose Item to add");
- itemDialog->setCondition([](const ItemType& itemType) -> bool {
- return itemType.pickupable;
- });
+ FindItemDialog dialog(GetParent(), "Choose Item to add", true);
- int32_t id = itemDialog->ShowModal();
- itemDialog->Destroy();
+ if(dialog.ShowModal() != 0) {
+ Container* container = getParentContainer();
+ ItemVector& itemVector = container->getVector();
- if(id == 0) {
- return;
- }
-
- Container* container = getParentContainer();
- ItemVector& itemVector = container->getVector();
+ Item* item = Item::Create(dialog.getResultID());
+ if(index < itemVector.size())
+ itemVector.insert(itemVector.begin() + index, item);
+ else
+ itemVector.push_back(item);
- Item* item = Item::Create(id);
- if(index < itemVector.size()) {
- itemVector.insert(itemVector.begin() + index, item);
- } else {
- itemVector.push_back(item);
- }
-
- ObjectPropertiesWindowBase* propertyWindow = getParentContainerWindow();
- if(propertyWindow) {
- propertyWindow->Update();
+ ObjectPropertiesWindowBase* propertyWindow = getParentContainerWindow();
+ if(propertyWindow)
+ propertyWindow->Update();
}
+ dialog.Destroy();
}
void ContainerItemButton::OnEditItem(wxCommandEvent& WXUNUSED(event))
diff --git a/source/find_item_window.cpp b/source/find_item_window.cpp
new file mode 100644
index 00000000..97129af8
--- /dev/null
+++ b/source/find_item_window.cpp
@@ -0,0 +1,430 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Remere's Map Editor
+//////////////////////////////////////////////////////////////////////
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//////////////////////////////////////////////////////////////////////
+
+#include "main.h"
+#include "find_item_window.h"
+#include "common_windows.h"
+#include "gui.h"
+#include "items.h"
+#include "brush.h"
+#include "raw_brush.h"
+
+BEGIN_EVENT_TABLE(FindItemDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, FindItemDialog::OnClickOK)
+ EVT_BUTTON(wxID_CANCEL, FindItemDialog::OnClickCancel)
+END_EVENT_TABLE()
+
+FindItemDialog::FindItemDialog(wxWindow* parent, const wxString& title, bool onlyPickupables/* = false*/) :
+ wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxSize(800, 600), wxDEFAULT_DIALOG_STYLE),
+ result_brush(nullptr),
+ result_id(0)
+{
+ this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+ wxBoxSizer* box_sizer = newd wxBoxSizer(wxHORIZONTAL);
+
+ wxBoxSizer* options_box_sizer = newd wxBoxSizer(wxVERTICAL);
+
+ wxString radio_boxChoices[] = { "Find by Server ID",
+ "Find by Client ID",
+ "Find by Name",
+ "Find by Types",
+ "Find by Properties" };
+
+ int radio_boxNChoices = sizeof(radio_boxChoices) / sizeof(wxString);
+ options_radio_box = newd wxRadioBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, radio_boxNChoices, radio_boxChoices, 1, wxRA_SPECIFY_COLS);
+ options_radio_box->SetSelection(onlyPickupables ? SearchMode::Properties : SearchMode::ServerIDs);
+ options_radio_box->Enable(!onlyPickupables);
+ options_box_sizer->Add(options_radio_box, 0, wxALL | wxEXPAND, 5);
+
+ wxStaticBoxSizer* server_id_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Server ID"), wxVERTICAL);
+ server_id_spin = newd wxSpinCtrl(server_id_box_sizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 100, g_items.getMaxID(), 100);
+ server_id_spin->Enable(!onlyPickupables);
+ server_id_box_sizer->Add(server_id_spin, 0, wxALL | wxEXPAND, 5);
+ options_box_sizer->Add(server_id_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ wxStaticBoxSizer* client_id_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Client ID"), wxVERTICAL);
+ client_id_spin = newd wxSpinCtrl(client_id_box_sizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 100, g_gui.gfx.getItemSpriteMaxID(), 100);
+ client_id_spin->Enable(false);
+ client_id_box_sizer->Add(client_id_spin, 0, wxALL | wxEXPAND, 5);
+ options_box_sizer->Add(client_id_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ wxStaticBoxSizer* name_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Name"), wxVERTICAL);
+ name_text_input = newd wxTextCtrl(name_box_sizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+ name_text_input->Enable(false);
+ name_box_sizer->Add(name_text_input, 0, wxALL | wxEXPAND, 5);
+ options_box_sizer->Add(name_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ // spacer
+ options_box_sizer->Add(0, 0, 4, wxALL | wxEXPAND, 5);
+
+ buttons_box_sizer = newd wxStdDialogButtonSizer();
+ ok_button = newd wxButton(this, wxID_OK);
+ buttons_box_sizer->AddButton(ok_button);
+ cancel_button = newd wxButton(this, wxID_CANCEL);
+ buttons_box_sizer->AddButton(cancel_button);
+ buttons_box_sizer->Realize();
+ options_box_sizer->Add(buttons_box_sizer, 0, wxALIGN_CENTER | wxALL, 5);
+
+ box_sizer->Add(options_box_sizer, 1, wxALL, 5);
+
+ // --------------- Types ---------------
+
+ wxStaticBoxSizer* type_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Types"), wxVERTICAL);
+
+ wxString types_choices[] = { "Depot",
+ "Mailbox",
+ "Trash Holder",
+ "Container",
+ "Door",
+ "Magic Field",
+ "Teleport",
+ "Bed",
+ "Key" };
+
+ int types_choices_count = sizeof(types_choices) / sizeof(wxString);
+ types_radio_box = newd wxRadioBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, types_choices_count, types_choices, 1, wxRA_SPECIFY_COLS);
+ types_radio_box->SetSelection(0);
+ types_radio_box->Enable(false);
+ type_box_sizer->Add(types_radio_box, 0, wxALL | wxEXPAND, 5);
+
+ box_sizer->Add(type_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ // --------------- Properties ---------------
+
+ wxStaticBoxSizer* properties_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Properties"), wxVERTICAL);
+
+ unpassable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Unpassable", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(unpassable, 0, wxALL, 5);
+
+ unmovable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Unmovable", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(unmovable, 0, wxALL, 5);
+
+ block_missiles = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Block Missiles", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(block_missiles, 0, wxALL, 5);
+
+ block_pathfinder = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Block Pathfinder", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(block_pathfinder, 0, wxALL, 5);
+
+ pickupable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Pickupable", wxDefaultPosition, wxDefaultSize, 0);
+ pickupable->SetValue(onlyPickupables);
+ properties_box_sizer->Add(pickupable, 0, wxALL, 5);
+
+ stackable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Stackable", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(stackable, 0, wxALL, 5);
+
+ rotatable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Rotatable", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(rotatable, 0, wxALL, 5);
+
+ hangable = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Hangable", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(hangable, 0, wxALL, 5);
+
+ hook_east = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Hook East", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(hook_east, 0, wxALL, 5);
+
+ hook_south = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Hook South", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(hook_south, 0, wxALL, 5);
+
+ has_elevation = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Has Elevation", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(has_elevation, 0, wxALL, 5);
+
+ ignore_look = newd wxCheckBox(properties_box_sizer->GetStaticBox(), wxID_ANY, "Ignore Look", wxDefaultPosition, wxDefaultSize, 0);
+ properties_box_sizer->Add(ignore_look, 0, wxALL, 5);
+
+ box_sizer->Add(properties_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ // --------------- Items list ---------------
+
+ wxStaticBoxSizer* result_box_sizer = newd wxStaticBoxSizer(newd wxStaticBox(this, wxID_ANY, "Result"), wxVERTICAL);
+ items_list = newd FindDialogListBox(result_box_sizer->GetStaticBox(), wxID_ANY);
+ items_list->SetMinSize(wxSize(230, 512));
+ result_box_sizer->Add(items_list, 0, wxALL, 5);
+ box_sizer->Add(result_box_sizer, 1, wxALL | wxEXPAND, 5);
+
+ this->SetSizer(box_sizer);
+ this->Layout();
+ this->Centre(wxBOTH);
+ this->EnableProperties(false);
+ this->RefreshContentsInternal();
+
+ // Connect Events
+ options_radio_box->Connect(wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(FindItemDialog::OnOptionChange), NULL, this);
+ server_id_spin->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler(FindItemDialog::OnServerIdChange), NULL, this);
+ server_id_spin->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnServerIdChange), NULL, this);
+ client_id_spin->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler(FindItemDialog::OnClientIdChange), NULL, this);
+ client_id_spin->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnClientIdChange), NULL, this);
+ name_text_input->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnText), NULL, this);
+
+ types_radio_box->Connect(wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(FindItemDialog::OnTypeChange), NULL, this);
+
+ unpassable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ unmovable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ block_missiles->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ block_pathfinder->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ pickupable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ stackable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ rotatable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hangable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hook_east->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hook_south->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ has_elevation->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ ignore_look->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+}
+
+FindItemDialog::~FindItemDialog()
+{
+ // Disconnect Events
+ options_radio_box->Disconnect(wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(FindItemDialog::OnOptionChange), NULL, this);
+ server_id_spin->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler(FindItemDialog::OnServerIdChange), NULL, this);
+ server_id_spin->Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnServerIdChange), NULL, this);
+ client_id_spin->Disconnect(wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler(FindItemDialog::OnClientIdChange), NULL, this);
+ client_id_spin->Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnClientIdChange), NULL, this);
+ name_text_input->Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(FindItemDialog::OnText), NULL, this);
+
+ types_radio_box->Disconnect(wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler(FindItemDialog::OnTypeChange), NULL, this);
+
+ unpassable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ unmovable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ block_missiles->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ block_pathfinder->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ pickupable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ stackable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ rotatable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hangable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hook_east->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ hook_south->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ has_elevation->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+ ignore_look->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(FindItemDialog::OnPropertyChange), NULL, this);
+}
+
+FindItemDialog::SearchMode FindItemDialog::getSearchMode() const
+{
+ return (SearchMode)options_radio_box->GetSelection();
+}
+
+void FindItemDialog::setSearchMode(FindItemDialog::SearchMode mode)
+{
+ if((SearchMode)options_radio_box->GetSelection() != mode)
+ options_radio_box->SetSelection(mode);
+
+ server_id_spin->Enable(mode == SearchMode::ServerIDs);
+ client_id_spin->Enable(mode == SearchMode::ClientIDs);
+ name_text_input->Enable(mode == SearchMode::Names);
+ types_radio_box->Enable(mode == SearchMode::Types);
+ EnableProperties(mode == SearchMode::Properties);
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::EnableProperties(bool enable)
+{
+ unpassable->Enable(enable);
+ unmovable->Enable(enable);
+ block_missiles->Enable(enable);
+ block_pathfinder->Enable(enable);
+ pickupable->Enable(enable);
+ stackable->Enable(enable);
+ rotatable->Enable(enable);
+ hangable->Enable(enable);
+ hook_east->Enable(enable);
+ hook_south->Enable(enable);
+ has_elevation->Enable(enable);
+ ignore_look->Enable(enable);
+}
+
+void FindItemDialog::RefreshContentsInternal()
+{
+ items_list->Clear();
+
+ SearchMode selection = (SearchMode)options_radio_box->GetSelection();
+ bool found_search_results = false;
+
+ if(selection == SearchMode::ServerIDs) {
+ uint16_t serverID = (uint16_t)server_id_spin->GetValue();
+ for(int id = 100; id <= g_items.getMaxID(); ++id) {
+ ItemType& item = g_items.getItemType(id);
+ if(item.id != serverID)
+ continue;
+
+ RAWBrush* raw_brush = item.raw_brush;
+ if (!raw_brush)
+ continue;
+
+ found_search_results = true;
+ items_list->AddBrush(raw_brush);
+ }
+ }
+ else if(selection == SearchMode::ClientIDs) {
+ uint16_t clientID = (uint16_t)client_id_spin->GetValue();
+ for (int id = 100; id <= g_items.getMaxID(); ++id) {
+ ItemType& item = g_items.getItemType(id);
+ if (item.id == 0 || item.clientID != clientID)
+ continue;
+
+ RAWBrush* raw_brush = item.raw_brush;
+ if (!raw_brush)
+ continue;
+
+ found_search_results = true;
+ items_list->AddBrush(raw_brush);
+ }
+ }
+ else if(selection == SearchMode::Names) {
+ std::string search_string = as_lower_str(nstr(name_text_input->GetValue()));
+ if(search_string.size() >= 2) {
+ for(int id = 100; id <= g_items.getMaxID(); ++id) {
+ ItemType& item = g_items.getItemType(id);
+ if(item.id == 0)
+ continue;
+
+ RAWBrush* raw_brush = item.raw_brush;
+ if(!raw_brush)
+ continue;
+
+ if(as_lower_str(raw_brush->getName()).find(search_string) == std::string::npos)
+ continue;
+
+ found_search_results = true;
+ items_list->AddBrush(raw_brush);
+ }
+ }
+ }
+ else if(selection == SearchMode::Types) {
+ for(int id = 100; id <= g_items.getMaxID(); ++id) {
+ ItemType& item = g_items.getItemType(id);
+ if (item.id == 0)
+ continue;
+
+ RAWBrush* raw_brush = item.raw_brush;
+ if(!raw_brush)
+ continue;
+
+ SearchItemType selection = (SearchItemType)types_radio_box->GetSelection();
+ if ((selection == SearchItemType::Depot && !item.isDepot()) ||
+ (selection == SearchItemType::Mailbox && !item.isMailbox()) ||
+ (selection == SearchItemType::TrashHolder && !item.isTrashHolder()) ||
+ (selection == SearchItemType::Container && !item.isContainer()) ||
+ (selection == SearchItemType::Door && !item.isDoor()) ||
+ (selection == SearchItemType::MagicField && !item.isMagicField()) ||
+ (selection == SearchItemType::Teleport && !item.isTeleport()) ||
+ (selection == SearchItemType::Bed && !item.isBed()) ||
+ (selection == SearchItemType::Key && !item.isKey())) {
+ continue;
+ }
+
+ found_search_results = true;
+ items_list->AddBrush(raw_brush);
+ }
+ }
+ else if(selection == SearchMode::Properties) {
+ bool has_selected = (unpassable->GetValue() ||
+ unmovable->GetValue() ||
+ block_missiles->GetValue() ||
+ block_pathfinder->GetValue() ||
+ pickupable->GetValue() ||
+ stackable->GetValue() ||
+ rotatable->GetValue() ||
+ hangable->GetValue() ||
+ hook_east->GetValue() ||
+ hook_south->GetValue() ||
+ has_elevation->GetValue() ||
+ ignore_look->GetValue());
+
+ if(has_selected) {
+ for(int id = 100; id <= g_items.getMaxID(); ++id) {
+ ItemType& item = g_items.getItemType(id);
+ if(item.id == 0)
+ continue;
+
+ RAWBrush* raw_brush = item.raw_brush;
+ if(!raw_brush)
+ continue;
+
+ if((unpassable->GetValue() && !item.unpassable) ||
+ (unmovable->GetValue() && item.moveable) ||
+ (block_missiles->GetValue() && !item.blockMissiles) ||
+ (block_pathfinder->GetValue() && !item.blockPathfinder) ||
+ (pickupable->GetValue() && !item.pickupable) ||
+ (stackable->GetValue() && !item.stackable) ||
+ (rotatable->GetValue() && !item.rotable) ||
+ (hangable->GetValue() && !item.isHangable) ||
+ (hook_east->GetValue() && !item.hookEast) ||
+ (hook_south->GetValue() && !item.hookSouth) ||
+ (has_elevation->GetValue() && !item.hasElevation) ||
+ (ignore_look->GetValue() && !item.ignoreLook)) {
+ continue;
+ }
+
+ found_search_results = true;
+ items_list->AddBrush(raw_brush);
+ }
+ }
+ }
+
+ if(found_search_results)
+ items_list->SetSelection(0);
+ else
+ items_list->SetNoMatches();
+
+ items_list->Refresh();
+}
+
+void FindItemDialog::OnOptionChange(wxCommandEvent& event)
+{
+ setSearchMode((SearchMode)options_radio_box->GetSelection());
+}
+
+void FindItemDialog::OnServerIdChange(wxCommandEvent& event)
+{
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::OnClientIdChange(wxCommandEvent& event)
+{
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::OnText(wxCommandEvent& event)
+{
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::OnTypeChange(wxCommandEvent& event)
+{
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::OnPropertyChange(wxCommandEvent& event)
+{
+ RefreshContentsInternal();
+}
+
+void FindItemDialog::OnClickOK(wxCommandEvent& event)
+{
+ if(items_list->GetItemCount() != 0) {
+ Brush* brush = items_list->GetSelectedBrush();
+ if(brush) {
+ result_brush = brush;
+ result_id = brush->asRaw()->getItemID();
+ EndModal(wxID_OK);
+ }
+ }
+}
+
+void FindItemDialog::OnClickCancel(wxCommandEvent& event)
+{
+ EndModal(wxID_CANCEL);
+}
diff --git a/source/find_item_window.h b/source/find_item_window.h
new file mode 100644
index 00000000..c6da2439
--- /dev/null
+++ b/source/find_item_window.h
@@ -0,0 +1,107 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Remere's Map Editor
+//////////////////////////////////////////////////////////////////////
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//////////////////////////////////////////////////////////////////////
+
+#ifndef RME_FIND_ITEM_WINDOW_H_
+#define RME_FIND_ITEM_WINDOW_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class FindDialogListBox;
+
+class FindItemDialog : public wxDialog
+{
+public:
+ enum SearchMode {
+ ServerIDs = 0,
+ ClientIDs,
+ Names,
+ Types,
+ Properties,
+ };
+
+ enum SearchItemType {
+ Depot,
+ Mailbox,
+ TrashHolder,
+ Container,
+ Door,
+ MagicField,
+ Teleport,
+ Bed,
+ Key
+ };
+
+ FindItemDialog(wxWindow* parent, const wxString& title, bool onlyPickupables = false);
+ ~FindItemDialog();
+
+ Brush* getResult() const { return result_brush; }
+ uint16_t getResultID() const { return result_id; }
+
+ SearchMode getSearchMode() const;
+ void setSearchMode(SearchMode mode);
+
+private:
+ void EnableProperties(bool enable);
+ void RefreshContentsInternal();
+
+ void OnOptionChange(wxCommandEvent& event);
+ void OnServerIdChange(wxCommandEvent& event);
+ void OnClientIdChange(wxCommandEvent& event);
+ void OnText(wxCommandEvent& event);
+ void OnTypeChange(wxCommandEvent& event);
+ void OnPropertyChange(wxCommandEvent& event);
+ void OnClickOK(wxCommandEvent& event);
+ void OnClickCancel(wxCommandEvent& event);
+
+ wxRadioBox* options_radio_box;
+
+ wxRadioBox* types_radio_box;
+
+ wxSpinCtrl* server_id_spin;
+ wxSpinCtrl* client_id_spin;
+ wxTextCtrl* name_text_input;
+ wxCheckBox* unpassable;
+ wxCheckBox* unmovable;
+ wxCheckBox* block_missiles;
+ wxCheckBox* block_pathfinder;
+ wxCheckBox* pickupable;
+ wxCheckBox* stackable;
+ wxCheckBox* rotatable;
+ wxCheckBox* hangable;
+ wxCheckBox* hook_east;
+ wxCheckBox* hook_south;
+ wxCheckBox* has_elevation;
+ wxCheckBox* ignore_look;
+
+ FindDialogListBox* items_list;
+ wxStdDialogButtonSizer* buttons_box_sizer;
+ wxButton* ok_button;
+ wxButton* cancel_button;
+ Brush* result_brush;
+ uint16_t result_id;
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // RME_FIND_ITEM_WINDOW_H_
diff --git a/source/graphics.cpp b/source/graphics.cpp
index 38c4423c..7e837104 100644
--- a/source/graphics.cpp
+++ b/source/graphics.cpp
@@ -383,9 +383,9 @@ bool GraphicManager::loadSpriteMetadata(const FileName& datafile, wxString& erro
file.getU16(effect_count);
file.getU16(distance_count);
- uint32_t minclientID = 100; // tibia.dat start with id 100
+ uint32_t minID = 100; // tibia.dat start with id 100
// We don't load distance/effects, if we would, just add effect_count & distance_count here
- uint32_t maxclientID = item_count + creature_count;
+ uint32_t maxID = item_count + creature_count;
dat_format = client_version->getDatFormatForSignature(datSignature);
@@ -395,9 +395,9 @@ bool GraphicManager::loadSpriteMetadata(const FileName& datafile, wxString& erro
has_frame_groups = dat_format >= DAT_FORMAT_1057;
}
- uint16_t id = minclientID;
+ uint16_t id = minID;
// loop through all ItemDatabase until we reach the end of file
- while(id <= maxclientID) {
+ while(id <= maxID) {
GameSprite* sType = newd GameSprite();
sprite_space[id] = sType;
diff --git a/source/item.cpp b/source/item.cpp
index 3bcf0a82..ca8d5d1d 100644
--- a/source/item.cpp
+++ b/source/item.cpp
@@ -185,7 +185,7 @@ bool Item::hasProperty(enum ITEMPROPERTY prop) const
const ItemType& it = g_items[id];
switch(prop){
case BLOCKSOLID:
- if(it.blockSolid)
+ if(it.unpassable)
return true;
break;
@@ -200,27 +200,27 @@ bool Item::hasProperty(enum ITEMPROPERTY prop) const
break;
*/
case BLOCKPROJECTILE:
- if(it.blockProjectile)
+ if(it.blockMissiles)
return true;
break;
case BLOCKPATHFIND:
- if(it.blockPathFind)
+ if(it.blockPathfinder)
return true;
break;
- case ISVERTICAL:
- if(it.isVertical)
+ case HOOK_SOUTH:
+ if(it.hookSouth)
return true;
break;
- case ISHORIZONTAL:
- if(it.isHorizontal)
+ case HOOK_EAST:
+ if(it.hookEast)
return true;
break;
case BLOCKINGANDNOTMOVEABLE:
- if(it.blockSolid && (!it.moveable || getUniqueID() != 0))
+ if(it.unpassable && (!it.moveable || getUniqueID() != 0))
return true;
break;
diff --git a/source/item.h b/source/item.h
index 120e8cab..e087ffa2 100644
--- a/source/item.h
+++ b/source/item.h
@@ -35,8 +35,8 @@ enum ITEMPROPERTY {
BLOCKPROJECTILE,
BLOCKPATHFIND,
PROTECTIONZONE,
- ISVERTICAL,
- ISHORIZONTAL,
+ HOOK_SOUTH,
+ HOOK_EAST,
MOVEABLE,
BLOCKINGANDNOTMOVEABLE
};
@@ -178,7 +178,7 @@ class Item : public ItemAttributes
// Item types
bool hasProperty(enum ITEMPROPERTY prop) const;
- bool isBlocking() const {return g_items[id].blockSolid;}
+ bool isBlocking() const {return g_items[id].unpassable;}
bool isStackable() const {return g_items[id].stackable;}
bool isClientCharged() const {return g_items[id].isClientCharged();}
bool isExtraCharged() const {return g_items[id].isExtraCharged();}
diff --git a/source/items.cpp b/source/items.cpp
index def1b25e..fe341ca3 100644
--- a/source/items.cpp
+++ b/source/items.cpp
@@ -57,10 +57,11 @@ ItemType::ItemType() :
charges(0),
client_chargeable(false),
extra_chargeable(false),
+ ignoreLook(false),
- isVertical(false),
- isHorizontal(false),
isHangable(false),
+ hookSouth(false),
+ hookEast(false),
canReadText(false),
canWriteText(false),
replaceable(true),
@@ -84,10 +85,11 @@ ItemType::ItemType() :
floorChangeEast(false),
floorChangeWest(false),
- blockSolid(false),
+ unpassable(false),
blockPickupable(false),
- blockProjectile(false),
- blockPathFind(false),
+ blockMissiles(false),
+ blockPathfinder(false),
+ hasElevation(false),
alwaysOnTopOrder(0),
rotateTo(0),
@@ -152,7 +154,7 @@ bool ItemDatabase::loadFromOtbVer1(BinaryNode* itemNode, wxString& error, wxArra
t->group = ItemGroup_t(u8);
switch(t->group) {
- case ITEM_GROUP_NONE:
+ case ITEM_GROUP_NONE:
case ITEM_GROUP_GROUND:
case ITEM_GROUP_SPLASH:
case ITEM_GROUP_FLUID:
@@ -173,11 +175,10 @@ bool ItemDatabase::loadFromOtbVer1(BinaryNode* itemNode, wxString& error, wxArra
uint32_t flags;
if(itemNode->getU32(flags)) {
- t->blockSolid = ((flags & FLAG_BLOCK_SOLID) == FLAG_BLOCK_SOLID);
- t->blockProjectile = ((flags & FLAG_BLOCK_PROJECTILE) == FLAG_BLOCK_PROJECTILE);
- t->blockPathFind = ((flags & FLAG_BLOCK_PATHFIND) == FLAG_BLOCK_PATHFIND);
- // These are irrelevant
- //t->hasHeight = ((flags & FLAG_HAS_HEIGHT) == FLAG_HAS_HEIGHT);
+ t->unpassable = ((flags & FLAG_UNPASSABLE) == FLAG_UNPASSABLE);
+ t->blockMissiles = ((flags & FLAG_BLOCK_MISSILES) == FLAG_BLOCK_MISSILES);
+ t->blockPathfinder = ((flags & FLAG_BLOCK_PATHFINDER) == FLAG_BLOCK_PATHFINDER);
+ t->hasElevation = ((flags & FLAG_HAS_ELEVATION) == FLAG_HAS_ELEVATION);
//t->useable = ((flags & FLAG_USEABLE) == FLAG_USEABLE);
t->pickupable = ((flags & FLAG_PICKUPABLE) == FLAG_PICKUPABLE);
t->moveable = ((flags & FLAG_MOVEABLE) == FLAG_MOVEABLE);
@@ -189,9 +190,9 @@ bool ItemDatabase::loadFromOtbVer1(BinaryNode* itemNode, wxString& error, wxArra
t->floorChangeWest = ((flags & FLAG_FLOORCHANGEWEST) == FLAG_FLOORCHANGEWEST);
// Now this is confusing, just accept that the ALWAYSONTOP flag means it's always on bottom, got it?!
t->alwaysOnBottom = ((flags & FLAG_ALWAYSONTOP) == FLAG_ALWAYSONTOP);
- t->isVertical = ((flags & FLAG_VERTICAL) == FLAG_VERTICAL);
- t->isHorizontal = ((flags & FLAG_HORIZONTAL) == FLAG_HORIZONTAL);
t->isHangable = ((flags & FLAG_HANGABLE) == FLAG_HANGABLE);
+ t->hookSouth = ((flags & FLAG_HOOK_EAST) == FLAG_HOOK_EAST);
+ t->hookEast = ((flags & FLAG_HOOK_SOUTH) == FLAG_HOOK_SOUTH);
t->allowDistRead = ((flags & FLAG_ALLOWDISTREAD) == FLAG_ALLOWDISTREAD);
t->rotable = ((flags & FLAG_ROTABLE) == FLAG_ROTABLE);
t->canReadText = ((flags & FLAG_READABLE) == FLAG_READABLE);
@@ -411,25 +412,26 @@ bool ItemDatabase::loadFromOtbVer2(BinaryNode* itemNode, wxString& error, wxArra
t->group = ItemGroup_t(u8);
switch(t->group) {
- case ITEM_GROUP_NONE:
+ case ITEM_GROUP_NONE:
case ITEM_GROUP_GROUND:
case ITEM_GROUP_SPLASH:
case ITEM_GROUP_FLUID:
break;
- case ITEM_GROUP_DOOR: t->type = ITEM_TYPE_DOOR; break;
- case ITEM_GROUP_CONTAINER: t->type = ITEM_TYPE_CONTAINER; break;
- case ITEM_GROUP_RUNE: t->client_chargeable = true; break;
- case ITEM_GROUP_TELEPORT: t->type = ITEM_TYPE_TELEPORT; break;
- case ITEM_GROUP_MAGICFIELD: t->type = ITEM_TYPE_MAGICFIELD; break;
+ case ITEM_GROUP_DOOR: t->type = ITEM_TYPE_DOOR; break;
+ case ITEM_GROUP_CONTAINER: t->type = ITEM_TYPE_CONTAINER; break;
+ case ITEM_GROUP_RUNE: t->client_chargeable = true; break;
+ case ITEM_GROUP_TELEPORT: t->type = ITEM_TYPE_TELEPORT; break;
+ case ITEM_GROUP_MAGICFIELD: t->type = ITEM_TYPE_MAGICFIELD; break;
default:
warnings.push_back("Unknown item group declaration");
}
uint32_t flags;
if(itemNode->getU32(flags)) {
- t->blockSolid = ((flags & FLAG_BLOCK_SOLID) == FLAG_BLOCK_SOLID);
- t->blockProjectile = ((flags & FLAG_BLOCK_PROJECTILE) == FLAG_BLOCK_PROJECTILE);
- t->blockPathFind = ((flags & FLAG_BLOCK_PATHFIND) == FLAG_BLOCK_PATHFIND);
+ t->unpassable = ((flags & FLAG_UNPASSABLE) == FLAG_UNPASSABLE);
+ t->blockMissiles = ((flags & FLAG_BLOCK_MISSILES) == FLAG_BLOCK_MISSILES);
+ t->blockPathfinder = ((flags & FLAG_BLOCK_PATHFINDER) == FLAG_BLOCK_PATHFINDER);
+ t->hasElevation = ((flags & FLAG_HAS_ELEVATION) == FLAG_HAS_ELEVATION);
t->pickupable = ((flags & FLAG_PICKUPABLE) == FLAG_PICKUPABLE);
t->moveable = ((flags & FLAG_MOVEABLE) == FLAG_MOVEABLE);
t->stackable = ((flags & FLAG_STACKABLE) == FLAG_STACKABLE);
@@ -440,9 +442,9 @@ bool ItemDatabase::loadFromOtbVer2(BinaryNode* itemNode, wxString& error, wxArra
t->floorChangeWest = ((flags & FLAG_FLOORCHANGEWEST) == FLAG_FLOORCHANGEWEST);
// Now this is confusing, just accept that the ALWAYSONTOP flag means it's always on bottom, got it?!
t->alwaysOnBottom = ((flags & FLAG_ALWAYSONTOP) == FLAG_ALWAYSONTOP);
- t->isVertical = ((flags & FLAG_VERTICAL) == FLAG_VERTICAL);
- t->isHorizontal = ((flags & FLAG_HORIZONTAL) == FLAG_HORIZONTAL);
t->isHangable = ((flags & FLAG_HANGABLE) == FLAG_HANGABLE);
+ t->hookSouth = ((flags & FLAG_HOOK_EAST) == FLAG_HOOK_EAST);
+ t->hookEast = ((flags & FLAG_HOOK_SOUTH) == FLAG_HOOK_SOUTH);
t->allowDistRead = ((flags & FLAG_ALLOWDISTREAD) == FLAG_ALLOWDISTREAD);
t->rotable = ((flags & FLAG_ROTABLE) == FLAG_ROTABLE);
t->canReadText = ((flags & FLAG_READABLE) == FLAG_READABLE);
@@ -573,9 +575,10 @@ bool ItemDatabase::loadFromOtbVer3(BinaryNode* itemNode, wxString& error, wxArra
uint32_t flags;
if(itemNode->getU32(flags)) {
- t->blockSolid = ((flags & FLAG_BLOCK_SOLID) == FLAG_BLOCK_SOLID);
- t->blockProjectile = ((flags & FLAG_BLOCK_PROJECTILE) == FLAG_BLOCK_PROJECTILE);
- t->blockPathFind = ((flags & FLAG_BLOCK_PATHFIND) == FLAG_BLOCK_PATHFIND);
+ t->unpassable = ((flags & FLAG_UNPASSABLE) == FLAG_UNPASSABLE);
+ t->blockMissiles = ((flags & FLAG_BLOCK_MISSILES) == FLAG_BLOCK_MISSILES);
+ t->blockPathfinder = ((flags & FLAG_BLOCK_PATHFINDER) == FLAG_BLOCK_PATHFINDER);
+ t->hasElevation = ((flags & FLAG_HAS_ELEVATION) == FLAG_HAS_ELEVATION);
t->pickupable = ((flags & FLAG_PICKUPABLE) == FLAG_PICKUPABLE);
t->moveable = ((flags & FLAG_MOVEABLE) == FLAG_MOVEABLE);
t->stackable = ((flags & FLAG_STACKABLE) == FLAG_STACKABLE);
@@ -586,9 +589,9 @@ bool ItemDatabase::loadFromOtbVer3(BinaryNode* itemNode, wxString& error, wxArra
t->floorChangeWest = ((flags & FLAG_FLOORCHANGEWEST) == FLAG_FLOORCHANGEWEST);
// Now this is confusing, just accept that the ALWAYSONTOP flag means it's always on bottom, got it?!
t->alwaysOnBottom = ((flags & FLAG_ALWAYSONTOP) == FLAG_ALWAYSONTOP);
- t->isVertical = ((flags & FLAG_VERTICAL) == FLAG_VERTICAL);
- t->isHorizontal = ((flags & FLAG_HORIZONTAL) == FLAG_HORIZONTAL);
t->isHangable = ((flags & FLAG_HANGABLE) == FLAG_HANGABLE);
+ t->hookSouth = ((flags & FLAG_HOOK_EAST) == FLAG_HOOK_EAST);
+ t->hookEast = ((flags & FLAG_HOOK_SOUTH) == FLAG_HOOK_SOUTH);
t->allowDistRead = ((flags & FLAG_ALLOWDISTREAD) == FLAG_ALLOWDISTREAD);
t->rotable = ((flags & FLAG_ROTABLE) == FLAG_ROTABLE);
t->canReadText = ((flags & FLAG_READABLE) == FLAG_READABLE);
@@ -784,22 +787,25 @@ bool ItemDatabase::loadItemFromGameXml(pugi::xml_node itemNode, int id)
std::string typeValue = attribute.as_string();
to_lower_str(key);
- if(typeValue == "magicfield") {
+ if(typeValue == "depot") {
+ it.type = ITEM_TYPE_DEPOT;
+ } else if(typeValue == "mailbox") {
+ it.type = ITEM_TYPE_MAILBOX;
+ } else if(typeValue == "trashholder") {
+ it.type = ITEM_TYPE_TRASHHOLDER;
+ } else if (typeValue == "container") {
+ it.type = ITEM_TYPE_CONTAINER;
+ } else if (typeValue == "door") {
+ it.type = ITEM_TYPE_DOOR;
+ } else if (typeValue == "magicfield") {
it.group = ITEM_GROUP_MAGICFIELD;
it.type = ITEM_TYPE_MAGICFIELD;
- } else if(typeValue == "key") {
- it.type = ITEM_TYPE_KEY;
- } else if(typeValue == "depot") {
- it.type = ITEM_TYPE_DEPOT;
- } else if(typeValue == "teleport") {
+ } else if (typeValue == "teleport") {
it.type = ITEM_TYPE_TELEPORT;
- } else if(typeValue == "bed") {
+ } else if (typeValue == "bed") {
it.type = ITEM_TYPE_BED;
- } else if(typeValue == "door") {
- it.type = ITEM_TYPE_DOOR;
- } else {
- // We ignore many types, no need to complain
- //warnings.push_back("items.xml: Unknown type " + typeValue);
+ } else if (typeValue == "key") {
+ it.type = ITEM_TYPE_KEY;
}
} else if(key == "name") {
if((attribute = itemAttributesNode.attribute("value"))) {
diff --git a/source/items.h b/source/items.h
index 28dd03b2..f7dd7035 100644
--- a/source/items.h
+++ b/source/items.h
@@ -127,29 +127,30 @@ enum itemattrib_t {
};
enum itemflags_t {
- FLAG_BLOCK_SOLID = 1,
- FLAG_BLOCK_PROJECTILE = 2,
- FLAG_BLOCK_PATHFIND = 4,
- FLAG_HAS_HEIGHT = 8,
- FLAG_USEABLE = 16,
- FLAG_PICKUPABLE = 32,
- FLAG_MOVEABLE = 64,
- FLAG_STACKABLE = 128,
- FLAG_FLOORCHANGEDOWN = 256,
- FLAG_FLOORCHANGENORTH = 512,
- FLAG_FLOORCHANGEEAST = 1024,
- FLAG_FLOORCHANGESOUTH = 2048,
- FLAG_FLOORCHANGEWEST = 4096,
- FLAG_ALWAYSONTOP = 8192,
- FLAG_READABLE = 16384,
- FLAG_ROTABLE = 32768,
- FLAG_HANGABLE = 65536,
- FLAG_VERTICAL = 131072,
- FLAG_HORIZONTAL = 262144,
- FLAG_CANNOTDECAY = 524288,
- FLAG_ALLOWDISTREAD = 1048576,
- FLAG_UNUSED = 2097152,
- FLAG_CLIENTCHARGES = 4194304,
+ FLAG_UNPASSABLE = 1 << 0,
+ FLAG_BLOCK_MISSILES = 1 << 1,
+ FLAG_BLOCK_PATHFINDER = 1 << 2,
+ FLAG_HAS_ELEVATION = 1 << 3,
+ FLAG_USEABLE = 1 << 4,
+ FLAG_PICKUPABLE = 1 << 5,
+ FLAG_MOVEABLE = 1 << 6,
+ FLAG_STACKABLE = 1 << 7,
+ FLAG_FLOORCHANGEDOWN = 1 << 8,
+ FLAG_FLOORCHANGENORTH = 1 << 9,
+ FLAG_FLOORCHANGEEAST = 1 << 10,
+ FLAG_FLOORCHANGESOUTH = 1 << 11,
+ FLAG_FLOORCHANGEWEST = 1 << 12,
+ FLAG_ALWAYSONTOP = 1 << 13,
+ FLAG_READABLE = 1 << 14,
+ FLAG_ROTABLE = 1 << 15,
+ FLAG_HANGABLE = 1 << 16,
+ FLAG_HOOK_SOUTH = 1 << 17,
+ FLAG_HOOK_EAST = 1 << 18,
+ FLAG_CANNOTDECAY = 1 << 19,
+ FLAG_ALLOWDISTREAD = 1 << 20,
+ FLAG_UNUSED = 1 << 21,
+ FLAG_CLIENTCHARGES = 1 << 22,
+ FLAG_IGNORE_LOOK = 1 << 23
};
enum slotsOTB_t{
@@ -245,18 +246,25 @@ class ItemType {
ItemType();
~ItemType();
- bool isGroundTile() const {return (group == ITEM_GROUP_GROUND);}
- bool isSplash() const {return (group == ITEM_GROUP_SPLASH);}
- bool isFluidContainer() const {return (group == ITEM_GROUP_FLUID);}
- bool isContainer() const {return (type == ITEM_TYPE_CONTAINER);}
- bool isDoor() const {return (type == ITEM_TYPE_DOOR);}
- bool isClientCharged() const {return client_chargeable;}
- bool isExtraCharged() const {return !client_chargeable && extra_chargeable;}
- bool isTeleport() const {return (type == ITEM_TYPE_TELEPORT);}
- bool isMagicField() const {return (type == ITEM_TYPE_MAGICFIELD);}
- bool isStackable() const {return stackable;}
- bool isDepot() const {return (type == ITEM_TYPE_DEPOT);}
- bool isMetaItem() const {return is_metaitem;}
+ bool isGroundTile() const { return (group == ITEM_GROUP_GROUND); }
+ bool isSplash() const { return (group == ITEM_GROUP_SPLASH); }
+ bool isFluidContainer() const { return (group == ITEM_GROUP_FLUID); }
+
+ bool isClientCharged() const { return client_chargeable; }
+ bool isExtraCharged() const { return !client_chargeable && extra_chargeable; }
+
+ bool isDepot() const { return (type == ITEM_TYPE_DEPOT); }
+ bool isMailbox() const { return (type == ITEM_TYPE_MAILBOX); }
+ bool isTrashHolder() const { return (type == ITEM_TYPE_TRASHHOLDER); }
+ bool isContainer() const { return (type == ITEM_TYPE_CONTAINER); }
+ bool isDoor() const { return (type == ITEM_TYPE_DOOR); }
+ bool isMagicField() const { return (type == ITEM_TYPE_MAGICFIELD); }
+ bool isTeleport() const { return (type == ITEM_TYPE_TELEPORT); }
+ bool isBed() const { return (type == ITEM_TYPE_BED); }
+ bool isKey() const { return (type == ITEM_TYPE_KEY); }
+
+ bool isStackable() const { return stackable; }
+ bool isMetaItem() const { return is_metaitem; }
GameSprite* sprite;
uint16_t id;
@@ -274,66 +282,69 @@ class ItemType {
ItemGroup_t group;
ItemTypes_t type;
- uint16_t volume;
- uint16_t maxTextLen;
- //uint16_t writeOnceItemId;
- uint16_t ground_equivalent;
- uint32_t border_group;
- bool has_equivalent; // True if any item has this as ground_equivalent
- bool wall_hate_me; // (For wallbrushes, regard this as not part of the wall)
+ uint16_t volume;
+ uint16_t maxTextLen;
+ //uint16_t writeOnceItemId;
+ uint16_t ground_equivalent;
+ uint32_t border_group;
+ bool has_equivalent; // True if any item has this as ground_equivalent
+ bool wall_hate_me; // (For wallbrushes, regard this as not part of the wall)
- std::string name;
- std::string editorsuffix;
- std::string description;
+ std::string name;
+ std::string editorsuffix;
+ std::string description;
- float weight;
+ float weight;
// It might be useful to be able to extrapolate this information in the future
- int attack;
- int defense;
- int armor;
- uint32_t charges;
- bool client_chargeable;
- bool extra_chargeable;
-
- bool isVertical;
- bool isHorizontal;
- bool isHangable;
- bool canReadText;
- bool canWriteText;
- bool allowDistRead;
- bool replaceable;
- bool decays;
-
- bool stackable;
- bool moveable;
- bool alwaysOnBottom;
- bool pickupable;
- bool rotable;
- bool isBorder;
- bool isOptionalBorder;
- bool isWall;
- bool isBrushDoor;
- bool isOpen;
- bool isTable;
- bool isCarpet;
-
- bool floorChangeDown;
- bool floorChangeNorth;
- bool floorChangeSouth;
- bool floorChangeEast;
- bool floorChangeWest;
-
- bool blockSolid;
- bool blockPickupable;
- bool blockProjectile;
- bool blockPathFind;
-
- int alwaysOnTopOrder;
- int rotateTo;
- BorderType border_alignment;
+ int attack;
+ int defense;
+ int armor;
+ uint32_t charges;
+ bool client_chargeable;
+ bool extra_chargeable;
+ bool ignoreLook;
+
+ bool isHangable;
+ bool hookEast;
+ bool hookSouth;
+ bool canReadText;
+ bool canWriteText;
+ bool allowDistRead;
+ bool replaceable;
+ bool decays;
+
+ bool stackable;
+ bool moveable;
+ bool alwaysOnBottom;
+ bool pickupable;
+ bool rotable;
+ bool isBorder;
+ bool isOptionalBorder;
+ bool isWall;
+ bool isBrushDoor;
+ bool isOpen;
+ bool isTable;
+ bool isCarpet;
+
+ bool floorChangeDown;
+ bool floorChangeNorth;
+ bool floorChangeSouth;
+ bool floorChangeEast;
+ bool floorChangeWest;
+
+ bool unpassable;
+ bool blockPickupable;
+ bool blockMissiles;
+ bool blockPathfinder;
+ bool hasElevation;
+
+ int alwaysOnTopOrder;
+ int rotateTo;
+ BorderType border_alignment;
};
-class ItemDatabase {
+class ItemDatabase
+{
public:
ItemDatabase();
~ItemDatabase();
@@ -369,13 +380,13 @@ class ItemDatabase {
protected:
// Count of GameSprite types
- int32_t item_count;
- int32_t effect_count;
- int32_t monster_count;
- int32_t distance_count;
+ uint16_t item_count;
+ uint16_t effect_count;
+ uint16_t monster_count;
+ uint16_t distance_count;
- int32_t minclientID;
- int32_t maxclientID;
+ uint16_t minclientID;
+ uint16_t maxclientID;
uint16_t max_item_id;
friend class GameSprite;
diff --git a/source/main_menubar.cpp b/source/main_menubar.cpp
index f70c043a..a20c3a8a 100644
--- a/source/main_menubar.cpp
+++ b/source/main_menubar.cpp
@@ -27,6 +27,8 @@
#include "dat_debug_view.h"
#include "result_window.h"
#include "extension_window.h"
+#include "find_item_window.h"
+#include "settings.h"
#include "gui.h"
@@ -836,17 +838,18 @@ void MainMenuBar::OnSearchForItem(wxCommandEvent& WXUNUSED(event))
if(!g_gui.IsEditorOpen())
return;
- FindItemDialog finder(frame, "Search for Item");
- if(finder.ShowModal() != 0) {
- OnSearchForItem::Finder func(finder.getResultID());
+ FindItemDialog dialog(frame, "Search for Item");
+ dialog.setSearchMode((FindItemDialog::SearchMode)g_settings.getInteger(Config::FIND_ITEM_MODE));
+ if(dialog.ShowModal() == wxID_OK) {
+ OnSearchForItem::Finder finder(dialog.getResultID());
g_gui.CreateLoadBar("Searching map...");
- foreach_ItemOnMap(g_gui.GetCurrentMap(), func, false);
- std::vector >& found = func.found;
+ foreach_ItemOnMap(g_gui.GetCurrentMap(), finder, false);
+ std::vector >& found = finder.found;
g_gui.DestroyLoadBar();
- if(func.more_than_value) {
+ if(finder.more_than_value) {
wxString msg;
msg << "Only the first " << size_t(g_settings.getInteger(Config::REPLACE_SIZE)) << " results will be displayed.";
g_gui.PopupDialog("Notice", msg, wxOK);
@@ -859,7 +862,10 @@ void MainMenuBar::OnSearchForItem(wxCommandEvent& WXUNUSED(event))
Item* item = iter->second;
result->AddPosition(wxstr(item->getName()), tile->getPosition());
}
+
+ g_settings.setInteger(Config::FIND_ITEM_MODE, (int)dialog.getSearchMode());
}
+ dialog.Destroy();
}
void MainMenuBar::OnReplaceItem(wxCommandEvent& WXUNUSED(event))
{
@@ -868,7 +874,7 @@ void MainMenuBar::OnReplaceItem(wxCommandEvent& WXUNUSED(event))
ReplaceItemDialog dlg(frame, "Replace Item");
- if(dlg.ShowModal() != 0) {
+ if(dlg.ShowModal() == wxID_OK) {
uint16_t find_id = dlg.GetResultFindID();
uint16_t with_id = dlg.GetResultWithID();
@@ -1144,17 +1150,16 @@ void MainMenuBar::OnJumpToItemBrush(wxCommandEvent& WXUNUSED(event))
return;
// Create the jump to dialog
- FindDialog* dlg = newd FindItemDialog(frame);
-
- // Display dialog to user
- dlg->ShowModal();
-
- // Retrieve result, if null user canceled
- const Brush* brush = dlg->getResult();
- if(brush) {
- g_gui.SelectBrush(brush, TILESET_RAW);
+ FindItemDialog dialog(frame, "Jump to Item");
+ dialog.setSearchMode((FindItemDialog::SearchMode)g_settings.getInteger(Config::JUMP_TO_ITEM_MODE));
+ if(dialog.ShowModal() == wxID_OK) {
+ // Retrieve result, if null user canceled
+ const Brush* brush = dialog.getResult();
+ if(brush)
+ g_gui.SelectBrush(brush, TILESET_RAW);
+ g_settings.setInteger(Config::JUMP_TO_ITEM_MODE, (int)dialog.getSearchMode());
}
- delete dlg;
+ dialog.Destroy();
}
void MainMenuBar::OnGotoPreviousPosition(wxCommandEvent& WXUNUSED(event))
@@ -1195,18 +1200,17 @@ void MainMenuBar::OnMapRemoveItems(wxCommandEvent& WXUNUSED(event))
if(!g_gui.IsEditorOpen())
return;
- FindItemDialog finder(frame, "Item Type to Remove");
- finder.ShowModal();
- uint16_t itemid = finder.getResultID();
+ FindItemDialog dialog(frame, "Item Type to Remove");
+ if(dialog.ShowModal() == wxID_OK) {
+ uint16_t itemid = dialog.getResultID();
- if(itemid != 0) {
g_gui.GetCurrentEditor()->selection.clear();
g_gui.GetCurrentEditor()->actionQueue->clear();
- OnMapRemoveItems::condition func(itemid);
+ OnMapRemoveItems::condition finder(itemid);
g_gui.CreateLoadBar("Searching map for items to remove...");
- long long removed = remove_if_ItemOnMap(g_gui.GetCurrentMap(), func);
+ long long removed = remove_if_ItemOnMap(g_gui.GetCurrentMap(), finder);
g_gui.DestroyLoadBar();
@@ -1217,6 +1221,7 @@ void MainMenuBar::OnMapRemoveItems(wxCommandEvent& WXUNUSED(event))
g_gui.GetCurrentMap().doChange();
}
+ dialog.Destroy();
}
namespace OnMapRemoveCorpses
diff --git a/source/map_drawer.cpp b/source/map_drawer.cpp
index 665cca8e..d21391e9 100644
--- a/source/map_drawer.cpp
+++ b/source/map_drawer.cpp
@@ -1063,9 +1063,9 @@ void MapDrawer::BlitItem(int& draw_x, int& draw_y, const Tile* tile, const Item*
if(it.isSplash() || it.isFluidContainer()) {
subtype = item->getSubtype();
} else if(it.isHangable) {
- if(tile->hasProperty(ISVERTICAL)) {
+ if(tile->hasProperty(HOOK_SOUTH)) {
pattern_x = 2;
- } else if(tile->hasProperty(ISHORIZONTAL)) {
+ } else if(tile->hasProperty(HOOK_EAST)) {
pattern_x = 1;
} else {
pattern_x = -0;
@@ -1163,9 +1163,9 @@ void MapDrawer::BlitItem(int& draw_x, int& draw_y, const Position& pos, const It
} else if(it.isHangable) {
pattern_x = 0;
/*
- if(tile->hasProperty(ISVERTICAL)) {
+ if(tile->hasProperty(HOOK_SOUTH)) {
pattern_x = 2;
- } else if(tile->hasProperty(ISHORIZONTAL)) {
+ } else if(tile->hasProperty(HOOK_EAST)) {
pattern_x = 1;
} else {
pattern_x = -0;
diff --git a/source/settings.cpp b/source/settings.cpp
index e369d80c..91992907 100644
--- a/source/settings.cpp
+++ b/source/settings.cpp
@@ -318,6 +318,9 @@ void Settings::IO(IOMode mode)
String(RECENT_EDITED_MAP_PATH, "");
String(RECENT_EDITED_MAP_POSITION, "");
+ Int(FIND_ITEM_MODE, 0);
+ Int(JUMP_TO_ITEM_MODE, 0);
+
#undef section
#undef Int
#undef IntToSave
diff --git a/source/settings.h b/source/settings.h
index 7f17db74..b4a353b2 100644
--- a/source/settings.h
+++ b/source/settings.h
@@ -135,6 +135,9 @@ namespace Config {
RECENT_EDITED_MAP_PATH,
RECENT_EDITED_MAP_POSITION,
+ FIND_ITEM_MODE,
+ JUMP_TO_ITEM_MODE,
+
LAST,
};
}
diff --git a/source/tile.cpp b/source/tile.cpp
index c6254f8f..4b8214e8 100644
--- a/source/tile.cpp
+++ b/source/tile.cpp
@@ -407,7 +407,7 @@ void Tile::update()
}
ItemType& it = g_items[i->getID()];
- if(it.blockSolid) {
+ if(it.unpassable) {
statflags |= TILESTATE_BLOCKING;
}
if(it.isOptionalBorder) {
diff --git a/vcproj/Project/RME.vcxproj b/vcproj/Project/RME.vcxproj
index 259e1b7d..f96a0ab5 100644
--- a/vcproj/Project/RME.vcxproj
+++ b/vcproj/Project/RME.vcxproj
@@ -293,6 +293,7 @@
+
@@ -481,6 +482,7 @@
+
diff --git a/vcproj/Project/RME.vcxproj.filters b/vcproj/Project/RME.vcxproj.filters
index af3c04b8..756cb64b 100644
--- a/vcproj/Project/RME.vcxproj.filters
+++ b/vcproj/Project/RME.vcxproj.filters
@@ -76,7 +76,7 @@
common
-
+
common
@@ -356,9 +356,12 @@
gui\dialogs
-
+
gui\controls
+
+ gui\dialogs
+
@@ -624,9 +627,12 @@
gui\dialogs
-
+
gui\controls
+
+ gui\dialogs
+