From d74c3773372ff0dc2d79d16ec77877ec8267a5a7 Mon Sep 17 00:00:00 2001
From: Kahrl <kahrl@gmx.net>
Date: Tue, 18 Jun 2013 01:32:11 +0200
Subject: [PATCH] Formspec: Don't perform black magic if selected item fits the
 guess

---
 src/guiFormSpecMenu.cpp | 96 ++++++++++++++++++++---------------------
 src/guiFormSpecMenu.h   |  1 +
 2 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index 0cc631332..c1b256f08 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -912,11 +912,20 @@ void GUIFormSpecMenu::drawMenu()
 
 void GUIFormSpecMenu::updateSelectedItem()
 {
+	// If the selected stack has become empty for some reason, deselect it.
+	// If the selected stack has become inaccessible, deselect it.
+	// If the selected stack has become smaller, adjust m_selected_amount.
+	ItemStack selected = verifySelectedItem();
+
 	// WARNING: BLACK MAGIC
 	// See if there is a stack suited for our current guess.
 	// If such stack does not exist, clear the guess.
-	if(m_selected_content_guess.name != "")
-	{
+	if(m_selected_content_guess.name != "" &&
+			selected.name == m_selected_content_guess.name &&
+			selected.count == m_selected_content_guess.count){
+		// Selected item fits the guess. Skip the black magic.
+	}
+	else if(m_selected_content_guess.name != ""){
 		bool found = false;
 		for(u32 i=0; i<m_inventorylists.size() && !found; i++){
 			const ListDrawSpec &s = m_inventorylists[i];
@@ -934,23 +943,12 @@ void GUIFormSpecMenu::updateSelectedItem()
 				if(stack.name == m_selected_content_guess.name &&
 						stack.count == m_selected_content_guess.count){
 					found = true;
-					if(m_selected_item){
-						// If guessed stack is already selected, all is fine
-						if(m_selected_item->inventoryloc == s.inventoryloc &&
-								m_selected_item->listname == s.listname &&
-								m_selected_item->i == (s32)item_i &&
-								m_selected_amount == stack.count){
-							break;
-						}
-						delete m_selected_item;
-						m_selected_item = NULL;
-					}
 					infostream<<"Client: Changing selected content guess to "
 							<<s.inventoryloc.dump()<<" "<<s.listname
 							<<" "<<item_i<<std::endl;
+					delete m_selected_item;
 					m_selected_item = new ItemSpec(s.inventoryloc, s.listname, item_i);
 					m_selected_amount = stack.count;
-					break;
 				}
 			}
 		}
@@ -960,35 +958,6 @@ void GUIFormSpecMenu::updateSelectedItem()
 			m_selected_content_guess.name = "";
 		}
 	}
-	// If the selected stack has become empty for some reason, deselect it.
-	// If the selected stack has become smaller, adjust m_selected_amount.
-	if(m_selected_item)
-	{
-		bool selection_valid = false;
-		if(m_selected_item->isValid())
-		{
-			Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
-			if(inv)
-			{
-				InventoryList *list = inv->getList(m_selected_item->listname);
-				if(list && (u32) m_selected_item->i < list->getSize())
-				{
-					ItemStack stack = list->getItem(m_selected_item->i);
-					if(m_selected_amount > stack.count)
-						m_selected_amount = stack.count;
-					if(!stack.empty())
-						selection_valid = true;
-				}
-			}
-		}
-		if(!selection_valid)
-		{
-			delete m_selected_item;
-			m_selected_item = NULL;
-			m_selected_amount = 0;
-			m_selected_dragging = false;
-		}
-	}
 
 	// If craftresult is nonempty and nothing else is selected, select it now.
 	if(!m_selected_item)
@@ -1017,12 +986,43 @@ void GUIFormSpecMenu::updateSelectedItem()
 	// If craftresult is selected, keep the whole stack selected
 	if(m_selected_item && m_selected_item->listname == "craftresult")
 	{
-		Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
-		assert(inv);
-		InventoryList *list = inv->getList(m_selected_item->listname);
-		assert(list);
-		m_selected_amount = list->getItem(m_selected_item->i).count;
+		m_selected_amount = verifySelectedItem().count;
+	}
+}
+
+ItemStack GUIFormSpecMenu::verifySelectedItem()
+{
+	// If the selected stack has become empty for some reason, deselect it.
+	// If the selected stack has become inaccessible, deselect it.
+	// If the selected stack has become smaller, adjust m_selected_amount.
+	// Return the selected stack.
+
+	if(m_selected_item)
+	{
+		if(m_selected_item->isValid())
+		{
+			Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
+			if(inv)
+			{
+				InventoryList *list = inv->getList(m_selected_item->listname);
+				if(list && (u32) m_selected_item->i < list->getSize())
+				{
+					ItemStack stack = list->getItem(m_selected_item->i);
+					if(m_selected_amount > stack.count)
+						m_selected_amount = stack.count;
+					if(!stack.empty())
+						return stack;
+				}
+			}
+		}
+
+		// selection was not valid
+		delete m_selected_item;
+		m_selected_item = NULL;
+		m_selected_amount = 0;
+		m_selected_dragging = false;
 	}
+	return ItemStack();
 }
 
 void GUIFormSpecMenu::acceptInput()
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 17b202b18..ae985adde 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -186,6 +186,7 @@ class GUIFormSpecMenu : public GUIModalMenu
 	void drawSelectedItem();
 	void drawMenu();
 	void updateSelectedItem();
+	ItemStack verifySelectedItem();
 
 	void acceptInput();
 	bool OnEvent(const SEvent& event);
-- 
GitLab